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:
2023-02-08 14:07:44 +01:00
parent 7993a2d172
commit 520104a43a
23 changed files with 474 additions and 701 deletions

View File

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

View File

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

View File

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

View File

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

View File

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