pull/6/head
Carlos Fenollosa 10 years ago
parent 9a8a1f6c76
commit d5d1a88cae

@ -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

@ -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** **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 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. 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 Strategy
-------- --------

@ -0,0 +1 @@
../../08-32bit-print/32bit-print.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

Binary file not shown.

@ -0,0 +1 @@
../../07-bootsector-disk/boot_sect_disk.asm

@ -0,0 +1 @@
../../09-32bit-gdt/32bit-gdt.asm

@ -0,0 +1 @@
../../13-kernel-barebones/kernel_entry.asm

Binary file not shown.

@ -0,0 +1 @@
../../10-32bit-enter/32bit-switch.asm

Binary file not shown.

Binary file not shown.

@ -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';
}

Binary file not shown.
Loading…
Cancel
Save