// vim: ft=gas:et:sw=12:ts=12:sts=12 .include "src/mode.S" .global _start .text .code16 // _start: entry point _start: cli cld mov %sp, %bp xor %ax, %ax mov %ax, %ds mov %ax, %es mov %ss, %ax mov %ax, real_ss // initialize our own BSS section mov $_bss_start, %di mov $_bss_end, %cx sub %di, %cx xor %al, %al rep stosb // a20_enable: Allow use of 'high' (>1Mb) memory a20_enable: // Of all the ways to toggle A20, we only try the Fast A20 Gate. // This is known to cause problems on some ancient systems, // but as our bootloader exclusively runs on 64-bit machines, // we should not run into any of those systems. // Modern machines apparently don't even have the A20 line anymore. inb $0x92, %al or $2, %al outb %al, $0x92 // prot_enter: Set up GDT, switch into 32-bit protected mode. prot_enter: lgdt GDT_PTR PROT PROT32 .code32 jmp main .data .global real_ss real_ss: .word 0 .global GDT GDT: // entry 0: null descriptor .space 8, 0 // entry 1: 16-bit code segment .byte 0xFF, 0xFF, 0, 0, 0, 0b10011010, 0x8F, 0 // entry 2: 16-bit data segment .byte 0xFF, 0xFF, 0, 0, 0, 0b10010010, 0x8F, 0 // entry 3: 32-bit code segment .byte 0xFF, 0xFF, 0, 0, 0, 0b10011010, 0xCF, 0 // entry 4: 32-bit data segment .byte 0xFF, 0xFF, 0, 0, 0, 0b10010010, 0xCF, 0 // TODO: 32-bit TSS .set GDT_SIZE, . - GDT GDT_PTR: .word GDT_SIZE - 1 .word GDT .word 0, 0, 0