This commit is contained in:
nub31
2025-12-30 22:25:51 +01:00
parent 87c79f50be
commit d15609e5c0
3 changed files with 55 additions and 24 deletions

View File

@@ -21,7 +21,7 @@ static void *multiboot_find_tag(uptr multiboot_info, u32 type) {
return tag; return tag;
} }
next = align(next + tag->size, MULTIBOOT_TAG_ALIGN); next = align_up(next + tag->size, MULTIBOOT_TAG_ALIGN);
} }
} }
@@ -30,13 +30,13 @@ static void *multiboot_find_tag(uptr multiboot_info, u32 type) {
typedef struct { typedef struct {
u64 base_address; u64 base_address;
u64 length; u64 length;
} region; } memory_region;
extern uptr kernel_start; extern uptr kernel_start;
extern uptr kernel_end; extern uptr kernel_end;
static region regions[MAX_REGIONS] = {0}; static memory_region memory_regions[MAX_REGIONS] = {0};
static size_t region_count = 0; static size_t memory_region_count = 0;
static void find_memory_regions(uptr multiboot_info) { static void find_memory_regions(uptr multiboot_info) {
multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP); multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP);
@@ -51,17 +51,23 @@ static void find_memory_regions(uptr multiboot_info) {
multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr; multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr;
if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) { if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) {
if (region_count >= MAX_REGIONS) { if (memory_region_count >= MAX_REGIONS) {
boot_panic("Too many memory regions"); boot_panic("Too many memory regions");
} }
regions[region_count++] = (region){ entry->base_address, entry->length }; memory_regions[memory_region_count++] = (memory_region){ entry->base_address, entry->length };
} }
entry_ptr += tag->entry_size; entry_ptr += tag->entry_size;
} }
} }
void kmain(uptr multiboot_info) { // We are now in long mode with kernel pages and vga buffer identity mapped
void x86_64_main(uptr multiboot_info) {
console_clear();
find_memory_regions(multiboot_info); find_memory_regions(multiboot_info);
for (u32 i = 0; i < memory_region_count; ++i) {
kprintf("region: base_address=0x%X, length=0x%X\n", memory_regions[i].base_address, memory_regions[i].length);
}
} }

View File

@@ -1,7 +1,7 @@
global _start global _start
extern kernel_start extern kernel_start
extern kernel_end extern kernel_end
extern kmain extern x86_64_main
%define MAGIC 0xe85250d6 %define MAGIC 0xe85250d6
%define ARCH 0x0 %define ARCH 0x0
@@ -21,10 +21,6 @@ header:
dd 8 dd 8
.end: .end:
section .data
align 8
multiboot_info: dq 0
%define PRESENT 1 << 7 %define PRESENT 1 << 7
%define NOT_SYS 1 << 4 %define NOT_SYS 1 << 4
%define EXEC 1 << 3 %define EXEC 1 << 3
@@ -58,6 +54,11 @@ gdt:
dq gdt dq gdt
section .bss section .bss
%define MULTIBOOT_INFO_MAX_SIZE 1024 * 64
align 8
multiboot_info: resb MULTIBOOT_INFO_MAX_SIZE
align 16 align 16
stack: stack:
.bottom: .bottom:
@@ -79,29 +80,38 @@ _start:
cmp eax, BOOTLOADER_MAGIC cmp eax, BOOTLOADER_MAGIC
jne .halt jne .halt
; Save pointer to info gathered by multiboot ; Copy multiboot structure to kernel owned memory
mov [multiboot_info], ebx mov esi, ebx
mov eax, [esi]
cmp eax, MULTIBOOT_INFO_MAX_SIZE
ja .halt
mov edi, multiboot_info
mov ecx, eax
cld
rep movsb
; Tell the cpu where the pages area ; Tell the cpu where the pages area
mov edi, pml4t mov edi, pml4t
mov cr3, edi mov cr3, edi
%define PT_PRESENT 1 %define PT_PRESENT 1
%define PT_READABLE 2 %define PT_RW 2
; pml4t[0] -> pdpt ; pml4t[0] -> pdpt
mov edi, pdpt mov edi, pdpt
or edi, PT_PRESENT | PT_READABLE or edi, PT_PRESENT | PT_RW
mov [pml4t], edi mov [pml4t], edi
; pdpt[0] -> pdt ; pdpt[0] -> pdt
mov edi, pdt mov edi, pdt
or edi, PT_PRESENT | PT_READABLE or edi, PT_PRESENT | PT_RW
mov [pdpt], edi mov [pdpt], edi
; pdt[0] -> pt ; pdt[0] -> pt
mov edi, pt mov edi, pt
or edi, PT_PRESENT | PT_READABLE or edi, PT_PRESENT | PT_RW
mov [pdt], edi mov [pdt], edi
%define ENTRIES_PER_PT 512 %define ENTRIES_PER_PT 512
@@ -113,7 +123,7 @@ _start:
mov edi, pt mov edi, pt
mov ebx, kernel_start mov ebx, kernel_start
and ebx, 0xfffff000 and ebx, 0xfffff000
or ebx, PT_PRESENT | PT_READABLE or ebx, PT_PRESENT | PT_RW
mov eax, kernel_end mov eax, kernel_end
sub eax, kernel_start sub eax, kernel_start
@@ -127,6 +137,17 @@ _start:
add edi, SIZEOF_PT_ENTRY add edi, SIZEOF_PT_ENTRY
loop .set_pt_entry loop .set_pt_entry
; note(nub31): Vga buffer is already page aligned
%define VGA_BUFFER 0xb8000
; Identity map vga buffer
mov ebx, VGA_BUFFER
or ebx, PT_PRESENT | PT_RW
mov edi, pt
add edi, VGA_BUFFER / PAGE_SIZE * SIZEOF_PT_ENTRY
mov [edi], ebx
%define CR4_PAE_ENABLE 1 << 5 %define CR4_PAE_ENABLE 1 << 5
; Enable pae ; Enable pae
@@ -169,8 +190,8 @@ start64:
mov ss, ax mov ss, ax
mov rsp, stack.top mov rsp, stack.top
mov rdi, [multiboot_info] mov rdi, multiboot_info
call kmain call x86_64_main
.halt: .halt:
cli cli
hlt hlt

View File

@@ -1,7 +1,11 @@
#pragma once #pragma once
static inline u32 align(u32 num, u32 alignment) { static inline uptr align_up(uptr value, uptr alignment) {
return (num + alignment - 1) & ~(alignment - 1); return (value + alignment - 1) / alignment * alignment;
}
static inline uptr align_down(uptr value, uptr alignment) {
return value - (value % alignment);
} }
static inline void hlt() { static inline void hlt() {