From d00271672b67f2f05d061dcdc7e5c2c8d031f14a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Duje=20Mihanovi=C4=87?= Date: Fri, 17 Jun 2022 20:47:51 +0200 Subject: [PATCH] Get memory map from BIOS E820 The entry order is reversed, but otherwise the map makes sense. Also print the map out to screen. --- boot/x86/stage3/e820.s | 65 +++++++++++++++++++++++++++++++++++++++ boot/x86/stage3/loader.s | 3 ++ include/arch/x86/tty.h | 1 + kernel/arch/x86/tty/tty.c | 38 +++++++++++++++++++++++ kernel/entry.s | 2 ++ kernel/kernel.c | 27 +++++++++++++++- 6 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 boot/x86/stage3/e820.s diff --git a/boot/x86/stage3/e820.s b/boot/x86/stage3/e820.s new file mode 100644 index 0000000..247b361 --- /dev/null +++ b/boot/x86/stage3/e820.s @@ -0,0 +1,65 @@ +; Code for getting the BIOS E820 memory map + +bits 16 + +; Return: ECX - number of entries, DI - pointer to map +get_e820_map: + push eax + push ebx + push edx + push esi + push es + + xor ax, ax + mov es, ax + push dword 1 + sub sp, 20 + xor si, si + xor ebx, ebx + mov edx, 0x534d4150 + mov eax, 0xe820 + mov ecx, 24 + mov di, sp + int 0x15 + jc .no_e820 + cmp eax, 0x534d4150 + jne .unexpected + inc si + .loop: + push dword 1 + sub sp, 20 + mov di, sp + mov eax, 0xe820 + mov ecx, 24 + int 0x15 + jc .carry_done + inc si + cmp ebx, 0 + je .done + jmp .loop + .carry_done: + add sp, 24 + .done: + movzx ecx, si + movzx edi, sp + mov ax, 24 + mul si + add sp, ax + pop es + pop esi + pop edx + pop ebx + pop eax + ret + .no_e820: + print no_e820 + hlt + jmp $-1 + .unexpected + print e820_unexpected + call print_dword + hlt + jmp $-1 + +no_e820: db "BIOS does not support E820, cannot proceed!", 0xd, 0xa, 0 +e820_unexpected: db "Unexpected value in EAX after getting map entry: expected SMAP, got ", 0 diff --git a/boot/x86/stage3/loader.s b/boot/x86/stage3/loader.s index 2967c6e..0ca0ea6 100644 --- a/boot/x86/stage3/loader.s +++ b/boot/x86/stage3/loader.s @@ -64,6 +64,8 @@ _start: call read_clus_chain_unreal ; load kernel print kernel_loaded + call get_e820_map + cli lgdt [gdt] mov eax, cr0 @@ -151,6 +153,7 @@ memcpy: %include "../fat32/fat32.s" %include "gdt.s" %include "print.s" +%include "e820.s" in_protected: bits 32 diff --git a/include/arch/x86/tty.h b/include/arch/x86/tty.h index 2224737..ce49da9 100644 --- a/include/arch/x86/tty.h +++ b/include/arch/x86/tty.h @@ -25,4 +25,5 @@ extern void kprint(const char *string, uint8_t color); extern void kprintb(const uint8_t byte); extern void kprintw(const uint16_t word); extern void kprintd(const uint32_t dword); +extern void kprintq(const uint64_t qword); #endif diff --git a/kernel/arch/x86/tty/tty.c b/kernel/arch/x86/tty/tty.c index 07d734e..2110a7d 100644 --- a/kernel/arch/x86/tty/tty.c +++ b/kernel/arch/x86/tty/tty.c @@ -137,3 +137,41 @@ void kprintd(uint32_t dword) temp = dword & 0xF; kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); } + +void kprintq(uint64_t qword) +{ + uint8_t temp; + temp = qword >> 60; + kprint("0x", VGA_COLOR_LIGHT_GRAY); + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 56) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 52) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 48) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 44) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 40) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 36) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 32) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 28) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 24) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 20) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 16) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 12) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 8) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = (qword >> 4) & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); + temp = qword & 0xF; + kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY); +} diff --git a/kernel/entry.s b/kernel/entry.s index 10c95e8..5ef71bb 100644 --- a/kernel/entry.s +++ b/kernel/entry.s @@ -6,6 +6,8 @@ global _start _start: mov ebp, __STACK_BOTTOM__ mov esp, ebp + push ecx + push edi call kmain hlt jmp $-1 diff --git a/kernel/kernel.c b/kernel/kernel.c index 060051c..0aa8fc2 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -11,13 +11,38 @@ extern void pf_handler(struct fault_frame *frame); static struct idt_descriptor idt[256] __attribute__((aligned(0x10))); static struct idtr idtr __attribute__((aligned(0x10))); +struct e820_map { + uint64_t base; + uint64_t length; + uint32_t type; + uint32_t attrib; +}; -void kmain(void) +void print_e820(struct e820_map *mmap, int mmap_size) +{ + kprint(" Base | Length | Type | Attrib |\n", 0); + kprint("------------------------------------------------------------\n", 0); + for (int i=0; i