Moved reading file from disk to its own super visor terminal command
- Updated gdt assembly - Updated Interrupt service request handlers - Improved virtual memory manager - NOTE: we're dependent on identity mappings for the heap to work
This commit is contained in:
@ -63,26 +63,24 @@ void free(void* addr)
|
||||
|
||||
void initHeap()
|
||||
{
|
||||
// put the start of our kernel heap 1 page after the kernel_end address
|
||||
// Lets calculate the address
|
||||
printf("FIND SUITABLE HEAP_ADDRESS\n");
|
||||
uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0);
|
||||
uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096;
|
||||
printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS);
|
||||
|
||||
// NOTE: we can't check if the mapping has failed or not here!
|
||||
AllocatePage(HEAP_ADDRESS);
|
||||
start = (heap_block*) HEAP_ADDRESS;
|
||||
void* HEAP_ADDRESS = allocate_block();
|
||||
printf("0x%x HEAP Paddr\n", HEAP_ADDRESS);
|
||||
|
||||
Immediate_Map((uint32_t)HEAP_ADDRESS + 0xC0000000, (uint32_t)HEAP_ADDRESS );
|
||||
start = (heap_block*) ((uint32_t)HEAP_ADDRESS + 0xC0000000);
|
||||
heap_size = 4096;
|
||||
|
||||
printf("Clear heap\n");
|
||||
// Clear the heap
|
||||
printf("set at 0x%x %d bytes to zero\n", start , heap_size);
|
||||
|
||||
memset((void*)start, 0x00, heap_size /4);
|
||||
|
||||
|
||||
printf("Init first heap block\n");
|
||||
// initialzie
|
||||
start->Size = heap_size - sizeof(heap_block);
|
||||
|
||||
start->Used = false;
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
#include "VirtualMemoryManager.h"
|
||||
#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align))
|
||||
|
||||
extern uint32_t boot_page_directory[1024] ;
|
||||
extern uint32_t boot_page_directory[1024] ; // points to the wrong location
|
||||
|
||||
extern uint32_t boot_page_table[1024];
|
||||
|
||||
|
||||
@ -26,29 +27,28 @@ void AllocatePage(uint32_t vaddr)
|
||||
{
|
||||
printf("Directory entry is marked as present\n");
|
||||
uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ;
|
||||
page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
|
||||
printf("Page table address: 0x%x\n", (uint32_t)page_table);
|
||||
//page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset
|
||||
printf("Page table address: 0x%x\n", (uint32_t)&page_table);
|
||||
|
||||
// check if the page table entry is marked as present
|
||||
if ( page_table[PageTableEntryIndex] & 0x1 )
|
||||
{
|
||||
printf("page already present!\n");
|
||||
return;
|
||||
} else{
|
||||
printf("Mapping a physical page.\n");
|
||||
// Map the entry to a physical page
|
||||
page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3);
|
||||
flush_cr3();
|
||||
page_table[PageTableEntryIndex] = (uint32_t)allocate_block() | 0x3;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("Mapping a new page directory entry with a page table\n");
|
||||
// mark the page table as present and allocate a physical block for it
|
||||
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3);
|
||||
flush_cr3();
|
||||
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)allocate_block() | 0x3;
|
||||
|
||||
}
|
||||
|
||||
asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" );
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -74,12 +74,45 @@ void FreePage(uint32_t vaddr )
|
||||
|
||||
void Immediate_Map ( uint32_t vaddr, uint32_t paddr)
|
||||
{
|
||||
uint32_t page_aligned_address = ALIGN(vaddr, 4096);
|
||||
|
||||
printf("map 0x%x to 0x%x\n", paddr, vaddr);
|
||||
// allocate a page at virtual address
|
||||
int PageDirectoryEntryIndex = vaddr >> 22;
|
||||
int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF;
|
||||
|
||||
printf("Map address at PDE 0x%x PTE 0x%x\n", PageDirectoryEntryIndex, PageTableEntryIndex);
|
||||
|
||||
if ((boot_page_directory - 0xC0000000)[PageDirectoryEntryIndex] & 0x1 )
|
||||
{
|
||||
printf("Directory entry is marked as present\n");
|
||||
|
||||
} else {
|
||||
printf("Mapping a new page directory entry with a page table\n");
|
||||
// mark the page table as present and allocate a physical block for it
|
||||
|
||||
void* new_page_dir = allocate_block();
|
||||
printf("New page directory address 0x%x\n", new_page_dir);
|
||||
boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)new_page_dir | 0x3;
|
||||
|
||||
}
|
||||
|
||||
printf("PDE found at : 0x%x\n", (uint32_t) &boot_page_directory[PageDirectoryEntryIndex]);
|
||||
uint32_t* page_table = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000) ;
|
||||
//page_table = (uint32_t*) ((uint32_t)page_table - 0xC0000000); // remove kernel offset
|
||||
printf("Page table address: 0x%x\n", (uint32_t)page_table);
|
||||
|
||||
// check if the page table entry is marked as present
|
||||
if ( page_table[PageTableEntryIndex] & 0x1 )
|
||||
{
|
||||
printf("page already present!\n");
|
||||
printf("Entry found at addr: 0x%x\n", &(page_table[PageTableEntryIndex]));
|
||||
} else{
|
||||
printf("Mapping a physical page.\n");
|
||||
// Map the entry to a physical page
|
||||
page_table[PageTableEntryIndex] = (uint32_t)(paddr | 0x3);
|
||||
}
|
||||
|
||||
|
||||
asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" );
|
||||
}
|
||||
|
||||
void Immediate_Unmap(uint32_t vaddr)
|
||||
|
@ -9,7 +9,7 @@ void SetupVMM();
|
||||
void AllocatePage(uint32_t v_addr );
|
||||
void FreePage(uint32_t v_addr);
|
||||
|
||||
void Immediate_Map(uint32_t p_addr, uint32_t v_addr);
|
||||
void Immediate_Map(uint32_t vaddr, uint32_t paddr);
|
||||
void Immediate_Unmap (uint32_t v_addr);
|
||||
|
||||
// void Demand_map(uint32_t p_addr, uint32_t v_addr);
|
||||
|
@ -6,9 +6,13 @@
|
||||
#define KERNEL_DATA_SEGMENT 2
|
||||
#define USER_CODE_SEGMENT 3
|
||||
#define USER_DATA_SEGMENT 4
|
||||
#define TASK_STATE_SEGMENT 5
|
||||
|
||||
SegmentDescriptor GlobalDescriptorTable[5];
|
||||
SegmentDescriptor GlobalDescriptorTable[6];
|
||||
GlobalDescriptorTableDescriptor gdtDescriptor;
|
||||
tss32 TaskStateSegment = {};
|
||||
|
||||
|
||||
|
||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){
|
||||
GlobalDescriptorTable[which].base_low = (base & 0xFFFF );
|
||||
@ -21,7 +25,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
|
||||
GlobalDescriptorTable[which].granularity |= (granularity & 0xF0);
|
||||
GlobalDescriptorTable[which].access = access;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -29,9 +32,9 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne
|
||||
|
||||
void initGDT(){
|
||||
|
||||
#ifdef __VERBOSE__
|
||||
|
||||
printf("Init GDT!\n");
|
||||
#endif
|
||||
|
||||
// NULL segment
|
||||
add_descriptor(NULL_SEGMENT, 0,0,0,0);
|
||||
|
||||
@ -42,16 +45,18 @@ void initGDT(){
|
||||
add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
// User Code Segment
|
||||
// TODO:
|
||||
add_descriptor(USER_CODE_SEGMENT, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
// User Data Segement
|
||||
// TODO:
|
||||
add_descriptor(USER_DATA_SEGMENT, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
// Task Segment Descriptor
|
||||
add_descriptor(TASK_STATE_SEGMENT, (unsigned long)&TaskStateSegment, sizeof(TaskStateSegment), 0x89, 0x0);
|
||||
|
||||
// init Gdt Descriptor
|
||||
gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1);
|
||||
gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable;
|
||||
gdtDescriptor.base = (unsigned int) (&GlobalDescriptorTable);
|
||||
|
||||
printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable));
|
||||
|
||||
LoadGlobalDescriptorTable();
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct SegmentDescriptor {
|
||||
unsigned short limit_low;
|
||||
unsigned short base_low;
|
||||
@ -10,14 +9,16 @@ struct SegmentDescriptor {
|
||||
unsigned char base_high;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct tss32 {
|
||||
uint64_t bits;
|
||||
uint8_t other_bits :5;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct GlobalDescriptorTableDescriptor{
|
||||
unsigned short limit;
|
||||
unsigned int base;
|
||||
}__attribute__((packed));
|
||||
}__attribute__((packed)) ;
|
||||
|
||||
extern SegmentDescriptor GlobalDescriptorTable[];
|
||||
extern GlobalDescriptorTableDescriptor gdtDescriptor;
|
||||
|
||||
|
||||
void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity );
|
||||
|
Reference in New Issue
Block a user