Code: Select all
// Check 0x400000 virtual address before writing a value
page_t* page_1 = get_page(0x400000, 1, kernel_pml4); // If not present, it will create a new page
printf("Test Address: %x\n", test_addr);
printf("Test Value: %d\n", *test_addr);
printf("Page: present=%d, rw=%d, user=%d, frame=%x\n", page_1->present, page_1->rw, page_1->user, page_1->frame);
// Check 0x400000 virtual address after writing a value
*test_addr = 12345; // Write a test value to the address
printf("Test Address: %x\n", test_addr);
printf("Test Value: %d\n", *test_addr);
page_t* page = get_page(0x400000, 1, kernel_pml4);
printf("Page: present=%d, rw=%d, user=%d, frame=%x\n", page->present, page->rw, page->user, page->frame);
Code: Select all
Test Address: 0x400000
Test Value: 4299235335
Page: present=1, rw=1, user=1, frame=0x100412
Test Address: 0x400000
Test Value: 12345
Page: present=1, rw=0, user=0, frame=0x3
Code: Select all
page_t* get_page(uint64_t va, int make, pml4_t* pml4) {
// printf("Inside of get_page:va=%x\n", va);
uint64_t pml4_index = PML4_INDEX(va);
uint64_t pdpt_index = PDPT_INDEX(va);
uint64_t pd_index = PD_INDEX(va);
uint64_t pt_index = PT_INDEX(va);
uint64_t page_offset = PAGE_OFFSET(va);
/*
printf("PML4 Index: %d, PDPT Index: %d, PD Index: %d, PT Index: %d, Page Offset: %d\n",
pml4_index, pdpt_index, pd_index, pt_index, page_offset);
*/
if(!pml4){
printf("[Error] Paging: get_page: pml4 is NULL\n");
return NULL;
}
// Get the PML4 entry from pml4_index which is found from va
dir_entry_t* pml4_entry = (dir_entry_t*) &pml4->entry_t[pml4_index];
if (!pml4_entry){
printf("[Error] Paging: PML4 entry is NULL\n");
return NULL; // PML4 entry does not exist
}
// the below if block will create pdpt if not present then make a new pdpt by bool make = 1
if (!pml4_entry->present) {
if (!make) {
printf("[Error] Paging: PML4 entry not present and make is false\n");
return NULL; // Page table does not exist and we are not allowed to create it
}
// Allocate a new PDPT
pdpt_t* pdpt = alloc_pdpt(); // Creating a new pdpt
if (!pdpt) {
printf("[Error] Paging: Failed to allocate PDPT\n");
return NULL; // Allocation failed
}
// Set up the PML4 entry
pml4_entry->present = 1;
pml4_entry->rw = 1; // Read/write
if(va >= HIGHER_HALF_START_ADDR){
pml4_entry->user = 0; // Kernel mode
}else{
pml4_entry->user = 1; // User mode
}
pml4_entry->base_addr = (uint64_t) pdpt >> 12; // Base address of PDPT
}
// Get the PDPT entry
pdpt_t* pdpt = (pdpt_t*)phys_to_vir(pml4_entry->base_addr << 12); // Converting base address into pdpt pointer
if(!pdpt){
printf("[Error] Paging: pdpt is NULL\n");
return NULL; // PDPT entry does not exist
}
dir_entry_t* pdpt_entry = ( dir_entry_t*) &pdpt->entry_t[pdpt_index]; //
if(!pdpt_entry){
printf("[Error] Paging: pdpt_entry is NULL\n");
return NULL; // PDPT entry does not exist
}
// the below if block will create pd if not present and make = 1
if (!pdpt_entry->present) {
if (!make) {
printf("[Error] Paging: PDPT entry not present and make is false\n");
return NULL; // Page directory does not exist and we are not allowed to create it
}
// Allocate a new PD
pd_t* pd = alloc_pd();
if (!pd) {
return NULL; // Allocation failed
}
// Set up the PDPT entry
pdpt_entry->present = 1;
pdpt_entry->rw = 1; // Read/write
if(va >= HIGHER_HALF_START_ADDR){
pml4_entry->user = 0; // Kernel mode
}else{
pml4_entry->user = 1; // User mode
}
pdpt_entry->base_addr = (uint64_t)pd >> 12; // Base address of PD
}
// Get the PD entry
pd_t* pd = (pd_t*)(pdpt_entry->base_addr << 12);
if(!pd){
printf("[Error] Paging: pd is NULL\n");
return NULL; // PD entry does not exist
}
dir_entry_t* pd_entry = (dir_entry_t*) &pd->entry_t[pd_index];
if(!pd_entry){
printf("[Error] Paging: pd_entry is NULL\n");
return NULL; // PD entry does not exist
}
// the below if block will create pt if not present and make = 1
if (!pd_entry->present) {
if (!make) {
printf("[Error] Paging: PD entry not present and make is false\n");
return NULL; // Page table does not exist and we are not allowed to create it
}
// Allocate a new PT
pt_t* pt = alloc_pt();
if (!pt) {
printf("[Error] Paging: Failed to allocate PT\n");
return NULL; // Allocation failed
}
// Set up the PD entry
pd_entry->present = 1;
pd_entry->rw = 1; // Read/write
if(va >= HIGHER_HALF_START_ADDR){
pml4_entry->user = 0; // Kernel mode
}else{
pml4_entry->user = 1; // User mode
}
pd_entry->base_addr = (uint64_t)pt >> 12; // Base address of PT
}
// Get the PT entry from pd_entry->base_addr
pt_t* pt = (pt_t*)phys_to_vir(pd_entry->base_addr << 12);
if(!pt){
printf("[Error] Paging: pt is NULL\n");
return NULL; // PT entry does not exist
}
page_t *page = (page_t *) &pt->pages[pt_index];
if (!page) {
printf("[Error] Paging: Page is NULL\n");
return NULL; // Page entry does not exist
}
if(page != NULL){
page->present = 1;
}
flush_tlb(va);
return page;
}
paging.c
paging.h