Physical memory manager [In Progress]

This commit is contained in:
unknown 2015-09-04 15:04:22 -04:00
parent a4411ce9a6
commit 58c61bae3c
10 changed files with 131 additions and 96 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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++)

View File

@ -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;
//}

63
x64/src/c/kernel/pmm.c Normal file
View File

@ -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)
{
}

14
x64/src/c/kernel/pmm.h Normal file
View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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);