mirror of
https://github.com/cfenollosa/os-tutorial.git
synced 2024-10-27 20:34:19 +00:00
lesson 14
This commit is contained in:
parent
9a8a1f6c76
commit
d5d1a88cae
43
14-checkpoint/Makefile
Normal file
43
14-checkpoint/Makefile
Normal file
@ -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
|
||||||
--------
|
--------
|
||||||
|
1
14-checkpoint/boot/32bit_print.asm
Symbolic link
1
14-checkpoint/boot/32bit_print.asm
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../08-32bit-print/32bit-print.asm
|
51
14-checkpoint/boot/bootsect.asm
Normal file
51
14-checkpoint/boot/bootsect.asm
Normal file
@ -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
|
BIN
14-checkpoint/boot/bootsect.bin
Normal file
BIN
14-checkpoint/boot/bootsect.bin
Normal file
Binary file not shown.
1
14-checkpoint/boot/disk.asm
Symbolic link
1
14-checkpoint/boot/disk.asm
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../07-bootsector-disk/boot_sect_disk.asm
|
1
14-checkpoint/boot/gdt.asm
Symbolic link
1
14-checkpoint/boot/gdt.asm
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../09-32bit-gdt/32bit-gdt.asm
|
1
14-checkpoint/boot/kernel_entry.asm
Symbolic link
1
14-checkpoint/boot/kernel_entry.asm
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../13-kernel-barebones/kernel_entry.asm
|
BIN
14-checkpoint/boot/kernel_entry.o
Normal file
BIN
14-checkpoint/boot/kernel_entry.o
Normal file
Binary file not shown.
1
14-checkpoint/boot/switch_pm.asm
Symbolic link
1
14-checkpoint/boot/switch_pm.asm
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../10-32bit-enter/32bit-switch.asm
|
BIN
14-checkpoint/kernel.elf
Executable file
BIN
14-checkpoint/kernel.elf
Executable file
Binary file not shown.
BIN
14-checkpoint/kernel.sym
Executable file
BIN
14-checkpoint/kernel.sym
Executable file
Binary file not shown.
8
14-checkpoint/kernel/kernel.c
Normal file
8
14-checkpoint/kernel/kernel.c
Normal file
@ -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';
|
||||||
|
}
|
BIN
14-checkpoint/kernel/kernel.o
Normal file
BIN
14-checkpoint/kernel/kernel.o
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user