diff --git a/Makefile b/Makefile index c4961a4..a600284 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,11 @@ config.mk: | config.default.mk boot.bin: boot.elf objcopy -O binary --only-section=.text boot.elf $@ -boot.elf: lboot.o fernlader.ld - $(LD) $(LDFLAGS) -o $@ lboot.o +boot.elf: lboot.o loader.o fernlader.ld + $(LD) $(LDFLAGS) -o $@ lboot.o loader.o -.S.o: +lboot.o: lboot.S $(CC) $(CFLAGS) -c -o $@ $(@:.o=.S) + +loader.o: loader.c + $(CC) $(CFLAGS) -m64 -Os -c -o $@ $(@:.o=.c) diff --git a/fernlader.ld b/fernlader.ld index 989ace6..17c6f00 100644 --- a/fernlader.ld +++ b/fernlader.ld @@ -1,6 +1,7 @@ SECTIONS { - . = 0x7C00; - .text : { - *(*) + .text 0x7C00: { + lboot.o(.text*, .data*) + loader.o(.text*, .data*, .bss*) } + memmap = ALIGN(8); } diff --git a/lboot.S b/lboot.S index 650a3be..8897e10 100644 --- a/lboot.S +++ b/lboot.S @@ -255,9 +255,15 @@ long: or $0x80000001, %eax mov %eax, %cr0 - lgdt gdt64_ptr + // Linearize stack address + mov %ss, %eax + shl $4, %eax + add %eax, %esp + mov %esp, %ebp - ret + // Load long mode GDT, switch to 64-bit CS + lgdt gdt64_ptr + ljmp $0x8, $trampo64 // hang: sleep indefinitely hang: hlt @@ -303,7 +309,7 @@ gdt64: // entry 0: null descriptor .word 0 .word 0 .byte 0 - .byte 0x90 + .byte 0x92 .byte 0x00 .byte 0 .set gdt64_size, .-gdt64 @@ -328,7 +334,17 @@ pd_ptr: .long 0 pdp_ptr: .long 0 pml4_ptr: .long 0 - // Memory map area + // Points to the end of the memory map memmap_end: .word 0 - .align 8 -memmap: // begins at end of binary + + .code64 + // trampo64: Trampoline function to load long-mode segments + // before entering the loader. +trampo64: + mov $0x10, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov %eax, %ss // FIXME why does this crash? + jmp loader_main diff --git a/loader.c b/loader.c new file mode 100644 index 0000000..3c8b049 --- /dev/null +++ b/loader.c @@ -0,0 +1,5 @@ +void +loader_main(void) +{ + for (;;) {} +}