diff options
Diffstat (limited to 'boot2/stage2.asm')
| -rw-r--r-- | boot2/stage2.asm | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/boot2/stage2.asm b/boot2/stage2.asm new file mode 100644 index 0000000..0a3ee87 --- /dev/null +++ b/boot2/stage2.asm @@ -0,0 +1,247 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; 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 |
