;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; FoolOS Boot Loader ; ; Copyright 2014 M.Idziorek ; ; we have just been loaded by the BIOS and are in 16-bits real mode! ; ; THIS IS THE CENTRAL FILE OF THE BOOTLOADER, ; ; after we are through, ; the following work has been accomplished (chronologically): ; ; * BOOT_DRIVE is set ; ; * 50 sectors of our kernel are loaded at KERNEL_OFFSET from floppy ; ; * memoru map is available at MEMMAP_OFFSET ; (look at MEMMEP_SIZE_OFFSET for number of entries) ; ; * the vesa mode specified by VESA_MODE_SELECT is set up ; (at VESA_MODES, and VESA_MODE_INFO additional info structs are available) ; ; * 32-bit protected mode was set up. ; ; * A20 gate is open ; ; * PICs are configured ; ; * we are inside the C kernel! ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;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 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 ;we want 16-bit instructions, before we switch to 32-bit protected mode. [bits 16] jmp boot_16 ;start boot process ;SOME Global Data, mainly strings BOOT_DRIVE: db 0xff STR_VERSION: db "v0.2~",0 VESA_CHECK: db "vesa check.",0 ;lets put our temporary GDT (Global Descriptor Table) here %include "boot/GDT.asm" ;include 16-bit real mode routines (print_string, disk_load) %include "boot/disk_load_16.asm" %include "boot/print_string_16.asm" ;include our routines for switching to 32-bit protected mode %include "boot/pm.asm" ;pic mapping %include "boot/pic.asm" ;get memory map %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 (50 sectors starting at sector 2) mov bx,KERNEL_OFFSET mov dh, 50 ;50 sectors! mov dl, [BOOT_DRIVE] call disk_load ;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 ;VESA: also setup vesa stuff before entering 32 bit protected mode ;VESA: get all available vesa modes! mov ax,0 ; set target address in es:di (0:offset) mov es,ax mov di,VESA_MODES mov ax,0x4f00 ;vesa function: Get Controller Info int 0x10 ; call the interrupt to get the data from the bios! vesa_err: mov bx, VESA_CHECK call print_string cmp ax,0x004f je vesa_ok jmp vesa_err vesa_ok: ; ;VESA: get vesa info on mode of interest mov ax,0 ; set target address in es:di (0:offset) mov es,ax mov di,VESA_MODE_INFO mov ax,0x4f01 ;vesa function: Get Mode Info mov cx,VESA_MODE_SELECT int 0x10 ; call the interrupt to get the data from the bios! vesa_err2: mov bx, VESA_CHECK call print_string cmp ax,0x004f je vesa_ok2 jmp vesa_err2 vesa_ok2: ;VESA: finally switch to the mode of choice! mov ax,0x4f02 ;vesa function: Set Mode mov bx,VESA_MODE_SELECT int 0x10 ;finally lets enter Protected mode!!! call switch_to_pm ;;;;;;;; BOOT 32-bit protected mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [bits 32] boot_32_pm: ; we could do ALL This inside the kernel!!!!!! TODO ;enable A20 ;http://www.brokenthorn.com/Resources/OSDev9.html ;Method 3.1: Enables A20 through keyboard controller mov al, 0xdd ; command 0xdd: enable a20 out 0x64, al ; send command to controller ;pic setup call pic_setup call KERNEL_OFFSET ;jump into our Kernel! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;so we get identified as MBR times 510-($-$$) db 0 dw 0xaa55