Physical memory manager [In Progress]
This commit is contained in:
parent
a4411ce9a6
commit
58c61bae3c
|
@ -1,4 +1,6 @@
|
|||
extern kmain
|
||||
extern kernel_start
|
||||
extern kernel_end
|
||||
global BOCHS_MAGIC_BREAKPOINT
|
||||
global kernel_heap
|
||||
; IMPORTANT: This module should be 4k-page aliened
|
||||
|
|
|
@ -11,7 +11,6 @@ typedef struct
|
|||
{
|
||||
uint64_t base_addr;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
linked_list_node_t list_node;
|
||||
} memory_descriptor_node_t;
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ avl_tree_node_t * NATIVE64 _avl_tree_node_insert(avl_tree_node_t *root, avl_tree
|
|||
return _avl_tree_node_balance(root);
|
||||
}
|
||||
|
||||
void _swap_nodes(avl_tree_node_t *node1, avl_tree_node_t *node2)
|
||||
void _avl_tree_swap_nodes(avl_tree_node_t *node1, avl_tree_node_t *node2)
|
||||
{
|
||||
if (node1 == NULL || node2 == NULL)
|
||||
return;
|
||||
|
@ -271,7 +271,7 @@ avl_tree_node_t * NATIVE64 avl_tree_node_delete(avl_tree_node_t * root, avl_tree
|
|||
while(successor->left != NULL)
|
||||
successor = successor->left;
|
||||
//swap fields
|
||||
_swap_nodes(successor,root);
|
||||
_avl_tree_swap_nodes(successor, root);
|
||||
|
||||
// Detach the inorder successor
|
||||
successor->right = avl_tree_node_delete(successor->right, root, compare);
|
||||
|
|
|
@ -31,19 +31,19 @@ boot_info_t* NATIVE64 hal_init(multiboot_info_t* m_info)
|
|||
hal_flush_idt(&g_idt_ptr);
|
||||
|
||||
boot_info_t* boot_info = (boot_info_t*)hal_halloc(sizeof(boot_info_t));
|
||||
BOCHS_MAGIC_BREAKPOINT();
|
||||
hal_assert(boot_info != NULL, "Unable to allocate memory for boot_info.");
|
||||
mem_set(boot_info,0, sizeof(boot_info_t));
|
||||
// obtain boot information
|
||||
// memory info
|
||||
boot_info->mem_info = (mem_info_t*)hal_halloc(sizeof(mem_info_t));
|
||||
hal_assert(boot_info->mem_info != NULL, "Unable to allocate memory for mem_info.");
|
||||
boot_info->mem_info->mem_available = 0;
|
||||
boot_info->mem_info->mem_reserved = 0;
|
||||
boot_info->mem_info->mem_seg_list = (linked_list_t*)hal_halloc((sizeof(linked_list_t)));
|
||||
hal_assert(boot_info->mem_info->mem_seg_list != NULL, "Unable to allocate memory for mem_seg_list.");
|
||||
linked_list_init(boot_info->mem_info->mem_seg_list);
|
||||
if(m_info->flags & (1 << 6))
|
||||
{
|
||||
boot_info->mem_info = (mem_info_t*)hal_halloc(sizeof(mem_info_t));
|
||||
hal_assert(boot_info->mem_info != NULL, "Unable to allocate memory for mem_info.");
|
||||
boot_info->mem_info->mem_available = 0;
|
||||
boot_info->mem_info->mem_reserved = 0;
|
||||
boot_info->mem_info->mem_seg_list = (linked_list_t*)hal_halloc((sizeof(linked_list_t)));
|
||||
hal_assert(boot_info->mem_info->mem_seg_list != NULL, "Unable to allocate memory for mem_seg_list.");
|
||||
linked_list_init(boot_info->mem_info->mem_seg_list);
|
||||
multiboot_memory_map_t const *mem_map = (multiboot_memory_map_t *) m_info->mmap_addr;
|
||||
uint64_t const mem_map_size = m_info->mmap_length / sizeof(multiboot_memory_map_t);
|
||||
for (int i = 0; i < mem_map_size; i++)
|
||||
|
@ -52,17 +52,16 @@ boot_info_t* NATIVE64 hal_init(multiboot_info_t* m_info)
|
|||
hal_assert(each_desc != NULL, "Unable to allocate memory for memory_descriptor.");
|
||||
each_desc->base_addr = (mem_map + i)->addr;
|
||||
each_desc->size = (mem_map + i)->len;
|
||||
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
|
||||
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
|
||||
{
|
||||
each_desc->type = MEMORY_RESERVED;
|
||||
|
||||
boot_info->mem_info->mem_reserved += (mem_map + i)->len;
|
||||
}
|
||||
else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE)
|
||||
{
|
||||
each_desc->type = MEMORY_AVAILABLE;
|
||||
linked_list_add(boot_info->mem_info->mem_seg_list, &each_desc->list_node);
|
||||
boot_info->mem_info->mem_available += (mem_map + i)->len;
|
||||
}
|
||||
linked_list_add(boot_info->mem_info->mem_seg_list, &each_desc->list_node);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -73,14 +72,14 @@ boot_info_t* NATIVE64 hal_init(multiboot_info_t* m_info)
|
|||
}
|
||||
|
||||
// loaded kernel modules
|
||||
boot_info->module_info = (module_info_t*)hal_halloc(sizeof(module_info_t));
|
||||
hal_assert(boot_info->module_info != NULL, "Unable to allocate memory for module_info.");
|
||||
boot_info->module_info->module_count = 0;
|
||||
boot_info->module_info->module_list = (linked_list_t*)hal_halloc(sizeof(linked_list_t));
|
||||
hal_assert(boot_info->module_info->module_list != NULL, "Unable to allocate memory for module_list.");
|
||||
linked_list_init(boot_info->module_info->module_list);
|
||||
if(m_info->flags & (1 << 3))
|
||||
{
|
||||
boot_info->module_info = (module_info_t*)hal_halloc(sizeof(module_info_t));
|
||||
hal_assert(boot_info->module_info != NULL, "Unable to allocate memory for module_info.");
|
||||
boot_info->module_info->module_count = 0;
|
||||
boot_info->module_info->module_list = (linked_list_t*)hal_halloc(sizeof(linked_list_t));
|
||||
hal_assert(boot_info->module_info->module_list != NULL, "Unable to allocate memory for module_list.");
|
||||
linked_list_init(boot_info->module_info->module_list);
|
||||
multiboot_module_t const * mods_list = (multiboot_module_t *)m_info->mods_addr;
|
||||
boot_info->module_info->module_count = m_info->mods_count;
|
||||
for (uint64_t i = 0; i < boot_info->module_info->module_count; i++)
|
||||
|
|
|
@ -91,44 +91,46 @@ void NATIVE64 hal_create_initial_page_table(void* const base, uint64_t size)
|
|||
|
||||
};
|
||||
|
||||
//
|
||||
//uint64_t NATIVE64 map_page(void *const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const attr, uint64_t const availableRam)
|
||||
|
||||
//uint64_t NATIVE64 hal_map_page(void* const base, uint64_t const p_addr, uint64_t const v_addr, uint64_t const flags)
|
||||
//{
|
||||
// //wait a sec, we actually need maximum memory information here for effectively map crap
|
||||
// // assume the initial page table has already been allocated
|
||||
//
|
||||
// // check p_addr and v_addr 4k-aligned
|
||||
// if(base == NULL || p_addr << 52 || v_addr << 52)
|
||||
// return 0;
|
||||
// //ASSUME: little endian
|
||||
// //All of the following should be 4K-aliened
|
||||
// return 1;
|
||||
//
|
||||
// uint64_t const pml4_index = (v_addr >> 39) & 0x1FF;
|
||||
// uint64_t const pdpt_index = (v_addr >> 30) & 0x1FF;
|
||||
// uint64_t const pd_index = (v_addr >> 21) & 0x1FF;
|
||||
// uint64_t const pt_index = (v_addr >> 12) & 0x1FF;
|
||||
////
|
||||
//// void * const pml4_entry_addr = (void*)((uint64_t*) base + pml4_index);
|
||||
//// if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
|
||||
//// {
|
||||
//// //PML4 does not exist
|
||||
//// write_pml4_entry(pml4_entry_addr, (uint64_t)((uint64_t*)pdpt_base + pml4_index * 512), PML4_PRESENT | PML4_WRITE);
|
||||
//// }
|
||||
//// uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
|
||||
////
|
||||
//// void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
|
||||
//// if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
|
||||
//// {
|
||||
//// write_pdpt_entry(pdpt_entry_addr, (uint64_t)((uint64_t*)pd_base + pml4_index * 512 * 512 + pdpt_index * 512), PDPT_PRESENT | PDPT_WRITE);
|
||||
//// }
|
||||
//// uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
|
||||
////
|
||||
//// void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
|
||||
//// if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
|
||||
//// {
|
||||
//// write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
|
||||
//// }
|
||||
//// uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
|
||||
////
|
||||
//// void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
|
||||
//// write_pt_entry(pt_entry_addr, p_addr, attr);
|
||||
//
|
||||
// void * const pml4_entry_addr = (void*)((uint64_t*) base + pml4_index);
|
||||
// if(!(*(uint64_t*)pml4_entry_addr & PML4_PRESENT))
|
||||
// {
|
||||
// //PML4 does not exist
|
||||
// return 1;
|
||||
// }
|
||||
// uint64_t const pml4_entry = *(uint64_t*)pml4_entry_addr;
|
||||
//
|
||||
// void * const pdpt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pml4_entry) + pdpt_index);
|
||||
// if(!(*(uint64_t*) pdpt_entry_addr & PDPT_PRESENT))
|
||||
// {
|
||||
// //PDPT does not exist
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// uint64_t const pdpt_entry = *(uint64_t*)pdpt_entry_addr;
|
||||
//
|
||||
// void * const pd_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pdpt_entry) + pd_index);
|
||||
// if(!(*(uint64_t*) pd_entry_addr & PD_PRESENT))
|
||||
// {
|
||||
// write_pd_entry(pd_entry_addr, (uint64_t)((uint64_t*)pt_base + pml4_index * 512 * 512 * 512 + pdpt_index * 512 * 512 + pd_index*512), PD_PRESENT | PD_WRITE);
|
||||
// }
|
||||
// uint64_t const pd_entry = *(uint64_t*)pd_entry_addr;
|
||||
//
|
||||
// void * const pt_entry_addr = (void*)((uint64_t*) PAGE_ENTRY_BASE(pd_entry) + pt_index);
|
||||
// hal_write_pt_entry(pt_entry_addr, p_addr, flags);
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#include "pmm.h"
|
||||
#include "../common/sys/sys_info.h"
|
||||
#include "../hal/io.h"
|
||||
#include "../common/util/list/linked_list/linked_list.h"
|
||||
#include "../common/util/util.h"
|
||||
|
||||
linked_list_t* occupied_mem;
|
||||
linked_list_t* available_mem;
|
||||
|
||||
void pmm_init(linked_list_t* occupied, linked_list_t* available)
|
||||
{
|
||||
hal_assert(occupied_mem != NULL && available_mem != NULL, NULL);
|
||||
occupied_mem = occupied;
|
||||
available_mem = available;
|
||||
return;
|
||||
}
|
||||
|
||||
void _pmm_add_page(linked_list_t* list,uint64_t base_addr, uint64_t size)
|
||||
{
|
||||
hal_assert(list != NULL,NULL);
|
||||
base_addr = (base_addr >> 12) << 12;
|
||||
if(list->size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < list->size; i++) {
|
||||
memory_descriptor_node_t *each_node = OBTAIN_STRUCT_ADDR(linked_list_get(list, i), list_node,
|
||||
memory_descriptor_node_t);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* pmm_alloc_page()
|
||||
{
|
||||
hal_assert(occupied_mem != NULL && available_mem != NULL, NULL);
|
||||
if(available_mem->size == 0)
|
||||
return NULL;
|
||||
for(int i = 0; i < available_mem->size; i++)
|
||||
{
|
||||
memory_descriptor_node_t* each_node = OBTAIN_STRUCT_ADDR(linked_list_get(available_mem,i),list_node,memory_descriptor_node_t);
|
||||
if(each_node->size >= PHYSICAL_PAGE_SIZE)
|
||||
{
|
||||
uint64_t address = each_node->base_addr;
|
||||
// found, add to occupied list and return
|
||||
each_node->size = each_node->size - PHYSICAL_PAGE_SIZE;
|
||||
each_node->base_addr = each_node->base_addr + PHYSICAL_PAGE_SIZE;
|
||||
|
||||
|
||||
return (void*)address;
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pmm_free_page(void *physical_addr)
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef _PMM_H_
|
||||
#define _PMM_H_
|
||||
|
||||
#include "../common/util/list/linked_list/linked_list.h"
|
||||
|
||||
#define PHYSICAL_PAGE_SIZE 4096
|
||||
|
||||
void pmm_init(linked_list_t* occupied, linked_list_t* available);
|
||||
|
||||
void*pmm_alloc_page();
|
||||
|
||||
void pmm_free_page(void *p_addr);
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
global load_gdt
|
||||
global support_x64
|
||||
global disable_paging
|
||||
global enable_paging
|
||||
[SECTION .text]
|
||||
|
@ -28,40 +27,6 @@ mov esp,ebp
|
|||
pop ebp
|
||||
ret
|
||||
|
||||
;int support_x64(void)
|
||||
support_x64:
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, eax
|
||||
xor eax, 1 << 21
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
push ecx
|
||||
popfd
|
||||
xor eax, ecx
|
||||
jz .not_supported
|
||||
mov eax, 0x80000000 ; Set the A-register to 0x80000000.
|
||||
cpuid ; CPU identification.
|
||||
cmp eax, 0x80000001 ; Compare the A-register with 0x80000001.
|
||||
jb .not_supported ; It is less, there is no long mode.
|
||||
mov eax, 0x80000001 ; Set the A-register to 0x80000001.
|
||||
cpuid ; CPU identification.
|
||||
test edx, 1 << 29 ; Test if the LM-bit, which is bit 29, is set in the D-register.
|
||||
jz .not_supported ; They aren't, there is no long mode.
|
||||
mov eax,1
|
||||
jmp .end
|
||||
.not_supported:
|
||||
xor eax,eax
|
||||
.end:
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
|
||||
;void disable_paging(void)
|
||||
disable_paging:
|
||||
mov eax, cr0 ; Set the A-register to control register 0.
|
||||
|
|
|
@ -9,7 +9,6 @@ uint8_t g_idt[8 * 256];
|
|||
idt_ptr_t g_idt_ptr;
|
||||
|
||||
extern uint32_t text_pos;
|
||||
extern void init_x64(multiboot_info_t* multiboot_info);
|
||||
extern void BOCHS_MAGIC_BREAKPOINT(void);
|
||||
extern void HLT_CPU(void);
|
||||
extern char kernel_start[];
|
||||
|
@ -20,13 +19,6 @@ void NATIVE32 kmain(multiboot_info_t *multiboot_info)
|
|||
//init text_position
|
||||
text_pos = 0;
|
||||
|
||||
//detect architecture
|
||||
if (support_x64() == 1)
|
||||
{
|
||||
kprintf("Architecture x64.\n\n");
|
||||
init_x64(multiboot_info);
|
||||
}
|
||||
kprintf("Architecture x86.\n\n");
|
||||
kprintf("Kernel Loaded at 0x%X. Size: %uB, %uKB\n\n",kernel_start,(kernel_end-kernel_start),(kernel_end-kernel_start)/1024);
|
||||
//dummy descriptor
|
||||
write_segment_descriptor((void *) (&g_gdt[0]), 0, 0, 0);
|
||||
|
|
|
@ -42,7 +42,6 @@ void NATIVE32 write_segment_descriptor(void *const gdt, uint32_t const base, uin
|
|||
extern void NATIVE32 load_gdt(gdt_ptr_t const * const ptr, uint16_t const sel_code, uint16_t const sel_data);
|
||||
void NATIVE32 mem_cpy(void* src, void* dst, uint32_t size);
|
||||
void NATIVE32 mem_move(void* src, void* dst, uint32_t size);
|
||||
extern int32_t NATIVE32 support_x64(void);
|
||||
extern void disable_paging(void);
|
||||
extern void enable_paging(void);
|
||||
void NATIVE32 mem_set(void* src, int8_t const val,uint32_t size);
|
||||
|
|
Loading…
Reference in New Issue