// 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. push $msg_a20 call dbgmsg add $2, %sp inb $0x92, %al or $2, %al outb %al, $0x92 // prot_enter: Set up GDT, switch into 32-bit protected mode. prot_enter: push $msg_prot call dbgmsg add $2, %sp lgdt GDT_PTR PROT PROT32 .code32 jmp main .code16 dbgmsg: push %bp mov %sp, %bp push %ax push %si mov 4(%bp), %si 1: lodsb test %al, %al jz 2f outb %al, $0xE9 jmp 1b 2: pop %si pop %ax pop %bp ret .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 msg_start: .asciz "Netboot via fernlader v2 ...\r\n" msg_a20: .asciz " * Enabling A20 Gate\r\n" msg_prot: .asciz " * Protected Mode\r\n"