mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-10 02:42:08 +00:00
memory works
This commit is contained in:
parent
175e5b55b8
commit
e71a141533
10 changed files with 132 additions and 96 deletions
2
Makefile
2
Makefile
|
@ -47,4 +47,4 @@ $(BUILD_DIR)/$(ISO_NAME): $(BUILD_DIR)/$(K_BIN_NAME) grub.cfg
|
||||||
grub-mkrescue -o $(BUILD_DIR)/$(ISO_NAME) $(BUILD_DIR)/iso
|
grub-mkrescue -o $(BUILD_DIR)/$(ISO_NAME) $(BUILD_DIR)/iso
|
||||||
|
|
||||||
run: all
|
run: all
|
||||||
qemu-system-x86_64 $(BUILD_DIR)/$(ISO_NAME) -serial stdio
|
qemu-system-x86_64 $(BUILD_DIR)/$(ISO_NAME) -serial stdio -m 4G
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
global start
|
global start
|
||||||
global pml4_list
|
global kernel_pml4
|
||||||
global init_pdpt
|
global kernel_pdpt_0
|
||||||
global init_pd
|
global kernel_pd_0
|
||||||
global init_pt
|
global kernel_pt_0
|
||||||
global paging_pt
|
global paging_pt
|
||||||
|
global bootstrap_pt
|
||||||
extern kmain
|
extern kmain
|
||||||
extern amd64_shim
|
extern amd64_shim
|
||||||
bits 32
|
bits 32
|
||||||
|
@ -25,15 +26,17 @@ mb_end:
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
align 4096
|
align 4096
|
||||||
pml4_list: ; reserve memory for initial 512 pml4 entires
|
kernel_pml4: ; reserve memory for initial 512 pml4 entires
|
||||||
resb 4096
|
resb 4096
|
||||||
init_pdpt: ; reserve memory for initial 512 pdpt entires
|
kernel_pdpt_0: ; reserve memory for initial 512 pdpt entires
|
||||||
resb 4096
|
resb 4096
|
||||||
init_pd: ; reserve memory for initial 512 pd entries
|
kernel_pd_0: ; reserve memory for initial 512 pd entries
|
||||||
resb 4096
|
resb 4096
|
||||||
init_pt: ; reserve memory for initial 512 pt entries
|
kernel_pt_0: ; reserve memory for initial 512 pt entries
|
||||||
resb 4096
|
resb 4096
|
||||||
paging_pt: ; reserve memory for 512 paging reserved pt entires
|
paging_pt: ; reserve pages for pager mappings
|
||||||
|
resb 4096
|
||||||
|
bootstrap_pt: ; reserve pages to bootstrap pager
|
||||||
resb 4096
|
resb 4096
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
|
@ -85,6 +88,7 @@ start:
|
||||||
mov esp, stack_end
|
mov esp, stack_end
|
||||||
mov ebp, stack_end
|
mov ebp, stack_end
|
||||||
|
|
||||||
|
push DWORD 0
|
||||||
push ebx
|
push ebx
|
||||||
|
|
||||||
mov edi, 0x1000
|
mov edi, 0x1000
|
||||||
|
@ -93,13 +97,13 @@ start:
|
||||||
mov ecx, 4096
|
mov ecx, 4096
|
||||||
rep stosd
|
rep stosd
|
||||||
mov edi, cr3
|
mov edi, cr3
|
||||||
; FIXME: Update boot.S to point base of paging to pml4e_list, see above
|
|
||||||
mov DWORD [edi], 0x2003 ; Set the uint32_t at the destination index to 0x2003.
|
mov DWORD [edi], kernel_pdpt_0 + 3 ; Set the uint32_t at the destination index to 0x2003.
|
||||||
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
mov edi, kernel_pdpt_0 ; Add 0x1000 to the destination index.
|
||||||
mov DWORD [edi], 0x3003 ; Set the uint32_t at the destination index to 0x3003.
|
mov DWORD [edi], kernel_pd_0 + 3 ; Set the uint32_t at the destination index to 0x3003.
|
||||||
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
mov edi, kernel_pd_0 ; Add 0x1000 to the destination index.
|
||||||
mov DWORD [edi], 0x4003 ; Set the uint32_t at the destination index to 0x4003.
|
mov DWORD [edi], kernel_pt_0 + 3 ; Set the uint32_t at the destination index to 0x4003.
|
||||||
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
mov edi, kernel_pt_0 ; Add 0x1000 to the destination index.
|
||||||
|
|
||||||
mov ebx, 0x00000003 ; Set the B-register to 0x00000003.
|
mov ebx, 0x00000003 ; Set the B-register to 0x00000003.
|
||||||
mov ecx, 512 ; Set the C-register to 512.
|
mov ecx, 512 ; Set the C-register to 512.
|
||||||
|
@ -132,6 +136,7 @@ start:
|
||||||
|
|
||||||
bits 64
|
bits 64
|
||||||
code64:
|
code64:
|
||||||
|
pop rdi
|
||||||
call amd64_shim
|
call amd64_shim
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
call kmain
|
call kmain
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
#include "mboot.h"
|
#include "mboot.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
|
||||||
static void read_cmdline(struct mboot_info *info, struct mboot_tag *tag, char *data, uint8_t len) {
|
static void read_cmdline(struct mboot_tag *tag, char *data, uint8_t len) {
|
||||||
if (len >= CMDLINE_MAX)
|
if (len >= CMDLINE_MAX)
|
||||||
len = CMDLINE_MAX; // truncate :(
|
len = CMDLINE_MAX; // truncate :(
|
||||||
memcpy(tag->data.cmdline, data, len);
|
memcpy(tag->data.cmdline, data, len);
|
||||||
tag->data.cmdline[len] = '\0';
|
tag->data.cmdline[len] = '\0';
|
||||||
info->tags[MBOOT_CMDLINE] = *tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_xsdp(struct mboot_info *info, struct mboot_tag *tag, char *data) {
|
static void read_memorymap(struct mboot_tag *tag, uint64_t size, uint32_t *data) {
|
||||||
|
tag->data.memory_map = (struct memory_map *) data;
|
||||||
|
tag->data.memory_map->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_xsdp(struct mboot_tag *tag, char *data) {
|
||||||
tag->data.rootsdp = (void *) data;
|
tag->data.rootsdp = (void *) data;
|
||||||
info->tags[MBOOT_XSDP] = *tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t *read_tag(struct mboot_info *info, uint32_t *data) {
|
static uint32_t *read_tag(struct mboot_info *info, uint32_t *data) {
|
||||||
struct mboot_tag tag;
|
struct mboot_tag tag;
|
||||||
tag.type = ((uint16_t*)data)[0];
|
tag.type = *((uint16_t *)data);
|
||||||
tag.size = data[1];
|
tag.size = data[1];
|
||||||
tag.valid = 1;
|
tag.valid = 1;
|
||||||
|
|
||||||
|
@ -26,15 +30,20 @@ static uint32_t *read_tag(struct mboot_info *info, uint32_t *data) {
|
||||||
|
|
||||||
switch (tag.type) {
|
switch (tag.type) {
|
||||||
case MBOOT_CMDLINE:
|
case MBOOT_CMDLINE:
|
||||||
read_cmdline(info, &tag, (char *)(data + 2), data_len);
|
read_cmdline(&tag, (char *)(data + 2), data_len);
|
||||||
|
break;
|
||||||
|
case MBOOT_MEMORYMAP:
|
||||||
|
read_memorymap(&tag, tag.size, data + 2);
|
||||||
break;
|
break;
|
||||||
case MBOOT_XSDP:
|
case MBOOT_XSDP:
|
||||||
read_xsdp(info, &tag, (char *) (data + 2));
|
read_xsdp(&tag, (char *) (data + 2));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info->tags[tag.type] = tag;
|
||||||
|
|
||||||
if(tag.size % 8 != 0) {
|
if(tag.size % 8 != 0) {
|
||||||
tag.size += 8 - (tag.size % 8);
|
tag.size += 8 - (tag.size % 8);
|
||||||
}
|
}
|
||||||
|
@ -42,13 +51,14 @@ static uint32_t *read_tag(struct mboot_info *info, uint32_t *data) {
|
||||||
return data + tag.size / sizeof(uint32_t);
|
return data + tag.size / sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mboot_info mboot_load_info(void *mboot_info) {
|
struct mboot_info mboot_load_info(const void *mboot_info) {
|
||||||
struct mboot_info info = {0};
|
struct mboot_info info = {0};
|
||||||
|
|
||||||
uint32_t* data = (uint32_t*) mboot_info;
|
uint32_t* data = (uint32_t*) mboot_info;
|
||||||
info.total_size = *data++;
|
info.total_size = *data++;
|
||||||
info.reserved = *data++;
|
info.reserved = *data++;
|
||||||
|
|
||||||
|
|
||||||
while((uint8_t*) data < (uint8_t*) mboot_info + info.total_size) {
|
while((uint8_t*) data < (uint8_t*) mboot_info + info.total_size) {
|
||||||
data = read_tag(&info, data);
|
data = read_tag(&info, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,14 @@ enum mboot_tag_type {
|
||||||
struct mboot_info {
|
struct mboot_info {
|
||||||
uint32_t total_size;
|
uint32_t total_size;
|
||||||
uint32_t reserved;
|
uint32_t reserved;
|
||||||
struct mboot_tag tags[21];
|
struct mboot_tag tags[22];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the multi boot information
|
* Loads the multi boot information
|
||||||
* @param mboot_info - the pointer passed from multiboot2
|
* @param mboot_info - the pointer passed from multiboot2
|
||||||
*/
|
*/
|
||||||
struct mboot_info mboot_load_info(void *mboot_info);
|
struct mboot_info mboot_load_info(const void *mboot_info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a tag from multiboot
|
* Gets a tag from multiboot
|
||||||
|
|
|
@ -7,18 +7,9 @@
|
||||||
#include <memory/physalloc.h>
|
#include <memory/physalloc.h>
|
||||||
#include <memory/virtalloc.h>
|
#include <memory/virtalloc.h>
|
||||||
|
|
||||||
|
#include "paging.h"
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
|
|
||||||
#define F_PRESENT 0x001
|
|
||||||
#define F_WRITEABLE 0x002
|
|
||||||
#define F_UNPRIVILEGED 0x004
|
|
||||||
#define F_WRITETHROUGH 0x008
|
|
||||||
#define F_CACHEDISABLE 0x010
|
|
||||||
#define F_ACCESSED 0x020
|
|
||||||
#define F_DIRTY 0x040
|
|
||||||
#define F_MEGABYTE 0x080
|
|
||||||
#define F_GLOBAL 0x100
|
|
||||||
|
|
||||||
// PAGE MAP LEVEL 4 ENTRY
|
// PAGE MAP LEVEL 4 ENTRY
|
||||||
struct pml4e {
|
struct pml4e {
|
||||||
uint64_t flags : 6;
|
uint64_t flags : 6;
|
||||||
|
@ -61,19 +52,19 @@ struct pte {
|
||||||
};
|
};
|
||||||
|
|
||||||
// bss segment, can write to
|
// bss segment, can write to
|
||||||
extern struct pml4e pml4_list[512];
|
extern struct pml4e kernel_pml4[512];
|
||||||
extern struct pdpte init_pdpt[512];
|
extern struct pdpte kernel_pdpt_0[512];
|
||||||
extern struct pde init_pd[512];
|
extern struct pde kernel_pd_0[512];
|
||||||
extern struct pte init_pt[512];
|
extern struct pte bootstrap_pt[512];
|
||||||
extern struct pte paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say
|
extern struct pte paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say
|
||||||
|
|
||||||
// paged address to read page tables
|
// paged address to read page tables
|
||||||
// the structures are not gurenteed to be ident mapped
|
// the structures are not gurenteed to be ident mapped
|
||||||
// map them here with map_<type>(phys_addr) before useing structures
|
// map them here with map_<type>(phys_addr) before useing structures
|
||||||
static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x1000;
|
static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000;
|
||||||
static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x2000;
|
static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x202000;
|
||||||
static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x3000;
|
static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x203000;
|
||||||
void *addr_mapped = (void *) (uintptr_t) 0x4000;
|
void *addr_mapped = (void *) (uintptr_t) 0x204000;
|
||||||
|
|
||||||
static inline void invlpg(void *addr) {
|
static inline void invlpg(void *addr) {
|
||||||
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
__asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||||
|
@ -172,6 +163,7 @@ int map_page(struct pml4e *pml4, void *virt_addr, void *phys_addr, unsigned int
|
||||||
map_pt(__pt);
|
map_pt(__pt);
|
||||||
pt_mapped[pt_offset].flags = F_PRESENT | flags;
|
pt_mapped[pt_offset].flags = F_PRESENT | flags;
|
||||||
pt_mapped[pt_offset].address = (((uint64_t)phys_addr) >> 12);
|
pt_mapped[pt_offset].address = (((uint64_t)phys_addr) >> 12);
|
||||||
|
|
||||||
invlpg(virt_addr);
|
invlpg(virt_addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -236,51 +228,52 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
void paging_init(void) {
|
void paging_init(void) {
|
||||||
memset(pml4_list, 0, 4096);
|
|
||||||
pml4_list[0].flags = F_PRESENT | F_WRITEABLE;
|
|
||||||
pml4_list[0].address = (uint64_t)init_pdpt >> 12;
|
|
||||||
|
|
||||||
memset(init_pdpt, 0, 4096);
|
kernel_pml4[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
init_pdpt[0].flags = F_PRESENT | F_WRITEABLE;
|
kernel_pml4[0].address = (uint64_t)(&kernel_pdpt_0) >> 12;
|
||||||
init_pdpt[0].address = (uint64_t)init_pd >> 12;
|
|
||||||
|
|
||||||
memset(pml4_list, 0, 4096);
|
kernel_pdpt_0[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
init_pd[0].flags = F_PRESENT | F_WRITEABLE;
|
kernel_pdpt_0[0].address = (uint64_t)(&kernel_pd_0) >> 12;
|
||||||
init_pd[0].address = (uint64_t)paging_pt >> 12;
|
|
||||||
init_pd[1].flags = F_PRESENT | F_WRITEABLE;
|
|
||||||
init_pd[1].address = (uint64_t)init_pt >> 12;
|
|
||||||
|
|
||||||
memset(init_pt, 0, 4096);
|
kernel_pd_0[1].flags = F_PRESENT | F_WRITEABLE;
|
||||||
memset(paging_pt, 0, 4096);
|
kernel_pd_0[1].address = (uint64_t)(&paging_pt) >> 12;
|
||||||
|
kernel_pd_0[2].flags = F_PRESENT | F_WRITEABLE;
|
||||||
|
kernel_pd_0[2].address = (uint64_t)(&bootstrap_pt) >> 12;
|
||||||
|
|
||||||
|
memset(&paging_pt, 0, 4096);
|
||||||
|
memset(&bootstrap_pt, 0, 4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *page_align(void *addr) {
|
static inline void *page_align(void *addr) {
|
||||||
uintptr_t a = (uintptr_t) addr;
|
uintptr_t a = (uintptr_t) addr;
|
||||||
a += PAGE_SIZE + 1;
|
a += PAGE_SIZE - 1;
|
||||||
a /= PAGE_SIZE;
|
a /= PAGE_SIZE;
|
||||||
|
a *= PAGE_SIZE;
|
||||||
return (void *) a;
|
return (void *) a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *mmap(void *addr, size_t len) {
|
void *mmap(void *addr, size_t len) {
|
||||||
len += (uintptr_t)addr % PAGE_SIZE;
|
len += (long)addr % PAGE_SIZE;
|
||||||
int pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
|
long pages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
void *virt = virtaddr_alloc(pages);
|
void *virt = virtaddr_alloc(pages);
|
||||||
if (virt == NULL)
|
if (virt == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
void *phys = page_align(addr);
|
void *phys = page_align(addr);
|
||||||
for (long i = 0; i < pages; i++) {
|
for (long i = 0; i < pages; i++) {
|
||||||
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
||||||
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
|
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
|
||||||
map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE);
|
map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE);
|
||||||
}
|
}
|
||||||
return addr;
|
map_page(kernel_pml4, virt, (void*)0x23443, F_WRITEABLE);
|
||||||
|
return virt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmap(void *addr) {
|
void unmap(void *addr) {
|
||||||
long pages = virtaddr_free(addr);
|
long pages = virtaddr_free(addr);
|
||||||
for (long i = 0; i < pages; i++) {
|
for (long i = 0; i < pages; i++) {
|
||||||
void *virt = (char *)addr + (i * PAGE_SIZE);
|
void *virt = (char *)addr + (i * PAGE_SIZE);
|
||||||
unmap_page(pml4_list, virt);
|
unmap_page(kernel_pml4, virt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +289,7 @@ void *alloc_pages(int count) {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
||||||
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
|
void *phys_temp = (char *)phys + (i * PAGE_SIZE);
|
||||||
map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE);
|
map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE);
|
||||||
}
|
}
|
||||||
return virt;
|
return virt;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +300,7 @@ void free_page(void *virt) {
|
||||||
return;
|
return;
|
||||||
for (long i = 0; i < pages; i++) {
|
for (long i = 0; i < pages; i++) {
|
||||||
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
void *virt_temp = (char *)virt + (i * PAGE_SIZE);
|
||||||
unmap_page(pml4_list, virt_temp);
|
unmap_page(kernel_pml4, virt_temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,3 +311,11 @@ void memory_lock(void) {
|
||||||
void memory_unlock(void) {
|
void memory_unlock(void) {
|
||||||
sti();
|
sti();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags) {
|
||||||
|
return map_page(kernel_pml4, virt_addr, phys_addr, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kunmap_page(void *virt_addr) {
|
||||||
|
return unmap_page(kernel_pml4, virt_addr);
|
||||||
|
}
|
||||||
|
|
16
src/arch/amd64/paging.h
Normal file
16
src/arch/amd64/paging.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define F_PRESENT 0x001
|
||||||
|
#define F_WRITEABLE 0x002
|
||||||
|
#define F_UNPRIVILEGED 0x004
|
||||||
|
#define F_WRITETHROUGH 0x008
|
||||||
|
#define F_CACHEDISABLE 0x010
|
||||||
|
#define F_ACCESSED 0x020
|
||||||
|
#define F_DIRTY 0x040
|
||||||
|
#define F_MEGABYTE 0x080
|
||||||
|
#define F_GLOBAL 0x100
|
||||||
|
|
||||||
|
int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags);
|
||||||
|
int kunmap_page(void *virt_addr);
|
||||||
|
|
||||||
|
void paging_init(void);
|
|
@ -4,23 +4,17 @@
|
||||||
#include <shim.h>
|
#include <shim.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
#include "paging.h"
|
||||||
#include "mboot.h"
|
#include "mboot.h"
|
||||||
|
|
||||||
static struct boot_info boot_info;
|
static struct boot_info boot_info;
|
||||||
|
|
||||||
// entry point for amd64
|
// entry point for amd64
|
||||||
void* amd64_shim(void *mboot_data_ptr) {
|
void* amd64_shim(void *mboot_data_ptr) {
|
||||||
//struct pml4e *pml4 = (struct pml4e *)0x1000;
|
serial_init();
|
||||||
//struct pdpte *pdpt = (struct pdpte *)0x2000;
|
paging_init();
|
||||||
//struct pde *pd = (struct pde *)0x3000;
|
|
||||||
//struct pte *pt = (struct pte *)0x4000;
|
kmap_page(mboot_data_ptr, mboot_data_ptr, F_WRITEABLE);
|
||||||
//pd[1].flags = F_PRESENT | F_WRITEABLE;
|
|
||||||
//pd[1].address = ((uint64_t)pt) >> 12;
|
|
||||||
//map_page(pml4, (void *)0x80000000, (void *)0xB8002, F_WRITEABLE);
|
|
||||||
//__asm("invlpg 0x200000");
|
|
||||||
//void *ret;
|
|
||||||
//find_phys_addr(pml4, (void *)0x80000000, &ret);
|
|
||||||
//return ret;
|
|
||||||
|
|
||||||
struct mboot_info mboot_info;
|
struct mboot_info mboot_info;
|
||||||
mboot_info = mboot_load_info(mboot_data_ptr);
|
mboot_info = mboot_load_info(mboot_data_ptr);
|
||||||
|
|
|
@ -10,6 +10,7 @@ void kmain(struct boot_info *info) {
|
||||||
memory_init(info->map);
|
memory_init(info->map);
|
||||||
//*(char*)(0xB8002 + 0x20'0000) = 'd';
|
//*(char*)(0xB8002 + 0x20'0000) = 'd';
|
||||||
itoa((long)info, buf, 16);
|
itoa((long)info, buf, 16);
|
||||||
|
itoa(*(long*)info, buf, 16);
|
||||||
//fb_init(1024, 768);
|
//fb_init(1024, 768);
|
||||||
serial_out_str(buf);
|
serial_out_str(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include <memory/physalloc.h>
|
#include <memory/physalloc.h>
|
||||||
#include <memory/virtalloc.h>
|
#include <memory/virtalloc.h>
|
||||||
|
|
||||||
extern uintptr_t kernel_start;
|
extern char kernel_start;
|
||||||
extern uintptr_t kernel_end;
|
extern char kernel_end;
|
||||||
|
#define kaddr(addr) ((uintptr_t)(&addr))
|
||||||
|
|
||||||
// between memory_start and kernel_start will be the bitmap
|
// between memory_start and kernel_start will be the bitmap
|
||||||
static uintptr_t memory_start = 0;
|
static uintptr_t memory_start = 0;
|
||||||
|
@ -113,9 +114,9 @@ void free_phys_pages(void *ptr, int pages) {
|
||||||
|
|
||||||
static bool segment_invalid(const struct memory_segment *segment) {
|
static bool segment_invalid(const struct memory_segment *segment) {
|
||||||
if (segment->type != 1) return false;
|
if (segment->type != 1) return false;
|
||||||
if (segment->addr < kernel_start) return false;
|
if (segment->addr < kaddr(kernel_start)) return false;
|
||||||
if (segment->addr + segment->len < memory_start) return false;
|
if (segment->addr + segment->len < memory_start) return false;
|
||||||
if (segment->addr + segment->len < kernel_start) return false;
|
if (segment->addr + segment->len < kaddr(kernel_start)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ static struct memory_area segment_to_area(const struct memory_segment *segment)
|
||||||
if (memory_start)
|
if (memory_start)
|
||||||
start = memory_start;
|
start = memory_start;
|
||||||
else
|
else
|
||||||
start = kernel_end;
|
start = kaddr(kernel_end);
|
||||||
|
|
||||||
if (segment->addr < start) {
|
if (segment->addr < start) {
|
||||||
addr = start;
|
addr = start;
|
||||||
|
@ -144,7 +145,7 @@ static struct memory_area segment_to_area(const struct memory_segment *segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t page_align(uintptr_t ptr) {
|
static uintptr_t page_align(uintptr_t ptr) {
|
||||||
return ptr + PAGE_SIZE - 1 / PAGE_SIZE;
|
return (ptr + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_init(struct memory_map *map) {
|
void memory_init(struct memory_map *map) {
|
||||||
|
@ -180,15 +181,17 @@ void memory_init(struct memory_map *map) {
|
||||||
|
|
||||||
//HACK: terrible hack bad bad bad bad
|
//HACK: terrible hack bad bad bad bad
|
||||||
long bitmap_size = bitmap_pages * PAGE_SIZE;
|
long bitmap_size = bitmap_pages * PAGE_SIZE;
|
||||||
bitmap = (uint64_t *) page_at(page_count - bitmap_pages);
|
bitmap = (uint64_t *) page_align(kaddr(kernel_end));
|
||||||
|
char buf[20];
|
||||||
|
|
||||||
long page_area_size = segment_count * sizeof(struct memory_area);
|
long page_area_size = segment_count * sizeof(struct memory_area);
|
||||||
char *page_area_addr = (char *)bitmap + bitmap_size;
|
char *page_area_addr = (char *)bitmap + bitmap_size;
|
||||||
|
|
||||||
bitmap = mmap(bitmap, bitmap_size);
|
bitmap = mmap(bitmap, bitmap_size);
|
||||||
|
ltoa((long)bitmap, buf, 16);
|
||||||
|
memset(bitmap, 0, 12);
|
||||||
memset(bitmap, 0, bitmap_size);
|
memset(bitmap, 0, bitmap_size);
|
||||||
|
|
||||||
memory_start = page_align(kernel_end + bitmap_size + page_area_size);
|
memory_start = page_align(kaddr(kernel_end) + bitmap_size + page_area_size);
|
||||||
|
|
||||||
page_area_addr = mmap(page_area_addr, page_area_size);
|
page_area_addr = mmap(page_area_addr, page_area_size);
|
||||||
page_start = (struct memory_area *) page_area_addr;
|
page_start = (struct memory_area *) page_area_addr;
|
||||||
|
|
|
@ -26,7 +26,7 @@ static struct addr_node *alloc_node(void) {
|
||||||
} else {
|
} else {
|
||||||
struct addr_node *node = &nodes[bss_nodes];
|
struct addr_node *node = &nodes[bss_nodes];
|
||||||
bss_nodes += 1;
|
bss_nodes += 1;
|
||||||
node->is_bss = false;
|
node->is_bss = true;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -39,8 +39,8 @@ static void free_node(struct addr_node *node) {
|
||||||
|
|
||||||
void virtaddr_init(void) {
|
void virtaddr_init(void) {
|
||||||
struct addr_node init = {
|
struct addr_node init = {
|
||||||
.start = 0,
|
.start = 0x400000, // third page table
|
||||||
.end = UINT64_MAX,
|
.end = 0x1000000000000, // 48bit memory address max
|
||||||
.next = NULL,
|
.next = NULL,
|
||||||
.prev = NULL,
|
.prev = NULL,
|
||||||
.is_alloc = false,
|
.is_alloc = false,
|
||||||
|
@ -53,6 +53,10 @@ void virtaddr_init(void) {
|
||||||
|
|
||||||
void *virtaddr_alloc(int n_pages) {
|
void *virtaddr_alloc(int n_pages) {
|
||||||
|
|
||||||
|
|
||||||
|
if (n_pages < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
long n_length = n_pages * PAGE_SIZE;
|
long n_length = n_pages * PAGE_SIZE;
|
||||||
struct addr_node *node = start_node;
|
struct addr_node *node = start_node;
|
||||||
|
|
||||||
|
@ -64,17 +68,19 @@ void *virtaddr_alloc(int n_pages) {
|
||||||
long length = node->end - node->start;
|
long length = node->end - node->start;
|
||||||
if (length >= n_length) {
|
if (length >= n_length) {
|
||||||
struct addr_node *new = alloc_node();
|
struct addr_node *new = alloc_node();
|
||||||
if (node == NULL)
|
if (node == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
new->next = node;
|
}
|
||||||
node->prev = new;
|
|
||||||
if (node->prev != NULL) {
|
if (node->prev != NULL) {
|
||||||
node->prev->next = new;
|
node->prev->next = new;
|
||||||
}
|
}
|
||||||
|
new->next = node;
|
||||||
|
node->prev = new;
|
||||||
new->start = node->start;
|
new->start = node->start;
|
||||||
new->end = new->start + n_length;
|
new->end = new->start + n_length;
|
||||||
node->start = new->end;
|
node->start = new->end;
|
||||||
new->is_alloc = true;
|
new->is_alloc = true;
|
||||||
|
new->next = node;
|
||||||
return (void *) new->start;
|
return (void *) new->start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue