...
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user