;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; THE FOOL-BOOT-LOADER ; ; * X 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 under MBR ; ; * 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 was bootloader0 ;this is where the BIOS per definition will put the first ;512 bytes of data from the boot device ;wer are one sector after that. [org 0x7e00] ;;define some constants ;;where we will load our kernel into memory and some ;;other memory locations ; MEMMAP_SIZE_OFFSET equ 0x7c00 MEMMAP_OFFSET equ 0x7c01 VESA_MODES equ 0x9300 ; do NOT overwrite yourself! be careful! VESA_MODE_INFO equ 0x9400 VESA_MODE_SELECT equ 0x4114 ; jmp boot_16 ;start boot process ;;SOME Global Data, mainly info/error strings FILL: times 32 db 0x66 BOOT_DRIVE: db 0xff LOADER_TARGET: dd 0x100000 ;here we will put our image KERNEL_CHUNK: dw 0x1 STR_VERSION: db "Fool Loader Stage 2 v0.5",0 STR_LOAD: db "Loading Kernel...",0 STR_BOOT: db "Boot Drive: ",0 MEMMAP_INFO: db "Getting Memory Map from BIOS.",0 STR_PM: db "PROTECTED MODE",0 ; ;;lets put our temporary GDT (Global Descriptor Table) here ;;kernel should move this away %include "GDT.asm" ; ;;include 16-bit real mode routines (print_string, disk_load, vesa_setup,check_a20) %include "disk_load_16.asm" ;%include "boot/check_a20_16.asm" %include "print_string_16.asm" %include "vesa_setup_16.asm" ; ;;include our routines for switching to 32-bit protected mode %include "pm.asm" ;include some pm mode helpers %include "common_pm.asm" ; ; ; ;;get memory map routine %include "memmap.asm" ; ;;;;;;;;; BOOT 16-bit real ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;;lets start [bits 16] idt_real: dw 0x3ff ; 256 entries, 4b each = 1K dd 0 ; Real Mode IVT @ 0x0000 boot_16: mov [BOOT_DRIVE],dl ;pr info mov bx, STR_VERSION call print_string call print_nextline ;show bootdrive mov bx, STR_BOOT call print_string mov al,dl call print_hex_byte call print_nextline ; memmap message mov bx,MEMMAP_INFO call print_string call print_nextline ;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 ; Load the KERNEL Image mov bx, STR_LOAD call print_string call print_nextline kernel_load: call disk_load_16 ; init vesa on last iteration! mov ax,[KERNEL_CHUNK] cmp ax,0x5 jne skip_vesa_init ; call VesaSetup skip_vesa_init: call switch_to_pm ; ;;;;;;;;; BOOT 32-bit protected mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [bits 32] boot_32_pm: ;Fast A20 Gate: ;http://wiki.osdev.org/A20_Line in al, 0x92 or al, 2 out 0x92, al ; tell the world we are protected ;mov ebx,STR_PM ;mov ecx,2*23*80 ;call print_string_pm ;increment chunk number mov ax,[KERNEL_CHUNK] add ax,1 mov [KERNEL_CHUNK],ax ;check if all chunkgs loaded (hardcoded to 0x6 for a start) cmp ax,0x6 je finish_load ; show KERNEL CHUNK value ; push edx ; persist edx for some reason!? ; mov edx,0 ; mov dx,[KERNEL_CHUNK] ; mov ecx,2*24*80 ; call print_hex_pm ; pop edx ; here we actually do copy the chunk into ext mem! mov eax,[LOADER_TARGET] mov ebx,0x18000 copy_next_byte: mov ecx,[ebx] mov [eax],ecx inc eax inc ebx cmp ebx, 0x90000 jne copy_next_byte mov [LOADER_TARGET],eax ;persist next target address ; and now go back to real! (first 16bit protected!) jmp CODE16_SEG:reinit_16 finish_load: ; ; call kernel! mov eax,0 ;tell the kernel ; we are the booting processor jmp 0x100000 ;jump into our Kernel! [bits 16] reinit_16: ;16 bit protected mode mov eax,DATA16_SEG mov ds,eax mov es,eax mov fs,eax mov gs,eax mov ss,eax mov eax,cr0 and eax,!0x1 ; Disable protected mode mov cr0, eax jmp 0:realmode realmode: mov sp,0x07bff mov bp,sp mov ax,0 mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax lidt [idt_real] sti jmp kernel_load