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
|
@ -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…
Reference in new issue