During linking it gets converted to a good old flat binary. This was done so
that the ELF loading code can be written in C, which will save me plenty of
headaches later.
Also, since with ELF that's possible, stack space for stage3 is now reserved and
set up in a similar (same) fashion to the kernel.
default: mbr vbr-fat32 stage3/LOADER.BIN
default: mbr vbr-fat32 stage3/LOADER.BIN
+LD=i686-elf-gcc
+LDFLAGS=-T stage3/stage3.ld -nostdlib
+
+STAGE3_OBJ=stage3/loader.o
+
mbr: mbr.s
$(AS) $(ASFLAGS) -w-zeroing -o $@ $<
vbr-fat32: vbr-fat32.s fat32/*.s
$(AS) $(ASFLAGS) -o $@ $<
mbr: mbr.s
$(AS) $(ASFLAGS) -w-zeroing -o $@ $<
vbr-fat32: vbr-fat32.s fat32/*.s
$(AS) $(ASFLAGS) -o $@ $<
-stage3/LOADER.BIN: stage3/loader.s stage3/*.s
- $(AS) $(ASFLAGS) -DGIT_REVISION=\"$(GIT_REV)\" -o $@ $<
+stage3/LOADER.BIN: $(STAGE3_OBJ)
+ $(LD) $(LDFLAGS) -o $@ $<
+
+stage3/loader.o: stage3/loader.s stage3/*.s
+ $(AS) $(ASFLAGS) -f elf -g dwarf2 -DGIT_REVISION=\"$(GIT_REV)\" -o $@ $<
- -rm mbr vbr-fat32 stage3/LOADER.BIN disk.img
+ -rm mbr vbr-fat32 stage3/LOADER.BIN $(STAGE3_OBJ) disk.img
+bits 16
+section .text
+
%macro in_wait 0
push ax
%%loop:
%macro in_wait 0
push ax
%%loop:
; Code for getting the BIOS E820 memory map
bits 16
; Code for getting the BIOS E820 memory map
bits 16
; Return: ECX - number of entries, DI - pointer to map
get_e820_map:
; Return: ECX - number of entries, DI - pointer to map
get_e820_map:
no_e820: db "BIOS does not support E820, cannot proceed!", 0xd, 0xa, 0
e820_unexpected: db "Unexpected value in EAX after getting map entry: expected SMAP, got ", 0
no_e820: db "BIOS does not support E820, cannot proceed!", 0xd, 0xa, 0
e820_unexpected: db "Unexpected value in EAX after getting map entry: expected SMAP, got ", 0
; Initial GDT for kernel, which wants a flat code and data descriptor
; Initial GDT for kernel, which wants a flat code and data descriptor
gdt:
dw .end-.start-1
dd .start
gdt:
dw .end-.start-1
dd .start
%include "../fat32/fat32-structs.s"
%macro print 1
%include "../fat32/fat32-structs.s"
%macro print 1
+extern __STACK_BOTTOM__
+
+global _start
+ mov sp, __STACK_BOTTOM__
mov [BOOT_DRIVE], dl
call enable_unreal
print begin
mov [BOOT_DRIVE], dl
call enable_unreal
print begin
%include "unreal.s"
%include "a20.s"
%include "../fat32/fat32.s"
%include "unreal.s"
%include "a20.s"
%include "../fat32/fat32.s"
%include "print.s"
%include "e820.s"
%include "print.s"
%include "e820.s"
+section .text
+in_protected:
mov ax, 0x10
mov ds, ax
mov es, ax
mov ax, 0x10
mov ds, ax
mov es, ax
+%include "paging.s"
+
+section .rodata
+
kernel_name: db "KERNEL BIN"
begin: db "Nameless Bootloader revision ", GIT_REVISION, 0xd, 0xa, 0
a20_enabled: db "A20 has been enabled", 0xd, 0xa, "Searching for kernel...", 0xd, 0xa, 0
kernel_name: db "KERNEL BIN"
begin: db "Nameless Bootloader revision ", GIT_REVISION, 0xd, 0xa, 0
a20_enabled: db "A20 has been enabled", 0xd, 0xa, "Searching for kernel...", 0xd, 0xa, 0
space: db " ", 0
hex_delm: db "0x", 0
newline: db 0xd, 0xa, 0
space: db " ", 0
hex_delm: db "0x", 0
newline: db 0xd, 0xa, 0
+bits 16
+section .text
+
print_str:
push ax
push bx
print_str:
push ax
push bx
--- /dev/null
+ENTRY(_start)
+OUTPUT_FORMAT(binary)
+
+SECTIONS {
+ . = 0x1800;
+ .text : {
+ stage3/loader.o(.text)
+ *(.text)
+ }
+ .rodata : { *(.rodata) }
+ .data : { *(.data) }
+ .bss : {
+ *(.bss)
+ . += 1K;
+ PROVIDE(__STACK_BOTTOM__ = .);
+ }
+}
; Routine for enabling unreal mode, which allows using 32-bit offsets in real mode
; Routine for enabling unreal mode, which allows using 32-bit offsets in real mode
+bits 16
+section .text
+
enable_unreal:
cli
push eax
enable_unreal:
cli
push eax
; GDT with 1 flat data segment descriptor
gdt_info:
dw gdt_end-gdt_start-1
; GDT with 1 flat data segment descriptor
gdt_info:
dw gdt_end-gdt_start-1