;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; THE FOOL-BOOT-LOADER ; ; So we have just been loaded by the BIOS and are in 16-bits real mode! ; Now the following work will bee accomplished (chronologically): ; ; NOTE: this should not exceed 446 bytes ; (otherwise it does not work on my Acer Aspire) ; ; * BOOT_DRIVE set ; ; * 52 sectors of our kernel loaded at KERNEL_OFFSET from floppy ; ; * memory map made available at MEMMAP_OFFSET ; (check at MEMMEP_SIZE_OFFSET for number of entries) ; ; * the VESA mode specified by VESA_MODE_SELECT will be set up ; (check at VESA_MODES, and VESA_MODE_INFO ; for additional information) ; ; * interrupts disabled ; ; * 32-bit protected mode set up. ; ; * esp set to 0x90000 ; ; * A20 gate opened ; ; * and finally we will jump into the C world to kernel_main() ! ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;we want 16-bit instructions, before we switch to 32-bit protected mode. [bits 16] ;define origin of boot record in memory: 0x7c00 ;this is where the BIOS per definition will put the first ;512 bytes of data from the boot device ;The Boot record is identified by the last 2 magic bytes: 0xaa55 (?) [org 0x7c00] ;;define some constants ;;where we will load our kernel into memory and some ;;other memory locations ; KERNEL_OFFSET equ 0x1000 MEMMAP_SIZE_OFFSET equ 0x7c00+0x600 MEMMAP_OFFSET equ 0x7c00+0x400 VESA_MODES equ 0x8300 VESA_MODE_INFO equ 0x8400 VESA_MODE_SELECT equ 0x4114 ; jmp boot_16 ;start boot process db 'X' jmp $ ;entry for other processors ;) db 'X' ; ;;SOME Global Data, mainly info/error strings BOOT_DRIVE: db 0xff STR_VERSION: db "v0.4",0 VESA_CHECK1: db "1",0 VESA_CHECK2: db "2",0 VESA_CHECK3: db "3",0 CHECK_A20: db "A",0 ; ;;lets put our temporary GDT (Global Descriptor Table) here ;;kernel should move this away %include "boot/GDT.asm" ; ;;include 16-bit real mode routines (print_string, disk_load, vesa_setup,check_a20) %include "boot/disk_load_16.asm" ;%include "boot/check_a20_16.asm" %include "boot/print_string_16.asm" %include "boot/vesa_setup_16.asm" ; ;;include our routines for switching to 32-bit protected mode %include "boot/pm.asm" ; ; ;;get memory map routine %include "boot/memmap.asm" ; ;;;;;;;;; BOOT 16-bit real ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;;lets start [bits 16] ; boot_16: ; ; mov bx, STR_VERSION call print_string ; ; ; ;setup the stack mov bp,0x8000 mov sp,bp ; ; ;remember BOOT_DRIVE (as was set by BIOS) mov [BOOT_DRIVE],dl ; ; ;Load the KERNEL (52 sectors starting at sector 2) mov bx,KERNEL_OFFSET mov dh, 52 ; for lba mode this is hardcoded anyway mov dl, [BOOT_DRIVE] call disk_load_16 ; ; ;get memory map from bios before we enter 32 bit protected mode mov ax,0 ; set target address in es:di (0:offset) mov es,ax mov di,MEMMAP_OFFSET call BiosGetMemoryMap ; this will also put the number of entries ; ; of the memory map at MEMMAP_SIZE_OFFSET ;a20check: ; ; mov bx, CHECK_A20 ; call print_string ; ; call check_a20 ; cmp ax,0 ; je a20check ;hang if a20 is disabled! ; ;VESA: also setup vesa stuff before entering 32 bit protected mode call VesaSetup ; ; ;finally lets enter Protected mode!!! call switch_to_pm ; ;;;;;;;;; BOOT 32-bit protected mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [bits 32] boot_32_pm: ; ; ;enable A20 ; ;http://www.brokenthorn.com/Resources/OSDev9.html ; ;Method 3.1: Enables A20 through keyboard controller ; ;Not all keyboard controllers support this ; ;todo: check if this has any effect at all !?!? mov al, 0xdd ; command 0xdd: enable a20 ; ;mov al, 0xdf ; command 0xdf: disable a20 out 0x64, al ; send command to controller ; call KERNEL_OFFSET ;jump into our Kernel! ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;so we get identified as MBR times 510-($-$$) db 0x0 ;dw 0x0 dw 0xaa55