...
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
global _start
|
global _start
|
||||||
extern c_start
|
|
||||||
|
|
||||||
%define MAGIC 0xe85250d6
|
%define MAGIC 0xe85250d6
|
||||||
%define ARCH 0x0
|
%define ARCH 0x0
|
||||||
@@ -19,6 +18,10 @@ header:
|
|||||||
dd 8
|
dd 8
|
||||||
.end:
|
.end:
|
||||||
|
|
||||||
|
section .data
|
||||||
|
align 8
|
||||||
|
multiboot_info: dd 0
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
align 4096
|
align 4096
|
||||||
stack:
|
stack:
|
||||||
@@ -26,13 +29,85 @@ stack:
|
|||||||
resb 1024 * 16
|
resb 1024 * 16
|
||||||
.top:
|
.top:
|
||||||
|
|
||||||
|
align 4096
|
||||||
|
pml4t: resb 4096
|
||||||
|
pdpt: resb 4096
|
||||||
|
pdt: resb 4096
|
||||||
|
pt: resb 4096
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
_start:
|
_start:
|
||||||
mov esp, stack.top
|
mov esp, stack.top
|
||||||
push ebx
|
|
||||||
push eax
|
%define BOOTLOADER_MAGIC 0x36d76289
|
||||||
call c_start
|
|
||||||
add esp, 8
|
; Make sure we booted with multiboot 2
|
||||||
|
cmp eax, BOOTLOADER_MAGIC
|
||||||
|
jne .halt
|
||||||
|
|
||||||
|
; Save pointer to info gathered by multiboot
|
||||||
|
mov [multiboot_info], ebx
|
||||||
|
|
||||||
|
; Tell the cpu where the pages area
|
||||||
|
mov edi, pml4t
|
||||||
|
mov cr3, edi
|
||||||
|
|
||||||
|
%define PT_PRESENT 1
|
||||||
|
%define PT_READABLE 2
|
||||||
|
|
||||||
|
; pml4t[0] -> pdpt
|
||||||
|
mov edi, pdpt
|
||||||
|
or edi, PT_PRESENT | PT_READABLE
|
||||||
|
mov [pml4t], edi
|
||||||
|
|
||||||
|
; pdpt[0] -> pdt
|
||||||
|
mov edi, pdt
|
||||||
|
or edi, PT_PRESENT | PT_READABLE
|
||||||
|
mov [pdpt], edi
|
||||||
|
|
||||||
|
; pdt[0] -> pt
|
||||||
|
mov edi, pt
|
||||||
|
or edi, PT_PRESENT | PT_READABLE
|
||||||
|
mov [pdt], edi
|
||||||
|
|
||||||
|
%define ENTRIES_PER_PT 512
|
||||||
|
%define SIZEOF_PT_ENTRY 8
|
||||||
|
%define PAGE_SIZE 0x1000
|
||||||
|
%define START_ADDRESS 0x0
|
||||||
|
|
||||||
|
; Identity map first 2mb of memory
|
||||||
|
mov edi, pt
|
||||||
|
mov ebx, START_ADDRESS | PT_PRESENT | PT_READABLE
|
||||||
|
mov ecx, ENTRIES_PER_PT
|
||||||
|
|
||||||
|
.set_pt_entry:
|
||||||
|
mov [edi], ebx
|
||||||
|
add ebx, PAGE_SIZE
|
||||||
|
add edi, SIZEOF_PT_ENTRY
|
||||||
|
loop .set_pt_entry
|
||||||
|
|
||||||
|
%define CR4_PAE_ENABLE 1 << 5
|
||||||
|
|
||||||
|
; Enable pae
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, CR4_PAE_ENABLE
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
%define EFER_MSR 0xc0000080
|
||||||
|
%define EFER_LM_ENABLE 1 << 8
|
||||||
|
|
||||||
|
; Switch to compatibility mode
|
||||||
|
mov ecx, EFER_MSR
|
||||||
|
rdmsr
|
||||||
|
or eax, EFER_LM_ENABLE
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
%define CR0_PG_ENABLE 1 << 31
|
||||||
|
|
||||||
|
; Enable paging
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, CR0_PG_ENABLE
|
||||||
|
mov cr0, eax
|
||||||
.halt:
|
.halt:
|
||||||
cli
|
cli
|
||||||
hlt
|
hlt
|
||||||
|
|||||||
60
src/boot/mem.c
Normal file
60
src/boot/mem.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#include <def.h>
|
||||||
|
#include "console.h"
|
||||||
|
#include "multiboot2.h"
|
||||||
|
#include "panic.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static void *multiboot_find_tag(uptr multiboot_info, u32 type) {
|
||||||
|
uptr next = multiboot_info + 8;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
multiboot_tag *tag = (multiboot_tag*)next;
|
||||||
|
|
||||||
|
if (tag->type == MULTIBOOT_TAG_TYPE_END) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag->type == type) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = align(next + tag->size, MULTIBOOT_TAG_ALIGN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_REGIONS 64
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 base_address;
|
||||||
|
u64 length;
|
||||||
|
} region;
|
||||||
|
|
||||||
|
extern uptr kernel_start;
|
||||||
|
extern uptr kernel_end;
|
||||||
|
|
||||||
|
static region regions[MAX_REGIONS] = {0};
|
||||||
|
static size_t region_count = 0;
|
||||||
|
|
||||||
|
static void find_memory_regions(uptr multiboot_info) {
|
||||||
|
multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP);
|
||||||
|
if (tag == NULL) {
|
||||||
|
boot_panic("Multiboot did not provide mmap tag");
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 entry_count = (tag->size - 16) / tag->entry_size;
|
||||||
|
u8 *entry_ptr = (u8*)tag->entries;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < entry_count; ++i) {
|
||||||
|
multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr;
|
||||||
|
|
||||||
|
if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) {
|
||||||
|
if (region_count >= MAX_REGIONS) {
|
||||||
|
boot_panic("Too many memory regions");
|
||||||
|
}
|
||||||
|
|
||||||
|
regions[region_count++] = (region){ entry->base_address, entry->length };
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_ptr += tag->entry_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,73 +2,7 @@
|
|||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "multiboot2.h"
|
#include "multiboot2.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
static void *multiboot_find_tag(uptr multiboot_info, u32 type) {
|
void c_start() {
|
||||||
uptr next = multiboot_info + 8;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
multiboot_tag *tag = (multiboot_tag*)next;
|
|
||||||
|
|
||||||
if (tag->type == MULTIBOOT_TAG_TYPE_END) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag->type == type) {
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
next = align(next + tag->size, MULTIBOOT_TAG_ALIGN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_REGIONS 64
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u64 base_address;
|
|
||||||
u64 length;
|
|
||||||
} region;
|
|
||||||
|
|
||||||
extern uptr kernel_start;
|
|
||||||
extern uptr kernel_end;
|
|
||||||
|
|
||||||
static region regions[MAX_REGIONS] = {0};
|
|
||||||
static size_t region_count = 0;
|
|
||||||
|
|
||||||
static void find_memory_regions(uptr multiboot_info) {
|
|
||||||
multiboot_tag_mmap *tag = multiboot_find_tag(multiboot_info, MULTIBOOT_TAG_TYPE_MMAP);
|
|
||||||
if (tag == NULL) {
|
|
||||||
boot_panic("Multiboot did not provide mmap tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 entry_count = (tag->size - 16) / tag->entry_size;
|
|
||||||
u8 *entry_ptr = (u8*)tag->entries;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < entry_count; ++i) {
|
|
||||||
multiboot_mmap_entry *entry = (multiboot_mmap_entry*)entry_ptr;
|
|
||||||
|
|
||||||
if (entry->type == MULTIBOOT_MEMORY_AVAILABLE) {
|
|
||||||
if (region_count >= MAX_REGIONS) {
|
|
||||||
boot_panic("Too many memory regions");
|
|
||||||
}
|
|
||||||
|
|
||||||
regions[region_count++] = (region){ entry->base_address, entry->length };
|
|
||||||
}
|
|
||||||
|
|
||||||
entry_ptr += tag->entry_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_start(u32 magic, uptr multiboot_info) {
|
|
||||||
console_clear();
|
console_clear();
|
||||||
|
|
||||||
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
|
||||||
boot_panic("Expected bootloader magic 0x%x, got 0x%x", MULTIBOOT_BOOTLOADER_MAGIC, magic);
|
|
||||||
}
|
|
||||||
|
|
||||||
find_memory_regions(multiboot_info);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < region_count; i++) {
|
|
||||||
kprintf("Memory region %d: base=0x%X, length=0x%X\n", i, regions[i].base_address, regions[i].length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user