summaryrefslogtreecommitdiff
path: root/boot2/stage2.asm
diff options
context:
space:
mode:
Diffstat (limited to 'boot2/stage2.asm')
-rw-r--r--boot2/stage2.asm247
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