From d5d1a88caecc2bf3b8944e5d4874d33d0f33ea49 Mon Sep 17 00:00:00 2001 From: Carlos Fenollosa Date: Mon, 20 Oct 2014 23:13:57 +0200 Subject: [PATCH] lesson 14 --- 14-checkpoint/Makefile | 43 +++++++++++++++++++++++ 14-checkpoint/README.md | 35 ++++++++++++++++++- 14-checkpoint/boot/32bit_print.asm | 1 + 14-checkpoint/boot/bootsect.asm | 51 ++++++++++++++++++++++++++++ 14-checkpoint/boot/bootsect.bin | Bin 0 -> 512 bytes 14-checkpoint/boot/disk.asm | 1 + 14-checkpoint/boot/gdt.asm | 1 + 14-checkpoint/boot/kernel_entry.asm | 1 + 14-checkpoint/boot/kernel_entry.o | Bin 0 -> 480 bytes 14-checkpoint/boot/switch_pm.asm | 1 + 14-checkpoint/kernel.elf | Bin 0 -> 5698 bytes 14-checkpoint/kernel.sym | Bin 0 -> 1562 bytes 14-checkpoint/kernel/kernel.c | 8 +++++ 14-checkpoint/kernel/kernel.o | Bin 0 -> 1936 bytes 14 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 14-checkpoint/Makefile create mode 120000 14-checkpoint/boot/32bit_print.asm create mode 100644 14-checkpoint/boot/bootsect.asm create mode 100644 14-checkpoint/boot/bootsect.bin create mode 120000 14-checkpoint/boot/disk.asm create mode 120000 14-checkpoint/boot/gdt.asm create mode 120000 14-checkpoint/boot/kernel_entry.asm create mode 100644 14-checkpoint/boot/kernel_entry.o create mode 120000 14-checkpoint/boot/switch_pm.asm create mode 100755 14-checkpoint/kernel.elf create mode 100755 14-checkpoint/kernel.sym create mode 100644 14-checkpoint/kernel/kernel.c create mode 100644 14-checkpoint/kernel/kernel.o diff --git a/14-checkpoint/Makefile b/14-checkpoint/Makefile new file mode 100644 index 0000000..61497ea --- /dev/null +++ b/14-checkpoint/Makefile @@ -0,0 +1,43 @@ +C_SOURCES = $(wildcard kernel/*.c drivers/*.c) +HEADERS = $(wildcard kernel/*.h drivers/*.h) +OBJ = ${C_SOURCES:.c=.o} + +# Change this if your cross-compiler is somewhere else +CC = /usr/local/i386elfgcc/bin/i386-elf-gcc +GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb +# -g: Use debugging symbols +CFLAGS = -g + +# First rule is run by default +os-image.bin: boot/bootsect.bin kernel.bin + cat $^ > os-image.bin + +kernel.bin: kernel.elf + i386-elf-ld -o $@ -Ttext 0x1000 $^ --oformat binary + +run: os-image.bin + qemu-system-i386 -fda os-image.bin + +debug: os-image.bin kernel.elf + qemu-system-i386 -s -fda os-image.bin & + ${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf" + +# To build the kernel: make all objects first +kernel.elf: boot/kernel_entry.o ${OBJ} + i386-elf-ld -o $@ -Ttext 0x1000 $^ + +# To make an object, always compile from its .c +%.o: %.c ${HEADERS} + ${CC} ${CFLAGS} -ffreestanding -c $< -o $@ + +# Object files from asm files +%.o: %.asm + nasm $< -f elf -o $@ + +%.bin: %.asm + nasm $< -f bin -o $@ + + +clean: + rm -rf *.bin *.dis *.o os-image.bin *.elf + rm -rf kernel/*.o boot/*.bin drivers/*.o diff --git a/14-checkpoint/README.md b/14-checkpoint/README.md index 16f415b..cf31211 100644 --- a/14-checkpoint/README.md +++ b/14-checkpoint/README.md @@ -1,4 +1,4 @@ -*Concepts you may want to Google beforehand: monolithic kernel, microkernel* +*Concepts you may want to Google beforehand: monolithic kernel, microkernel, debugger, gdb* **Goal: Pause and organize our code a little bit** @@ -13,6 +13,39 @@ Take a look at the new folder structure. Most of the files have been symlinked from previous lessons, so if we have to change them at some point, it will be a better idea to remove the symlink and create a new file. +Furthermore, since from now on we will use mostly C to code, we'll take advantage of qemu's +ability to open a connection to gdb. First, let's install a cross-compiled `gdb` since +OSX uses `lldb` which is not compatible with the ELF file format (neither is the `gdb` available +on Homebrew's repos) + +```sh +cd /tmp/src +curl -O http://ftp.rediris.es/mirror/GNU/gnu/gdb/gdb-7.8.tar.gz +tar xf gdb-7.8.tar.gz +mkdir gdb-build +cd gdb-build +export PREFIX="/usr/local/i386elfgcc" +export TARGET=i386-elf +../gdb-7.8/configure --target="$TARGET" --prefix="$PREFIX" --program-prefix=i386-elf- +make +make install +``` + +Check out the Makefile target `make debug`. We can take +advantage of this cool qemu feature. Type `make debug` and, on the gdb shell: + +- Set up a breakpoint in `kernel.c:main()`: `b main` +- Run the OS: `continue` +- Run two steps into the code: `next` then `next`. You will see that we are just about to set + the 'X' on the screen, but it isn't there yet (chech out the qemu screen) +- Let's see what's in the video memory: `print *video_memory`. There is the 'L' from "Landed in + 32-bit Protected Mode" +- Hmmm, let's make sure that `video_memory` points to the correct address: `print video_memory` +- `next` to put there our 'X' +- Let's make sure: `print *video_memory` and look at the qemu screen. It's definitely there. + +Now is a good time to read some tutorial on `gdb`! + Strategy -------- diff --git a/14-checkpoint/boot/32bit_print.asm b/14-checkpoint/boot/32bit_print.asm new file mode 120000 index 0000000..b249c3a --- /dev/null +++ b/14-checkpoint/boot/32bit_print.asm @@ -0,0 +1 @@ +../../08-32bit-print/32bit-print.asm \ No newline at end of file diff --git a/14-checkpoint/boot/bootsect.asm b/14-checkpoint/boot/bootsect.asm new file mode 100644 index 0000000..361d7ef --- /dev/null +++ b/14-checkpoint/boot/bootsect.asm @@ -0,0 +1,51 @@ +; Identical to lesson 13's boot sector, but the %included files have new paths +[org 0x7c00] +KERNEL_OFFSET equ 0x1000 ; The same one we used when linking the kernel + + mov [BOOT_DRIVE], dl ; Remember that the BIOS sets us the boot drive in 'dl' on boot + mov bp, 0x9000 + mov sp, bp + + mov bx, MSG_REAL_MODE + call print + call print_nl + + call load_kernel ; read the kernel from disk + call switch_to_pm ; disable interrupts, load GDT, etc. Finally jumps to 'BEGIN_PM' + jmp $ ; Never executed + +%include "boot/print.asm" +%include "boot/print_hex.asm" +%include "boot/disk.asm" +%include "boot/gdt.asm" +%include "boot/32bit_print.asm" +%include "boot/switch_pm.asm" + +[bits 16] +load_kernel: + mov bx, MSG_LOAD_KERNEL + call print + call print_nl + + mov bx, KERNEL_OFFSET ; Read from disk and store in 0x1000 + mov dh, 2 + mov dl, [BOOT_DRIVE] + call disk_load + ret + +[bits 32] +BEGIN_PM: + mov ebx, MSG_PROT_MODE + call print_string_pm + call KERNEL_OFFSET ; Give control to the kernel + jmp $ ; Stay here when the kernel returns control to us (if ever) + + +BOOT_DRIVE db 0 ; It is a good idea to store it in memory because 'dl' may get overwritten +MSG_REAL_MODE db "Started in 16-bit Real Mode", 0 +MSG_PROT_MODE db "Landed in 32-bit Protected Mode", 0 +MSG_LOAD_KERNEL db "Loading kernel into memory", 0 + +; padding +times 510 - ($-$$) db 0 +dw 0xaa55 diff --git a/14-checkpoint/boot/bootsect.bin b/14-checkpoint/boot/bootsect.bin new file mode 100644 index 0000000000000000000000000000000000000000..e8d27fbfebf937aaa6263436ba130a44bd615eda GIT binary patch literal 512 zcmb_YK}#D!6n?u6rW$mY3Mo_%Lp^yYL<^;Y$6g986r~qY$mq^Wh}nV33JSYL*h`Yb zA|47Y1#cFl2Zb2aC6Kt6(z58$TXL}su8JP@km(TdANXC~``-8Xc;73fXWcrimoI`j zm#2Wg0FD%X1#u@^Nlt>@TOEjWFI3_i9A>KnJAIM9(;w-Q8~}K?346GF;8vJMVJEJYobJh%iPOytfu8V`RZb)^cHxg_v#iQk-jNz#;_yyW(r1o_8m9MK(Ox#rhuo)N?(5*6 z`X_$FZ~MFs&+!DiiBVgIk+XZ9Vk2iQqC8<1S&|kuMFmozZ1o}K JBh=5^{{et8xw-%V literal 0 HcmV?d00001 diff --git a/14-checkpoint/boot/disk.asm b/14-checkpoint/boot/disk.asm new file mode 120000 index 0000000..b01433e --- /dev/null +++ b/14-checkpoint/boot/disk.asm @@ -0,0 +1 @@ +../../07-bootsector-disk/boot_sect_disk.asm \ No newline at end of file diff --git a/14-checkpoint/boot/gdt.asm b/14-checkpoint/boot/gdt.asm new file mode 120000 index 0000000..3ebae1a --- /dev/null +++ b/14-checkpoint/boot/gdt.asm @@ -0,0 +1 @@ +../../09-32bit-gdt/32bit-gdt.asm \ No newline at end of file diff --git a/14-checkpoint/boot/kernel_entry.asm b/14-checkpoint/boot/kernel_entry.asm new file mode 120000 index 0000000..387cb0d --- /dev/null +++ b/14-checkpoint/boot/kernel_entry.asm @@ -0,0 +1 @@ +../../13-kernel-barebones/kernel_entry.asm \ No newline at end of file diff --git a/14-checkpoint/boot/kernel_entry.o b/14-checkpoint/boot/kernel_entry.o new file mode 100644 index 0000000000000000000000000000000000000000..d421a6a9162892b3ed0ed888a7299ae04e555dd0 GIT binary patch literal 480 zcmb<-^>JflWMqH=Mh0dE1doBi0V-hvrZpJY7?@y6Nuoh!f-oCYmjRH&j%0!WlnoMN zMiO@bs?$c|gUkQ{K_EtUNdZv80Vu`-#32138f2ywqLRcUAgeMLLPPmQsW}ie zFdZl~%zls{3&Y3%$daI#5JwUKhfz{~eu;i|YEfQlPJC)!Nl~RX6-#H<8FQ3wP<+Mb!3na1hv&|M=& z0xpQ4h=)DxMZ9?N;>n8#Z^8ZeLxg}{_Pk>Jy{@it{5W{@&=0EL$M09KtKM`K%)7mK z{x=~68L_B9sW(nkM{sjeBXzP7KR~0jeSi}VKaoqor%z`x#nhsys5~MUAG;3fh4CH1-uG!TC&maxL)jq9hn%{58IKky+$LJH;mWwL(JBb zkQ-J0Hkk&E`(I_Ib1w_yC$=-;5DUkc$Divy1bM8$HljaMqC*HU?{EgJgEwJF8OAvG z+E^QT2%c>mXoKr;h5n%$@=ZS0`lxI0A6zmvf)%)<7+gPW4c*31^KIe?^Px3j@)`dV z%?Th`M>GA6v_Jf2#)ntTzWMdi>G0FrO*?76^y?V%`4aso1sWODm!n1cZwpt*K-eER zFxa=D&6PEY*++*6yp1`Gbz29=QMo0U=0;=wh0pNi&wOe`k;=}YKBbPA1Rrmhub*KT Y7e%bdbsI^N+35*(Wy@0@AyJDy082RGqW}N^ literal 0 HcmV?d00001 diff --git a/14-checkpoint/kernel.sym b/14-checkpoint/kernel.sym new file mode 100755 index 0000000000000000000000000000000000000000..c165349f324a5082f08746a9aec9b629e6e80c9c GIT binary patch literal 1562 zcma)6L2DC16n?v#q?WX?Z4g`QVTCFc$)?3nw9+a~wG>JPu^@u1n`DwK&F+@nNokj; zGgYKPHuzk8KcC|d@HF~cnMT8N*`g!m^H3f zs%5LPSeZ5EN;8*{+x;R(ivpX(IpF?}*3^L=eRz zLL2R->Z4r?q>+s&J9KVMK$(*m(VymvY3VuSvY>;KRQ&8?7w{;SluXlz! z&6ie-uBZJ!EEj-eFO~XFsh?k&M==)DR zA!A{G>;SND!|Eq%4zt&C3A~LB=&7y98FX$JP`_xLzke=%aL%Vz6v^x!s$1%KN$~rH c`S%@m@leE)T(^}Z8BTAoD>|O^2!%TI3ms3v1ONa4 literal 0 HcmV?d00001 diff --git a/14-checkpoint/kernel/kernel.c b/14-checkpoint/kernel/kernel.c new file mode 100644 index 0000000..ea8fd38 --- /dev/null +++ b/14-checkpoint/kernel/kernel.c @@ -0,0 +1,8 @@ +/* This will force us to create a kernel entry function instead of jumping to kernel.c:0x00 */ +void dummy_test_entrypoint() { +} + +void main() { + char* video_memory = (char*) 0xb8000; + *video_memory = 'X'; +} diff --git a/14-checkpoint/kernel/kernel.o b/14-checkpoint/kernel/kernel.o new file mode 100644 index 0000000000000000000000000000000000000000..c7cfa2e54c46d6deae1031809589bb0c71a2cbf0 GIT binary patch literal 1936 zcma)7OKTKC5U$?YU88H(JQSnxu!8XcW;T-eHa-&L3lS6oBFH*B+q*ktXGUgbLn4Zb z2#N>sFK+37taVG$dDk5dK%G$ zr94xq*iA#Uf#x57z5X75lW+2RkY7)JIfQnBZUb0b*C1}c@#!(QA0a2$zIWE(hLrQQ-3 zHhW-v9Gs(_7=`#z?#Gz+5#19DG74meNJ-mOEiI(khNmZ5-BvD#_(iWF!NaH%b~<6~ zR8L3Y&3d?0JsrATUj|8BZFxz%Td#)kc+yS6$a6Z?eN*FZTe=H3LoZ0E(e?f1T7s-K zOo*11)onYG-a&O`BfjGWL}zDbk5qPJ#e39(i8gXaK;qUF61V%r==yyA5n91bWM<+6 zrc>pTuR7pIEh1cJ&wtaWXEpE zdbd^cf@TO;ik*5rl8afd6FEUkuA0#C0%;~7KiO{RbNAFV*{(Gs$Ctdo|D#ca@jWW) zaK1m;kH_4x?K)0hGrFYXjWBV$VCVz?D{cZYW)A1zd~F7rjBhXWwZ;h9w}$8jgeE3)5oL1nR4ZiCVJ#Cv3|>J-l}^_)N!amRXOVaMyV zT7VovcPfyK`Cr0%?-%^{pPc%ise3BWBkrNVfpI@srVkP%-jejq+RhRm*iP-|d&F