use e820 to get available memory

main
pantonshire 1 year ago
parent 8e5761f610
commit fdf6d81b2e

@ -3,8 +3,9 @@
; --------------------------------------------------------------------
; R | 0x000000 - 0x000400: real-mode interrupt vector table
; R | 0x000400 - 0x000500: bios data area
; U | 0x000500 - 0x007000: stack
; U | 0x007000 - 0x007c00: globals
; U | 0x000500 - 0x004000: stack
; U | 0x004000 - 0x006a00: globals
; U | 0x006a00 - 0x007c00: memory map
; U | 0x007c00 - 0x007e00: boot sector
; U | 0x007e00 - 0x080000: conventional usable memory
; R | 0x080000 - 0x0a0000: extended bios data area (maximum possible size)
@ -29,7 +30,7 @@ main:
mov ds, ax
mov es, ax
; Put the stack base at 0x7000.
; Put the stack base at 0x4000.
; Stack grows high->low, so we'll grow away from our globals and program text.
mov ss, ax
mov bp, STACK_BASE

@ -247,8 +247,14 @@ main:
mov ax, msg_a20_enabled
call vga_println
call mem_detect
jc .mem_detect_fail
hlt
.mem_detect_fail:
panic PANIC_TYPE_MEM_DETECT
; Print a panic message then terminate.
; Arguments:
@ -704,6 +710,74 @@ enable_a20_intel_8042:
ret
mem_detect:
%if MEMMAP_CAP < 1
%error "memmap buffer too small"
%endif
fnstart
push es
mov word [GLOBALS + MEMMAP_ENTRIES], 0
; Memset the memmap buffer to 0.
xor ax, ax
mov es, ax
mov di, MEMMAP
mov cx, (MEMMAP_END - MEMMAP)
rep stosb
; Entry number (will be incremented for us)
xor ebx, ebx
; Buffer (es:di)
mov di, MEMMAP
mov dword [di + 0x20], 0x1
; Entry size
mov ecx, MEMMAP_ENT_SIZE
; Magic number
mov edx, E820_MAGIC
; Detect memory
mov eax, 0xe820
clc
int 0x15
jc .fail
cmp eax, E820_MAGIC
jne .fail
inc word [GLOBALS + MEMMAP_ENTRIES]
.loop:
cmp word [GLOBALS + MEMMAP_ENTRIES], MEMMAP_CAP
jae .done
add di, MEMMAP_ENT_SIZE
mov dword [di + 0x20], 0x1
mov ecx, MEMMAP_ENT_SIZE
mov eax, 0xe820
clc
int 0x15
; Carry flag will be set if we'd already reached the end of the entries.
jc .done
inc word [GLOBALS + MEMMAP_ENTRIES]
test ebx, ebx
jz .done
jmp .loop
.fail:
stc
jmp .return
.done:
clc
.return:
pop es
fnret
msg_boot1_loaded db "boot1 loaded. hello!", 0
msg_a20_enabled db "a20 enabled", 0
msg_a20_disabled db "a20 not enabled", 0
@ -746,15 +820,18 @@ table_reg_msgs:
dw msg_reg_flags
dw 0
msg_panic_generic db "generic panic", 0
msg_panic_a20 db "failed to enable a20 line", 0
msg_panic_generic db "generic panic", 0
msg_panic_a20 db "failed to enable a20 line", 0
msg_panic_mem_detect db "failed to detect available memory", 0
panic_type_msgs:
PANIC_TYPE_GENERIC equ ($ - panic_type_msgs) / 2
PANIC_TYPE_GENERIC equ ($ - panic_type_msgs) / 2
dw msg_panic_generic
PANIC_TYPE_A20 equ ($ - panic_type_msgs) / 2
PANIC_TYPE_A20 equ ($ - panic_type_msgs) / 2
dw msg_panic_a20
PANIC_TYPE_MAX equ ($ - panic_type_msgs) / 2
PANIC_TYPE_MEM_DETECT equ ($ - panic_type_msgs) / 2
dw msg_panic_mem_detect
PANIC_TYPE_MAX equ ($ - panic_type_msgs) / 2
dw 0
boot1_magic dd BOOT1_MAGIC

@ -1,8 +1,14 @@
%define BOOT0_LOADPOINT 0x7c00
%define BOOT1_LOADPOINT 0x8200
%define GLOBALS 0x7000
%define STACK_BASE GLOBALS
%define MEMMAP 0x6a00
%define MEMMAP_END BOOT0_LOADPOINT
%define MEMMAP_ENT_SIZE 24
%define MEMMAP_CAP ((MEMMAP_END - MEMMAP) / MEMMAP_ENT_SIZE)
%define GLOBALS 0x4000
%define GLOBALS_END MEMMAP
%define STACK_BASE GLOBALS
%define EBDA_START 0x080000
@ -25,6 +31,9 @@
%define INTEL_8042_CMD_CONTROLLER_OUT_PORT_READ 0xd0
%define INTEL_8042_CMD_CONTROLLER_OUT_PORT_WRITE 0xd1
; ASCII string "SMAP", which is used by e820 as a magic number argument and return value.
%define E820_MAGIC 0x534d4150
; boot0 base stack frame variable offsets / globals
; (we use the same offsets once we copy the variables to the globals section)
; -------------------------------------------------------------------------------------------------
@ -53,6 +62,7 @@
; ------------------------------------------------------------------------------------------------
%define VGA_COL 0x1c
%define TEXTBUF_LINE 0x1e
%define MEMMAP_ENTRIES 0x20
%macro fnstart 0
push bp

@ -15,6 +15,7 @@
## Memory
- <https://wiki.osdev.org/Memory_Map_(x86)>
- <https://wiki.osdev.org/Detecting_Memory_(x86)>
- <http://www.uruk.org/orig-grub/mem64mb.html>
## BIOS interrupts
- <https://en.wikipedia.org/wiki/BIOS_interrupt_call>

Loading…
Cancel
Save