.org 0x7c00 .code16 .section boot.stage0, "aw" .globl _stage0 _stage0: # :When we enter this procedure, we are # in 16-bit real mode. Our CPU essentially # thinks it is a 8086 and we have to work our # way through enabling Long Mode, from which # we will jump to the Hare code # :Clear segment registers # this is important if memory accesses are done later before proper segmentation # as these registers can have arbitrary values xchg %bx, %bx xor %ax, %ax mov %ax, %ds mov %ax, %es mov %ax, %ss mov %ax, %fs mov %ax, %gs xchg %bx, %bx sidt bios_idtr mov $stack_top, %sp # :Initialize the drive # handling routines call drive_init # :Enable the A20 line call a20_enable_bios call a20_check cmp $1, %ax je a20_ok call a20_enable_kb call a20_check cmp $1, %ax je a20_ok call a20_enable_fast_gate call a20_check cmp $1, %ax je a20_ok a20_fail: # :We can't do anything, hang # XXX error message? hlt a20_ok: # :Now that the drive is initialized and A20 set up, we shall load # the rest :) load_stage1: # :Start to read at the second sector mov entry1_begin, %edi # :Place the result just after us mov $boot_stage1_start, %esi load_stage1_loop: # :When stage1 has finished loaded, finish looping cmp $boot_end, %esi jge load_stage1_loop_end call drive_read_lba inc %di add $0x200, %esi jmp load_stage1_loop load_stage1_loop_end: # :We will need the last sector for later, for when # we want to load the stage3 # :XXX can probably work this out reliably by division mov %di, previous_sector # :Jump to the newly loaded code jmp _stage1_real .include "rt/+x86_64/stage0_drive.S" .include "rt/+x86_64/stage0_a20.S" previous_sector: .short 0 bios_idtr: .quad 0 .org 446 entry1: .byte 0x80 .byte 0x0 .byte 0x0 .byte 0x0 .byte 0x0 # type .byte 0x0 # last .byte 0x0 .byte 0x0 entry1_begin: .int 0x0 .int 512 .org 510 .word 0xaa55 .include "rt/+x86_64/stage1.S"