71 lines
2.3 KiB
C
71 lines
2.3 KiB
C
#include <stdint.h>
|
|
#include "paging_helpers.h"
|
|
#include "paging.h"
|
|
uint32_t page_directory [1024] __attribute__((aligned(4096)));
|
|
uint32_t page_tables [1048576] __attribute__((aligned(4096)));
|
|
void* next_kern_virt=(void*)KERN_VIRT_START;
|
|
void* next_kern_phys=(void*)KERN_PHYS_START;
|
|
void set_directory_entry(int entry,char usr,char wr,char p,uint32_t* page_directory,uint32_t* page_tables) {
|
|
int flags=p&1;
|
|
flags=flags|((wr&1)<<1);
|
|
flags=flags|((usr&1)<<2);
|
|
page_directory[entry]=(((uint32_t)&(page_tables[entry*1024]))-0xC0000000)|flags;
|
|
}
|
|
|
|
void set_table_entry(uint32_t page,uint32_t base_addr,char usr,char wr,char p,uint32_t* page_tables) {
|
|
int flags=p&1;
|
|
flags=flags|((wr&1)<<1);
|
|
flags=flags|((usr&1)<<2);
|
|
page_tables[page]=base_addr|flags;
|
|
}
|
|
|
|
void alloc_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr,uint32_t* page_directory,uint32_t* page_tables) {
|
|
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
|
|
uint32_t phys_addr=(uint32_t)phys_addr_ptr;
|
|
int dir_entry=(virt_addr&0xFFC00000)>>22;
|
|
int table_entry=(virt_addr&0x3FF000)>>12;
|
|
for (int i=0;i<=num_pages;i++) {
|
|
set_table_entry((dir_entry*1024)+table_entry,phys_addr,usr,wr,1,page_tables);
|
|
table_entry++;
|
|
phys_addr+=0x1000;
|
|
if (table_entry==1024) {
|
|
table_entry=0;
|
|
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
|
|
dir_entry++;
|
|
} else if (i==num_pages) {
|
|
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
|
|
}
|
|
}
|
|
}
|
|
|
|
void* alloc_kern_pages(int num_pages,char wr) {
|
|
void* starting=next_kern_virt;
|
|
alloc_pages(next_kern_virt,next_kern_phys,num_pages,1,wr,page_directory,page_tables);
|
|
next_kern_virt+=num_pages*4096;
|
|
next_kern_phys+=num_pages*4096;
|
|
return starting;
|
|
}
|
|
|
|
int dir_entry_present(int entry) {
|
|
uint32_t dir_entry=page_directory[entry];
|
|
return dir_entry&1;
|
|
}
|
|
|
|
void* virt_to_phys(void* virt_addr_ptr) {
|
|
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
|
|
int dir_num=(virt_addr&0xFFC00000)>>22;
|
|
int table_num=(virt_addr&0x3FF000)>>12;
|
|
int offset=(virt_addr&0xFFF);
|
|
uint32_t table_entry=page_tables[(dir_num*1024)+table_num];
|
|
table_entry=table_entry&0xFFFFF000;
|
|
return (void*)(table_entry+offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_paging() {
|
|
alloc_kern_pages(NUM_KERN_DIRS*1024,1);
|
|
load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000));
|
|
}
|