From c8a976eced96f3af4a17d756c34cdd566ffa8a9e Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Thu, 7 Aug 2014 03:01:23 +0200 Subject: optimized MBR and added memmap identification --- boot/common.asm | 167 ++++++++++++++++++++++++++++---------------------------- boot/mbr.asm | 26 +++++---- boot/memmap.asm | 55 +++++++++++++++++++ 3 files changed, 154 insertions(+), 94 deletions(-) create mode 100644 boot/memmap.asm (limited to 'boot') diff --git a/boot/common.asm b/boot/common.asm index c241f55..323b54f 100644 --- a/boot/common.asm +++ b/boot/common.asm @@ -12,89 +12,90 @@ [bits 16] - -;global data -STR_HEX_OUT: - db "0x0000",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_hex routine (dx) -;will print the value of the bx register as hex to the screen -print_hex: - - pusha - - ;begin with last hex val (hex_out[5]) - mov bx,STR_HEX_OUT+5 - - ;lets loop throuth all 4 'digits' - print_hex_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_setnum - - ;set hex a-f - mov al,'A'-10 - add al,cl - jmp print_hex_al - - ;set hex 0-9 - print_hex_setnum: - mov al,'0' - add al,cl - - ; set hex_out[bx] to al - print_hex_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+1 - jne print_hex_loop - - ;output complete hex string and return to caller - mov bx,STR_HEX_OUT - call print_string - popa - ret - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;/* +;;global data +;STR_HEX_OUT: +; db "0x0000",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_hex routine (dx) +;;will print the value of the bx register as hex to the screen +;print_hex: +; +; pusha +; +; ;begin with last hex val (hex_out[5]) +; mov bx,STR_HEX_OUT+5 +; +; ;lets loop throuth all 4 'digits' +; print_hex_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_setnum +; +; ;set hex a-f +; mov al,'A'-10 +; add al,cl +; jmp print_hex_al +; +; ;set hex 0-9 +; print_hex_setnum: +; mov al,'0' +; add al,cl +; +; ; set hex_out[bx] to al +; print_hex_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+1 +; jne print_hex_loop +; +; ;output complete hex string and return to caller +; mov bx,STR_HEX_OUT +; call print_string +; popa +; ret +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;*/ ;disk_load routune (load dh sectors from drive dl to es:bx) disk_load: diff --git a/boot/mbr.asm b/boot/mbr.asm index a6dc876..12b7707 100644 --- a/boot/mbr.asm +++ b/boot/mbr.asm @@ -27,11 +27,12 @@ jmp boot_16 ;start boot process ;SOME Global Data, mainly strings STR_VERSION: - db "_<-Fool-Loader~0.0.13~",0 +; db "v0.2~",0 STR_PROT: - db "Entered 32-bit Protected Mode.",0 +; db "32-bit PM",0 STR_LOADED: - db "FoolOS Kernel Loaded.",0 +; db "loaded",0 + BOOT_DRIVE: db 0 @@ -42,7 +43,7 @@ BOOT_DRIVE: %include "boot/common.asm" ;include 32-bit Protected Mode routines (print_string_pm,print_hex_pm) -%include "boot/common_pm.asm" +;%include "boot/common_pm.asm" ;include our routines for switching to 32-bit protected mode %include "boot/pm.asm" @@ -50,6 +51,9 @@ BOOT_DRIVE: ;pic mapping %include "boot/pic.asm" +;memory map +%include "boot/memmap.asm" + ;;;;;;;; BOOT 16-bit real ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;lets start @@ -64,8 +68,8 @@ boot_16: mov [BOOT_DRIVE],dl ;print FoolOS version info - mov bx, STR_VERSION - call print_string +; mov bx, STR_VERSION +; call print_string ;Load the KERNEL mov bx,KERNEL_OFFSET @@ -74,8 +78,8 @@ boot_16: call disk_load ;print info message that kernel was loaded - mov bx, STR_LOADED - call print_string +; mov bx, STR_LOADED +; call print_string ;finally lets enter Protected mode!!! call switch_to_pm @@ -85,9 +89,9 @@ boot_16: boot_32_pm: ;print info message that we are in protected mode! - mov ecx,160 - mov ebx,STR_PROT - call print_string_pm +; mov ecx,160 +; mov ebx,STR_PROT +; call print_string_pm ;enable A20 ;http://www.brokenthorn.com/Resources/OSDev9.html diff --git a/boot/memmap.asm b/boot/memmap.asm new file mode 100644 index 0000000..29d48f3 --- /dev/null +++ b/boot/memmap.asm @@ -0,0 +1,55 @@ +;--------------------------------------------- +; 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: + popad + ret -- cgit v1.2.3