summaryrefslogtreecommitdiff
path: root/xxx/boot2
diff options
context:
space:
mode:
Diffstat (limited to 'xxx/boot2')
-rw-r--r--xxx/boot2/GDT.asm77
-rw-r--r--xxx/boot2/Makefile28
-rw-r--r--xxx/boot2/check_a20_16.asm61
-rw-r--r--xxx/boot2/common_pm.asm86
-rw-r--r--xxx/boot2/disk_load_16.asm281
-rw-r--r--xxx/boot2/memmap.asm57
-rw-r--r--xxx/boot2/mp.asm37
-rw-r--r--xxx/boot2/pm.asm36
-rw-r--r--xxx/boot2/print_string_16.asm115
-rw-r--r--xxx/boot2/stage2.asm267
-rw-r--r--xxx/boot2/vesa_setup_16.asm93
11 files changed, 1138 insertions, 0 deletions
diff --git a/xxx/boot2/GDT.asm b/xxx/boot2/GDT.asm
new file mode 100644
index 0000000..4c14b46
--- /dev/null
+++ b/xxx/boot2/GDT.asm
@@ -0,0 +1,77 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Global Descriptor Table
+; we have the null descriptor and a code and data block for a start
+;
+; 0x80 code segment
+; 0x10 data segment
+;
+; this file contains pure data
+;
+;
+;
+;
+global gdt_descriptor
+
+gdt_start:
+
+gdt_null: ;null descriptor (2 x 4 bytes)
+ dd 0x0
+ dd 0x0
+
+gdt_code:
+ ; flags:
+ ; present: 1 / privilege: 00 / type: 1
+ ; code: 1 / conforming: 0 / readable: 1 / accessed: 0
+ ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0
+ dw 0xffff ;limit
+ dw 0x0 ;base
+ db 0x0 ;base
+ db 10011010b ;flags
+ db 11001111b ;flags & seg.limit
+ db 0x0 ;base
+
+gdt_data:
+ ; flags:
+ ; code: 0 / expand down: 0 / writable: 1 / accessed: 0
+ dw 0xffff
+ dw 0x0
+ db 0x0
+ db 10010010b
+ db 11001111b
+ db 0x0
+
+gdt16_code:
+ ; flags:
+ ; present: 1 / privilege: 00 / type: 1
+ ; code: 1 / conforming: 0 / readable: 1 / accessed: 0
+ ; granularity: 1 / 16-bit default: 1 / 64-bit seg: 0 / AVL: 0
+ dw 0xffff ;limit
+ dw 0x0 ;base
+ db 0x0 ;base
+ db 10011010b ;flags
+ db 10001111b ;flags & seg.limit
+ db 0x0 ;base
+
+gdt16_data:
+ ; flags:
+ ; code: 0 / expand down: 0 / writable: 1 / accessed: 0
+ dw 0xffff
+ dw 0x0
+ db 0x0
+ db 10010010b
+ db 10001111b
+ db 0x0
+
+gdt_end:
+
+gdt_descriptor:
+ dw gdt_end-gdt_start-1
+ dd gdt_start
+
+CODE_SEG equ gdt_code - gdt_start
+DATA_SEG equ gdt_data - gdt_start
+CODE16_SEG equ gdt16_code - gdt_start
+DATA16_SEG equ gdt16_data - gdt_start
diff --git a/xxx/boot2/Makefile b/xxx/boot2/Makefile
new file mode 100644
index 0000000..f2537ce
--- /dev/null
+++ b/xxx/boot2/Makefile
@@ -0,0 +1,28 @@
+#master boot record
+
+include ../Makefile.common
+
+.PHONY: all clean
+
+STAGE2=stage2.bin
+MP=mp.bin
+CONFIG=config.inc
+
+
+
+ASM_SOURCES=$(wildcard *.asm)
+
+all: $(STAGE2) $(MP)
+
+$(CONFIG): ../kernel/config.h
+ cat ../kernel/config.h | grep "^#define" | sed -e "s/#/%/" -e "s/\/\/.*//" > $@
+
+$(STAGE2): $(ASM_SOURCES) $(CONFIG)
+$(MP): $(ASM_SOURCES)
+
+clean:
+ -rm $(STAGE2) $(MP) $(CONFIG)
+
+
+
+
diff --git a/xxx/boot2/check_a20_16.asm b/xxx/boot2/check_a20_16.asm
new file mode 100644
index 0000000..43da6e3
--- /dev/null
+++ b/xxx/boot2/check_a20_16.asm
@@ -0,0 +1,61 @@
+; The following code is public domain licensed
+
+[bits 16]
+
+; Function: check_a20
+;
+; Purpose: to check the status of the a20 line in a completely self-contained state-preserving way.
+; The function can be modified as necessary by removing push's at the beginning and their
+; respective pop's at the end if complete self-containment is not required.
+;
+; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
+; 1 in ax if the a20 line is enabled (memory does not wrap around)
+
+check_a20:
+ pushf
+ push ds
+ push es
+ push di
+ push si
+
+ cli
+
+ xor ax, ax ; ax = 0
+ mov es, ax
+
+ not ax ; ax = 0xFFFF
+ mov ds, ax
+
+ mov di, 0x0500
+ mov si, 0x0510
+
+ mov al, byte [es:di]
+ push ax
+
+ mov al, byte [ds:si]
+ push ax
+
+ mov byte [es:di], 0x00
+ mov byte [ds:si], 0xFF
+
+ cmp byte [es:di], 0xFF
+
+ pop ax
+ mov byte [ds:si], al
+
+ pop ax
+ mov byte [es:di], al
+
+ mov ax, 0
+ je check_a20__exit
+
+ mov ax, 1
+
+check_a20__exit:
+ pop si
+ pop di
+ pop es
+ pop ds
+ popf
+
+ ret
diff --git a/xxx/boot2/common_pm.asm b/xxx/boot2/common_pm.asm
new file mode 100644
index 0000000..c96e1a8
--- /dev/null
+++ b/xxx/boot2/common_pm.asm
@@ -0,0 +1,86 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+;print_string_pm
+;print_hex_pm
+;
+;
+;
+
+[bits 32]
+
+VIDEO_MEM equ 0xb8000
+WHITE_ON_BLACK equ 0x0f
+
+;global data
+STR_HEX_OUT_PM:
+ db "0x0000",0
+
+; print [ebx] at ecx
+print_string_pm:
+ pusha
+ mov edx, VIDEO_MEM
+ add edx,ecx
+ print_string_pm_loop:
+ mov al,[ebx]
+ mov ah, WHITE_ON_BLACK
+ cmp al,0
+ je print_string_pm_done
+ mov [edx],ax
+ add ebx,1
+ add edx,2
+ jmp print_string_pm_loop
+
+print_string_pm_done:
+ popa
+ ret
+
+;print_hex_pm routine (dx) at ecx
+;will print the value of the bx register as hex to the screen
+print_hex_pm:
+
+ pusha
+
+
+ ;begin with last hex val (hex_out[5])
+ mov bx,STR_HEX_OUT_PM+5
+
+ ;lets loop throuth all 4 'digits'
+ print_hex_pm_loop:
+
+ ;get least significan hex digit to cx
+ mov cx,dx
+ and cx,0x000F
+
+ ;check range (0-9 vs a-f)
+ cmp cx,10
+ jl print_hex_pm_setnum
+
+ ;set hex a-f
+ mov al,'A'-10
+ add al,cl
+ jmp print_hex_pm_al
+
+ ;set hex 0-9
+ print_hex_pm_setnum:
+ mov al,'0'
+ add al,cl
+
+ ; set hex_out[bx] to al
+ print_hex_pm_al:
+ mov [bx],al
+
+ ;proceed with the next significant hex 'digit'
+ dec bx
+ shr dx,4
+
+ ;check if finished (otherwise loop)
+ cmp bx,STR_HEX_OUT_PM+1
+ jne print_hex_pm_loop
+
+ ;output complete hex string and return to caller
+ popa
+ mov bx,STR_HEX_OUT_PM
+ call print_string_pm
+ ret
diff --git a/xxx/boot2/disk_load_16.asm b/xxx/boot2/disk_load_16.asm
new file mode 100644
index 0000000..65b1bff
--- /dev/null
+++ b/xxx/boot2/disk_load_16.asm
@@ -0,0 +1,281 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+;disk_load_16
+;
+
+[bits 16]
+
+STR_ERROR:
+ db "Disk Read Error",0
+
+STR_SPACE:
+ db " ",0
+
+STR_OK:
+ db "Kernel Loaded",0
+STR_PROGRESS:
+ db ".",0
+
+bpbSectorsPerTrack:
+ dw 18
+
+bpbHeadsPerCylinder:
+ dw 2
+
+LBA:
+ dw 10 ; current lba
+
+disk_load_16:
+
+ ; check if LBA is supported
+ mov ah,0x41
+ mov bx,0x55aa
+ int 0x13
+ jnc disk_load_lba
+ jmp disk_load_chs
+
+
+;#######################
+
+disk_load_lba:
+
+ pusha
+
+ mov bx,0x1800 ;target es:bx
+ mov es,bx
+ mov bx,0
+
+ next_sectors_lba:
+
+ jmp skip_debug_lba
+ ;show es - target
+ pusha
+ mov bx,es
+
+ ;mov al,bh
+ ;call print_hex_byte
+
+ ;mov al,bl
+ ;call print_hex_byte
+
+ mov bx,[LBA]
+
+ mov al,bh
+ call print_hex_byte
+
+ mov al,bl
+ call print_hex_byte
+
+ popa
+ ;--
+
+ skip_debug_lba:
+
+ mov [lba_addr_sector],es
+ mov ax,[LBA]
+ mov [lba_first_sector],ax
+
+ mov dl,[BOOT_DRIVE]
+
+ mov ah,0x42
+ mov bx,0
+ mov ds,bx
+ lea si,[lba_adr]
+ int 0x13
+ jc disk_read_error
+
+ mov bx,es
+ add bx,0x0800
+
+ mov ax,[LBA]
+ add ax,64 ; 64 sectors = 0x2000*4 bytes
+ mov [LBA],ax
+
+ cmp bx,0x9000
+ je disk_load_finish
+
+ mov es,bx ;next target es:bx
+ mov bx,0
+
+ jmp next_sectors_lba
+
+;#######################
+
+
+disk_load_chs:
+
+ pusha
+
+ ; get boot drive geometry
+ mov ah,8
+ mov dl,[BOOT_DRIVE]
+ int 0x13
+
+ add dh,1
+ and cl,0x3f
+
+ mov [bpbSectorsPerTrack],cl
+ mov [bpbHeadsPerCylinder],dh
+ ;
+
+ ;show geometry
+ mov al,dh
+ call print_hex_byte
+
+ mov bx, STR_SPACE
+ call print_string
+
+ mov al,cl
+ call print_hex_byte
+
+ call print_nextline
+ popa
+ ;
+
+ pusha
+
+
+ mov bx,0x1800 ;target es:bx
+ mov es,bx
+ mov bx,0
+
+ next_sectors_chs:
+
+ ;jmp skip_debug
+ pusha
+
+ mov bx, STR_SPACE
+ call print_string
+
+ ;show es - target
+ mov bx,es
+
+ mov al,bh
+ call print_hex_byte
+
+ mov al,bl
+ call print_hex_byte
+
+ mov bx, STR_SPACE
+ call print_string
+
+ ;show next LBA numer
+ mov ax,[LBA]
+ mov al,ah
+ call print_hex_byte
+
+ mov ax,[LBA]
+ call print_hex_byte
+
+ mov bx, STR_SPACE
+ call print_string
+
+ popa
+
+ mov ax,[LBA]
+
+ ;calculate chs
+ call lba_to_chs
+
+ ;show chs sector/ head / cylinder
+ mov al,cl
+ call print_hex_byte
+
+ mov al,dh
+ call print_hex_byte
+
+ mov al,ch
+ call print_hex_byte
+
+ call print_nextline
+
+ skip_debug:
+
+
+ mov ax,[LBA]
+
+ ;calculate chs
+ call lba_to_chs
+
+ ; and now READ it!
+ mov al,1 ;number of sectors to read
+ mov dl,[BOOT_DRIVE]
+
+ mov ah,0x02 ;BIOS read sector func
+ int 0x13 ;bios interrupt
+
+ jc disk_read_error
+
+ mov bx,es
+ add bx,0x0020
+ cmp bx,0x9000
+ je disk_load_finish
+
+ mov es,bx
+ mov bx,0
+
+ mov ax,[LBA]
+ add ax,1
+ mov [LBA],ax
+
+ jmp next_sectors_chs
+
+disk_read_error:
+ mov bx, STR_ERROR
+ call print_string
+ call print_nextline
+ ;jmp $
+
+disk_load_finish:
+
+ mov bx, STR_PROGRESS
+ call print_string
+; call print_nextline
+
+ popa
+ ret
+
+
+
+;lba to chs translation:
+; input : ax - lba
+; output: cl - sector
+; dh - head
+; ch - cylinder / track
+
+lba_to_chs:
+
+ xor dx, dx ; prepare dx:ax for operation
+ div WORD [bpbSectorsPerTrack] ; divide by sectors per track
+ inc dl ; add 1 (obsolute sector formula)
+ mov cl, dl
+
+ xor dx, dx ; prepare dx:ax for operation
+ div WORD [bpbHeadsPerCylinder] ; mod by number of heads (Absolue head formula)
+ mov dh,dl ; everything else was already done from the first formula
+
+ mov ch, al ; not much else to do :)
+ ret
+
+;; here we hold the lba addr
+lba_adr:
+
+ dw 0x10 ; size of packet ( 16 byte)
+ dw 64 ; number of sectors to read
+
+ ; target is 0x10000
+
+ dw 0x0000 ; target addr. offset
+
+lba_addr_sector:
+ dw 0x1800 ; target addr. sector
+
+lba_first_sector:
+ dw 10 ; first sector to read
+ dw 0
+
+ dd 0
+
+ ;
diff --git a/xxx/boot2/memmap.asm b/xxx/boot2/memmap.asm
new file mode 100644
index 0000000..d101557
--- /dev/null
+++ b/xxx/boot2/memmap.asm
@@ -0,0 +1,57 @@
+;---------------------------------------------
+; Get memory map from bios
+; /in es:di->destination buffer for entries
+; /ret bp=entry count
+;---------------------------------------------
+
+; stolen from: http://www.brokenthorn.com/Resources/OSDev17.html
+struc MemoryMapEntry
+ .baseAddress resq 1 ; base address of address range
+ .length resq 1 ; length of address range in bytes
+ .type resd 1 ; type of address range
+ .acpi_null resd 1 ; reserved
+endstruc
+
+[bits 16]
+
+BiosGetMemoryMap:
+ pushad
+ xor ebx, ebx
+ xor bp, bp ; number of entries stored here
+ mov edx, 'PAMS' ; 'SMAP'
+ mov eax, 0xe820
+ mov ecx, 24 ; memory map entry struct is 24 bytes
+ int 0x15 ; get first entry
+ jc .error
+ cmp eax, 'PAMS' ; bios returns SMAP in eax
+ jne .error
+ test ebx, ebx ; if ebx=0 then list is one entry long; bail out
+ je .error
+ jmp .start
+.next_entry:
+ mov edx, 'PAMS' ; some bios's trash this register
+ mov ecx, 24 ; entry is 24 bytes
+ mov eax, 0xe820
+ int 0x15 ; get next entry
+.start:
+ jcxz .skip_entry ; if actual returned bytes is 0, skip entry
+.notext:
+ mov ecx, [es:di + MemoryMapEntry.length] ; get length (low dword)
+ test ecx, ecx ; if length is 0 skip it
+ jne short .good_entry
+ mov ecx, [es:di + MemoryMapEntry.length + 4]; get length (upper dword)
+ jecxz .skip_entry ; if length is 0 skip it
+.good_entry:
+ inc bp ; increment entry count
+ add di, 24 ; point di to next entry in buffer
+.skip_entry:
+ cmp ebx, 0 ; if ebx return is 0, list is done
+ jne .next_entry ; get next entry
+ jmp .done
+.error:
+ stc
+.done:
+
+ mov [MEMMAP_SIZE_OFFSET],bp
+ popad
+ ret
diff --git a/xxx/boot2/mp.asm b/xxx/boot2/mp.asm
new file mode 100644
index 0000000..b6efd04
--- /dev/null
+++ b/xxx/boot2/mp.asm
@@ -0,0 +1,37 @@
+; other processors will enter here!
+[org 0x7000] ; here the binary will be loaded
+
+[bits 16]
+
+ cli ;switch off interrupts!
+ lgdt [gdt_descriptor] ;load descriptor table!
+
+ ;switch on 32-bit protected mode
+ mov eax, cr0
+ or eax,0x1
+ mov cr0, eax
+
+ jmp 0x8:init_pm
+
+[bits 32]
+init_pm:
+
+ mov ax, 0x10
+ mov ds, ax
+ mov ss, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov ebp, 0x95000
+ mov esp, ebp
+
+ call boot_32_pm ;continue booting in 32-bit protected mode
+
+boot_32_pm:
+
+ mov eax,1
+;
+ call 0x18000 ;jump into our Kernel!
+
+%include "GDT.asm"
diff --git a/xxx/boot2/pm.asm b/xxx/boot2/pm.asm
new file mode 100644
index 0000000..e6f3474
--- /dev/null
+++ b/xxx/boot2/pm.asm
@@ -0,0 +1,36 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; switch_to_pm - actual switch from 16bit real to 32bit protected
+; init_pm - sets up some regs and calls boot_32_pm
+;
+
+[bits 16]
+switch_to_pm:
+
+ cli ;switch off interrupts!
+ lgdt [gdt_descriptor] ;load descriptor table!
+; lldt [gdt_descriptor] ;load descriptor table! (local)
+
+ ;switch on 32-bit protected mode
+ mov eax, cr0
+ or eax,0x1
+ mov cr0, eax
+
+ jmp CODE_SEG:init_pm
+
+[bits 32]
+init_pm:
+
+ mov ax, DATA_SEG
+ mov ds, ax
+ mov ss, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov ebp, 0x07bff
+ mov esp, ebp
+
+ call boot_32_pm ;continue booting in 32-bit protected mode
diff --git a/xxx/boot2/print_string_16.asm b/xxx/boot2/print_string_16.asm
new file mode 100644
index 0000000..9f81a87
--- /dev/null
+++ b/xxx/boot2/print_string_16.asm
@@ -0,0 +1,115 @@
+[bits 16]
+
+BLANK:
+ db 0x12
+
+SPACE:
+ db " ",0
+
+;print_string routine ([bx])
+;this routine will print a null terminated string at [bx] to the screen.
+print_string:
+
+ pusha ;push all registers
+ mov ah,0x0e
+
+ print_string_loop:
+
+ ;check if value at [bx] is "\0" (end of string)
+ mov cl,[bx]
+ cmp cl,0
+ je print_string_finish
+
+ ;otherwise instruct BIOS to print the current char
+ mov al,cl
+ int 0x10
+
+ ;proceed with next char
+ inc bx
+ jmp print_string_loop
+
+ print_string_finish:
+
+ popa ;pop all registers
+ ret ;return to caller
+
+print_clear:
+
+pusha
+ mov ah,0x6 ;func
+ mov al,0 ;scroll one line
+ mov bh,[BLANK] ;blank char
+
+ mov ch,0 ;upper left corner
+ mov cl,0
+ mov dh,20 ;lower right corner
+ mov dl,40
+ int 0x10
+
+ mov ah,0x2
+ mov bh,0
+ mov dl,0
+ mov dh,20
+ int 0x10
+popa
+
+print_nextline:
+
+ pusha
+
+ mov ah,0x6 ;func
+ mov al,1 ;scroll one line
+ mov bh,[BLANK] ;blank char
+
+ mov ch,0 ;upper left corner
+ mov cl,0
+ mov dh,20 ;lower right corner
+ mov dl,40
+ int 0x10
+
+
+ mov ah,0x3
+ mov bh,0
+ int 0x10
+
+
+ mov ah,0x2
+ mov dl,0
+ int 0x10
+
+ mov bx,SPACE
+ call print_string
+
+ popa
+ ret
+
+
+;print byte from al to screen
+ print_hex_byte:
+
+ pusha
+
+ mov [.temp],al
+ shr al,4
+ cmp al,10
+ sbb al,69h
+ das
+
+ mov ah,0Eh
+ int 10h
+
+ mov al,[.temp]
+ ror al,4
+ shr al,4
+ cmp al,10
+ sbb al,69h
+ das
+
+ mov ah,0Eh
+ int 10h
+
+popa
+
+ ret
+
+ .temp db 0
diff --git a/xxx/boot2/stage2.asm b/xxx/boot2/stage2.asm
new file mode 100644
index 0000000..160d75c
--- /dev/null
+++ b/xxx/boot2/stage2.asm
@@ -0,0 +1,267 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; 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 0xa000
+MEMMAP_OFFSET equ 0xa001
+
+VESA_MODES equ 0xb000 ; do NOT overwrite yourself! be careful!
+VESA_MODE_INFO equ 0xc000
+
+VESA_MODE_SELECT equ 0x4114
+CHUNKS_TO_LOAD equ 0x20 ;number of 0x8000 * 512 byte chunks to load into ram
+;
+
+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
+
+; kernel config
+%include "config.inc"
+
+;
+;;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
+
+
+ ; hide text-mode cursor
+ mov ah,0x01
+ mov cx,0x2607
+ int 0x10
+
+
+ ;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,(CHUNKS_TO_LOAD-1)
+ jne skip_vesa_init
+
+ %ifndef FOOLOS_CONSOLE
+ call VesaSetup
+ %endif
+
+ 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)
+ ;each chunk is 0x8000 * 15 bytes
+ cmp ax,CHUNKS_TO_LOAD
+ 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,0x07000
+ 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
diff --git a/xxx/boot2/vesa_setup_16.asm b/xxx/boot2/vesa_setup_16.asm
new file mode 100644
index 0000000..5bee57c
--- /dev/null
+++ b/xxx/boot2/vesa_setup_16.asm
@@ -0,0 +1,93 @@
+VESA_CHECK1:
+ db "VESA: get modes!",0
+VESA_CHECK2:
+ db "VESA: get info on target mode!",0
+VESA_CHECK3:
+ db "VESA: switching to target mode!",0
+VESA_PAUSE:
+ db "[Press any key to switch to VESA 0x114]",0
+
+VesaSetup:
+
+ pusha
+
+ ;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_CHECK1
+ call print_string
+ call print_nextline
+ 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_CHECK2
+ call print_string
+ call print_nextline
+ cmp ax,0x004f
+ je vesa_ok2
+ jmp vesa_err2
+ vesa_ok2:
+
+ ;show press any key
+; call print_nextline
+; mov bx, VESA_PAUSE
+; call print_string
+; call print_nextline
+
+ ;preempt keyboard buffer
+
+ next_key:
+
+ mov ah,0x1 ;get scnacode from kb (non-blocking)
+ int 0x16
+ jnz get_key ; nothing to preempt
+
+ jmp wait_key
+
+ get_key:
+ mov ah,0 ;get key from buffer
+ int 0x16
+
+; mov al,ah
+; call print_hex_byte
+; call print_nextline
+
+ jmp next_key
+
+ ;;;;;;;;;;;;;;;;;
+ wait_key:
+; mov ah,0 ; block waiting for keyboard scancode
+; int 0x16
+
+
+ ;VESA: finally switch to the mode of choice!
+ mov ax,0x4f02 ;vesa function: Set Mode
+ mov bx,VESA_MODE_SELECT
+
+ int 0x10
+ cmp ax,0x004f
+ je vesa_ok3
+ vesa_err3:
+ mov bx, VESA_CHECK3
+ call print_string
+ call print_nextline
+ jmp vesa_err3
+ vesa_ok3:
+ popa
+ ret