From fdf6d81b2e5fe2170b445606433a0580388022f7 Mon Sep 17 00:00:00 2001 From: pantonshire Date: Tue, 23 Jul 2024 07:40:29 +0100 Subject: [PATCH] use e820 to get available memory --- boot0.s | 7 +++-- boot1.s | 87 +++++++++++++++++++++++++++++++++++++++++++++++++--- defines.s | 14 +++++++-- resources.md | 1 + 4 files changed, 99 insertions(+), 10 deletions(-) diff --git a/boot0.s b/boot0.s index 0f16081..cce1163 100644 --- a/boot0.s +++ b/boot0.s @@ -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 diff --git a/boot1.s b/boot1.s index 5b61e6e..a3f96f0 100644 --- a/boot1.s +++ b/boot1.s @@ -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 diff --git a/defines.s b/defines.s index 747922e..40d3897 100644 --- a/defines.s +++ b/defines.s @@ -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 diff --git a/resources.md b/resources.md index b1c31a2..32de0dd 100644 --- a/resources.md +++ b/resources.md @@ -15,6 +15,7 @@ ## Memory - - +- ## BIOS interrupts -