From e3cc5f6c89ba9f37bf2c1edf588d0f75c1d63c57 Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Fri, 14 Nov 2014 11:08:04 +0100 Subject: rename dirs --- boot/GDT.asm | 76 ------------- boot/Makefile | 16 --- boot/check_a20_16.asm | 61 ---------- boot/common_pm.asm | 86 -------------- boot/disk_load_16.asm | 281 ---------------------------------------------- boot/kernel_entry.asm | 20 ---- boot/memmap.asm | 57 ---------- boot/mp.asm | 37 ------ boot/pm.asm | 36 ------ boot/print_string_16.asm | 115 ------------------- boot/stage2.asm | 247 ---------------------------------------- boot/vesa_setup_16.asm | 92 --------------- boot0/Makefile | 16 --- boot0/disk_load_16.asm | 102 ----------------- boot0/mbr.asm | 106 ----------------- boot0/print_string_16.asm | 115 ------------------- boot1/Makefile | 16 +++ boot1/disk_load_16.asm | 102 +++++++++++++++++ boot1/mbr.asm | 106 +++++++++++++++++ boot1/print_string_16.asm | 115 +++++++++++++++++++ boot2/GDT.asm | 76 +++++++++++++ boot2/Makefile | 16 +++ boot2/check_a20_16.asm | 61 ++++++++++ boot2/common_pm.asm | 86 ++++++++++++++ boot2/disk_load_16.asm | 281 ++++++++++++++++++++++++++++++++++++++++++++++ boot2/kernel_entry.asm | 20 ++++ boot2/memmap.asm | 57 ++++++++++ boot2/mp.asm | 37 ++++++ boot2/pm.asm | 36 ++++++ boot2/print_string_16.asm | 115 +++++++++++++++++++ boot2/stage2.asm | 247 ++++++++++++++++++++++++++++++++++++++++ boot2/vesa_setup_16.asm | 92 +++++++++++++++ 32 files changed, 1463 insertions(+), 1463 deletions(-) delete mode 100644 boot/GDT.asm delete mode 100644 boot/Makefile delete mode 100644 boot/check_a20_16.asm delete mode 100644 boot/common_pm.asm delete mode 100644 boot/disk_load_16.asm delete mode 100644 boot/kernel_entry.asm delete mode 100644 boot/memmap.asm delete mode 100644 boot/mp.asm delete mode 100644 boot/pm.asm delete mode 100644 boot/print_string_16.asm delete mode 100644 boot/stage2.asm delete mode 100644 boot/vesa_setup_16.asm delete mode 100644 boot0/Makefile delete mode 100644 boot0/disk_load_16.asm delete mode 100644 boot0/mbr.asm delete mode 100644 boot0/print_string_16.asm create mode 100644 boot1/Makefile create mode 100644 boot1/disk_load_16.asm create mode 100644 boot1/mbr.asm create mode 100644 boot1/print_string_16.asm create mode 100644 boot2/GDT.asm create mode 100644 boot2/Makefile create mode 100644 boot2/check_a20_16.asm create mode 100644 boot2/common_pm.asm create mode 100644 boot2/disk_load_16.asm create mode 100644 boot2/kernel_entry.asm create mode 100644 boot2/memmap.asm create mode 100644 boot2/mp.asm create mode 100644 boot2/pm.asm create mode 100644 boot2/print_string_16.asm create mode 100644 boot2/stage2.asm create mode 100644 boot2/vesa_setup_16.asm diff --git a/boot/GDT.asm b/boot/GDT.asm deleted file mode 100644 index cc33c45..0000000 --- a/boot/GDT.asm +++ /dev/null @@ -1,76 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; 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 -; -; -; -; - -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 10001111b - 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 11001111b - 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/boot/Makefile b/boot/Makefile deleted file mode 100644 index 17dc454..0000000 --- a/boot/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#master boot record - -include ../Makefile.common - -STAGE2=stage2.bin - -ASM_SOURCES=$(wildcard *.asm) - -$(STAGE2): $(ASM_SOURCES) - -clean: - -rm $(STAGE2) - - - - diff --git a/boot/check_a20_16.asm b/boot/check_a20_16.asm deleted file mode 100644 index 43da6e3..0000000 --- a/boot/check_a20_16.asm +++ /dev/null @@ -1,61 +0,0 @@ -; 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/boot/common_pm.asm b/boot/common_pm.asm deleted file mode 100644 index c96e1a8..0000000 --- a/boot/common_pm.asm +++ /dev/null @@ -1,86 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; 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/boot/disk_load_16.asm b/boot/disk_load_16.asm deleted file mode 100644 index 52912f4..0000000 --- a/boot/disk_load_16.asm +++ /dev/null @@ -1,281 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; 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 ;16 sectors this is 0x200*0x10 butes - 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/boot/kernel_entry.asm b/boot/kernel_entry.asm deleted file mode 100644 index 53f63ad..0000000 --- a/boot/kernel_entry.asm +++ /dev/null @@ -1,20 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; this will be compiled to an object file and linked with the kernel -; to simplify the entrance! -; -; -[bits 32] -[extern kernel_main] - -push 0x1 - -cmp eax,1 -je multiproc -push 0x0 -multiproc: - -push esp -call kernel_main ; jumps in the world of C diff --git a/boot/memmap.asm b/boot/memmap.asm deleted file mode 100644 index d101557..0000000 --- a/boot/memmap.asm +++ /dev/null @@ -1,57 +0,0 @@ -;--------------------------------------------- -; 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/boot/mp.asm b/boot/mp.asm deleted file mode 100644 index 072aa74..0000000 --- a/boot/mp.asm +++ /dev/null @@ -1,37 +0,0 @@ -; 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 "boot/GDT.asm" diff --git a/boot/pm.asm b/boot/pm.asm deleted file mode 100644 index e6f3474..0000000 --- a/boot/pm.asm +++ /dev/null @@ -1,36 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;; 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/boot/print_string_16.asm b/boot/print_string_16.asm deleted file mode 100644 index 9f81a87..0000000 --- a/boot/print_string_16.asm +++ /dev/null @@ -1,115 +0,0 @@ -[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/boot/stage2.asm b/boot/stage2.asm deleted file mode 100644 index 0a3ee87..0000000 --- a/boot/stage2.asm +++ /dev/null @@ -1,247 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; 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 diff --git a/boot/vesa_setup_16.asm b/boot/vesa_setup_16.asm deleted file mode 100644 index d4c6ca2..0000000 --- a/boot/vesa_setup_16.asm +++ /dev/null @@ -1,92 +0,0 @@ -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 diff --git a/boot0/Makefile b/boot0/Makefile deleted file mode 100644 index e930498..0000000 --- a/boot0/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#master boot record - -include ../Makefile.common - -MBR=mbr.bin - -ASM_SOURCES=$(wildcard *.asm) - -$(MBR): $(ASM_SOURCES) - -clean: - -rm $(MBR) - - - - diff --git a/boot0/disk_load_16.asm b/boot0/disk_load_16.asm deleted file mode 100644 index 76102ad..0000000 --- a/boot0/disk_load_16.asm +++ /dev/null @@ -1,102 +0,0 @@ -; -;disk_load_16 -; - -[bits 16] - -STR_LBA: - db "LBA Support Detected",0 - -STR_CHS: - db "CHS BROKEN SORRY(?)",0 - -STR_ERROR: - db "Disk Read Error",0 - -STR_DONE: - db "Stage 2 Loaded",0 - -disk_load_16: - - pusha - - ; check if LBA is supported - mov ah,0x41 - mov bx,0x55aa - int 0x13 - jnc disk_load_lba - jmp disk_load_chs - -disk_load_lba: - - mov bx, STR_LBA - call print_string - call print_nextline - - mov dl,[BOOT_DRIVE] - xor ah,ah - mov ah,0x42 - - mov bx,0 - mov ds,bx - lea si,[lba_adr] - - int 0x13 - jnc disk_load_finish - jmp disk_load_error - -disk_load_chs: - - mov bx, STR_CHS - call print_string - call print_nextline - - mov bx,0 ;target es:bx - mov es,bx - mov bx,0x7e00 - - mov al,50 ;number of sectors to read - mov ah,0x02 ;BIOS read sector func - - mov cl,2 ; sector - mov ch,0 ; cylinder - - mov dl,[BOOT_DRIVE] - mov dh,0 ;head - - int 0x13 ;bios interrupt - - jnc disk_load_finish - -disk_load_error: - - call print_nextline - mov bx, STR_ERROR - call print_string - call print_nextline - jmp $ - -disk_load_finish: - - call print_nextline - mov bx, STR_DONE - call print_string - call print_nextline - - - popa - ret - - -;; here we hold the lba addr -lba_adr: - - dw 0x10 ; size of packet ( 16 byte) - dw 16 ; number of sectors to read - - ; target is 0x7e00 - dw 0x7e00 ; target addr. offset - dw 0x0000 ; target addr. sector - - dd 1 ; first sector to read - dd 0 diff --git a/boot0/mbr.asm b/boot0/mbr.asm deleted file mode 100644 index c0a555d..0000000 --- a/boot0/mbr.asm +++ /dev/null @@ -1,106 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; FOOL-OS Master Boot Record -; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; This is the Master Boot Record for x86 -; -; We are limited to 512 bytes (one sector) -; minus 64 bytes for the partition table -; minus 2 bytes formagic number (0xaa55) -; -; all we do here is : -; -; 1. Put the Stack at 0x07bff (it is counting down) -; 2. Remeber Boot Drive at [BOOT_DRIVE] -; 3. Print PR message and Boot Drive number -; 4. Load Second Stage Bootloader from Boot Drive at next sector -; 5. Show Info Message after successfull loading -; 6. Jump to 2nd Stage Boot Loader -; -; Refer to a memory map as needed: -; http://wiki.osdev.org/Memory_Map_(x86) - -; Everything here is 16bit -[bits 16] - -; Per definition this will be loaded by the BIOS at 0x7c00 -[org 0x7c00] - -; skip constants and includes -jmp stage1 - -; string constants (null terminated) -STR_1: db "Fool Loader Stage 1. v0.1",0 -STR_2: db "Starting Stage 2",0 -STR_BOOT: db "Boot drive: ",0 - -; some space (one byte) to remember the Boot Drive -BOOT_DRIVE: db 0xff - -; include print and disk load routines -%include "print_string_16.asm" -%include "disk_load_16.asm" - -; Here we start! -stage1: - - ; first of all, setup the stack (right under our MBR) - ; ~30KB space guaranteed - mov bp,0x07bff - mov sp,bp - - ; remember BOOT_DRIVE (as was set by BIOS in dl) - mov [BOOT_DRIVE],dl - - ; clear screen and print PR message - call print_clear - call print_nextline - - mov bx, STR_1 - call print_string - call print_nextline - - - ; print bootdrive number - mov bx, STR_BOOT - call print_string - - mov al,[BOOT_DRIVE] - call print_hex_byte - call print_nextline - - - ; Actually Load the Second Stage Bootloader! - call disk_load_16 - - - ; show info message that 2nd Stage was loaded - mov bx, STR_2 - call print_string - call print_nextline - call print_nextline - - - ; save Boot Drive in dl for second stage - mov dl,[BOOT_DRIVE] - - - ; jump to the next sector where we loaded the 2nd stage - jmp 0x7e00 - - - ; nothing essential under this line - ; we need this to follow some mbr standards - - ; fill at least 4x16byte with zeroes. (partition table) - ; (otherwise my Acer Aspire will not boot) - times 64 db 0x0 - - ; fill rest with zeroes - times 510-($-$$) db 0x0 - - ; magic number so we get identified as MBR - dw 0xaa55 - diff --git a/boot0/print_string_16.asm b/boot0/print_string_16.asm deleted file mode 100644 index 9f81a87..0000000 --- a/boot0/print_string_16.asm +++ /dev/null @@ -1,115 +0,0 @@ -[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/boot1/Makefile b/boot1/Makefile new file mode 100644 index 0000000..e930498 --- /dev/null +++ b/boot1/Makefile @@ -0,0 +1,16 @@ +#master boot record + +include ../Makefile.common + +MBR=mbr.bin + +ASM_SOURCES=$(wildcard *.asm) + +$(MBR): $(ASM_SOURCES) + +clean: + -rm $(MBR) + + + + diff --git a/boot1/disk_load_16.asm b/boot1/disk_load_16.asm new file mode 100644 index 0000000..76102ad --- /dev/null +++ b/boot1/disk_load_16.asm @@ -0,0 +1,102 @@ +; +;disk_load_16 +; + +[bits 16] + +STR_LBA: + db "LBA Support Detected",0 + +STR_CHS: + db "CHS BROKEN SORRY(?)",0 + +STR_ERROR: + db "Disk Read Error",0 + +STR_DONE: + db "Stage 2 Loaded",0 + +disk_load_16: + + pusha + + ; check if LBA is supported + mov ah,0x41 + mov bx,0x55aa + int 0x13 + jnc disk_load_lba + jmp disk_load_chs + +disk_load_lba: + + mov bx, STR_LBA + call print_string + call print_nextline + + mov dl,[BOOT_DRIVE] + xor ah,ah + mov ah,0x42 + + mov bx,0 + mov ds,bx + lea si,[lba_adr] + + int 0x13 + jnc disk_load_finish + jmp disk_load_error + +disk_load_chs: + + mov bx, STR_CHS + call print_string + call print_nextline + + mov bx,0 ;target es:bx + mov es,bx + mov bx,0x7e00 + + mov al,50 ;number of sectors to read + mov ah,0x02 ;BIOS read sector func + + mov cl,2 ; sector + mov ch,0 ; cylinder + + mov dl,[BOOT_DRIVE] + mov dh,0 ;head + + int 0x13 ;bios interrupt + + jnc disk_load_finish + +disk_load_error: + + call print_nextline + mov bx, STR_ERROR + call print_string + call print_nextline + jmp $ + +disk_load_finish: + + call print_nextline + mov bx, STR_DONE + call print_string + call print_nextline + + + popa + ret + + +;; here we hold the lba addr +lba_adr: + + dw 0x10 ; size of packet ( 16 byte) + dw 16 ; number of sectors to read + + ; target is 0x7e00 + dw 0x7e00 ; target addr. offset + dw 0x0000 ; target addr. sector + + dd 1 ; first sector to read + dd 0 diff --git a/boot1/mbr.asm b/boot1/mbr.asm new file mode 100644 index 0000000..c0a555d --- /dev/null +++ b/boot1/mbr.asm @@ -0,0 +1,106 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; FOOL-OS Master Boot Record +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; This is the Master Boot Record for x86 +; +; We are limited to 512 bytes (one sector) +; minus 64 bytes for the partition table +; minus 2 bytes formagic number (0xaa55) +; +; all we do here is : +; +; 1. Put the Stack at 0x07bff (it is counting down) +; 2. Remeber Boot Drive at [BOOT_DRIVE] +; 3. Print PR message and Boot Drive number +; 4. Load Second Stage Bootloader from Boot Drive at next sector +; 5. Show Info Message after successfull loading +; 6. Jump to 2nd Stage Boot Loader +; +; Refer to a memory map as needed: +; http://wiki.osdev.org/Memory_Map_(x86) + +; Everything here is 16bit +[bits 16] + +; Per definition this will be loaded by the BIOS at 0x7c00 +[org 0x7c00] + +; skip constants and includes +jmp stage1 + +; string constants (null terminated) +STR_1: db "Fool Loader Stage 1. v0.1",0 +STR_2: db "Starting Stage 2",0 +STR_BOOT: db "Boot drive: ",0 + +; some space (one byte) to remember the Boot Drive +BOOT_DRIVE: db 0xff + +; include print and disk load routines +%include "print_string_16.asm" +%include "disk_load_16.asm" + +; Here we start! +stage1: + + ; first of all, setup the stack (right under our MBR) + ; ~30KB space guaranteed + mov bp,0x07bff + mov sp,bp + + ; remember BOOT_DRIVE (as was set by BIOS in dl) + mov [BOOT_DRIVE],dl + + ; clear screen and print PR message + call print_clear + call print_nextline + + mov bx, STR_1 + call print_string + call print_nextline + + + ; print bootdrive number + mov bx, STR_BOOT + call print_string + + mov al,[BOOT_DRIVE] + call print_hex_byte + call print_nextline + + + ; Actually Load the Second Stage Bootloader! + call disk_load_16 + + + ; show info message that 2nd Stage was loaded + mov bx, STR_2 + call print_string + call print_nextline + call print_nextline + + + ; save Boot Drive in dl for second stage + mov dl,[BOOT_DRIVE] + + + ; jump to the next sector where we loaded the 2nd stage + jmp 0x7e00 + + + ; nothing essential under this line + ; we need this to follow some mbr standards + + ; fill at least 4x16byte with zeroes. (partition table) + ; (otherwise my Acer Aspire will not boot) + times 64 db 0x0 + + ; fill rest with zeroes + times 510-($-$$) db 0x0 + + ; magic number so we get identified as MBR + dw 0xaa55 + diff --git a/boot1/print_string_16.asm b/boot1/print_string_16.asm new file mode 100644 index 0000000..9f81a87 --- /dev/null +++ b/boot1/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/boot2/GDT.asm b/boot2/GDT.asm new file mode 100644 index 0000000..cc33c45 --- /dev/null +++ b/boot2/GDT.asm @@ -0,0 +1,76 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; 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 +; +; +; +; + +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 10001111b + 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 11001111b + 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/boot2/Makefile b/boot2/Makefile new file mode 100644 index 0000000..17dc454 --- /dev/null +++ b/boot2/Makefile @@ -0,0 +1,16 @@ +#master boot record + +include ../Makefile.common + +STAGE2=stage2.bin + +ASM_SOURCES=$(wildcard *.asm) + +$(STAGE2): $(ASM_SOURCES) + +clean: + -rm $(STAGE2) + + + + diff --git a/boot2/check_a20_16.asm b/boot2/check_a20_16.asm new file mode 100644 index 0000000..43da6e3 --- /dev/null +++ b/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/boot2/common_pm.asm b/boot2/common_pm.asm new file mode 100644 index 0000000..c96e1a8 --- /dev/null +++ b/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/boot2/disk_load_16.asm b/boot2/disk_load_16.asm new file mode 100644 index 0000000..52912f4 --- /dev/null +++ b/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 ;16 sectors this is 0x200*0x10 butes + 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/boot2/kernel_entry.asm b/boot2/kernel_entry.asm new file mode 100644 index 0000000..53f63ad --- /dev/null +++ b/boot2/kernel_entry.asm @@ -0,0 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; Miguel's FoolOS Helper Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; this will be compiled to an object file and linked with the kernel +; to simplify the entrance! +; +; +[bits 32] +[extern kernel_main] + +push 0x1 + +cmp eax,1 +je multiproc +push 0x0 +multiproc: + +push esp +call kernel_main ; jumps in the world of C diff --git a/boot2/memmap.asm b/boot2/memmap.asm new file mode 100644 index 0000000..d101557 --- /dev/null +++ b/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/boot2/mp.asm b/boot2/mp.asm new file mode 100644 index 0000000..072aa74 --- /dev/null +++ b/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 "boot/GDT.asm" diff --git a/boot2/pm.asm b/boot2/pm.asm new file mode 100644 index 0000000..e6f3474 --- /dev/null +++ b/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/boot2/print_string_16.asm b/boot2/print_string_16.asm new file mode 100644 index 0000000..9f81a87 --- /dev/null +++ b/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/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 diff --git a/boot2/vesa_setup_16.asm b/boot2/vesa_setup_16.asm new file mode 100644 index 0000000..d4c6ca2 --- /dev/null +++ b/boot2/vesa_setup_16.asm @@ -0,0 +1,92 @@ +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 -- cgit v1.2.3