diff options
Diffstat (limited to 'src/core/paging.cc')
| -rw-r--r-- | src/core/paging.cc | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/src/core/paging.cc b/src/core/paging.cc index 8e58511..73a5c63 100644 --- a/src/core/paging.cc +++ b/src/core/paging.cc @@ -4,29 +4,50 @@ #include "libs/string.hpp" char paging_status[PAGING_MAX_PAGE / 8]; -u64* kpml4; +u64 kernel_vma,stack_pma,userspace_pma; +u64 kpages[MAX_TABLES][512] __attribute__((aligned(4096))); +int kpages_next=1; // First page is for the pml4 + +u64* paging_allocate_table(){ + u64 addr=(u64)kpages[kpages_next]; + u64* allocated=(u64*)(addr-kernel_vma); + kpages_next++; + return allocated; +} void paging_enable() { + // Init linker variables + asm("movq $__kernel_vma, %0":"=r"(kernel_vma)); + asm("movq $__userspace_pma, %0":"=r"(userspace_pma)); + asm("movq $__stack_pma, %0":"=r"(stack_pma)); + // Init status for (int i = 0; i < PAGING_MAX_PAGE / 8; i++) { paging_status[i] = 0; } + // Init tables + for(int i=0;i<MAX_TABLES;i++){ + memset(kpages[i], 0, 512*64); + } + // Allocate paging for the kernel (to not override the source // code during the next paging_allocate_table() calls) - paging_allocate_contiguous(PAGING_KERNEL_USED_PAGE); + paging_allocate_contiguous(userspace_pma/4096); // Setting up new kernel address space - kpml4=paging_allocate_table(); - for(int i=0;i<PAGING_KERNEL_SPACE_MAX_PAGE;i++){ - int addr=i*4096; - paging_allocate_addr(kpml4,addr,addr, PAGING_OPT_P|PAGING_OPT_RW); // Identity map + for(u64 i=0;i<=0x10000000;i+=4096){ + paging_allocate_addr(kpages[0],kernel_vma+i,i, 0x3,0); // Identity map } + // 4096 bytes stack + paging_allocate_addr(kpages[0],kernel_vma-4096,stack_pma,0x3,0); + // Load new pml4 + u64 kpage_phy=((u64)kpages[0]-kernel_vma); asm volatile( - "movq %0, %%rax \n\t" - "movq %%rax, %%cr3 \n\t" - :: "r" (kpml4)); + "mov %0, %%rax \n\t" + "mov %%rax, %%cr3 \n\t" + :: "r" (kpage_phy)); } u64 paging_as_phy(u64* pml4_table, u64 virt){ @@ -40,6 +61,7 @@ u64 paging_as_phy(u64* pml4_table, u64 virt){ u64* pt_table=(u64*)PAGE(pd_table[pd]); return((PAGE(pt_table[pt]))|(virt&0xFFF)); } + u64* paging_allocate_contiguous(int npages){ int n_contiguous=0; for (int i = 0; i < PAGING_MAX_PAGE / 8; i++) { @@ -116,12 +138,6 @@ void paging_dump(int min, int max) { } } -u64* paging_allocate_table(){ - u64* table=paging_allocate_contiguous(8); - memset(table, 0, 32768); // nb_entries * entry size = 512 * 64 - return table; -} - void paging_deallocate_table(u64* table){ char *c_table=(char*)PAGE((u64)table); for(u8 i=0;i<8;i++){ @@ -130,7 +146,7 @@ void paging_deallocate_table(u64* table){ } } -void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options){ +void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options, u64 offset){ u16 pml4=virt>>39&0x1FF; u16 pdp=virt>>30&0x1FF; u16 pd=virt>>21&0x1FF; @@ -141,27 +157,29 @@ void paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options){ if(pml4_table[pml4] == 0){ pml4_table[pml4]=(u64)paging_allocate_table(); pml4_table[pml4]|=options; - paging_allocate_addr(pml4_table,virt,phy,options); + paging_allocate_addr(pml4_table,virt,phy,options,offset); return; } + // Solve pd - u64* pdp_table=(u64*)PAGE(pml4_table[pml4]); + u64* pdp_table=(u64*)(PAGE(pml4_table[pml4])+offset); if(pdp_table[pdp] == 0){ pdp_table[pdp]=(u64)paging_allocate_table(); pdp_table[pdp]|=options; - paging_allocate_addr(pml4_table,virt,phy,options); + paging_allocate_addr(pml4_table,virt,phy,options,offset); return; } + // Solve pt - u64* pd_table=(u64*)PAGE(pdp_table[pdp]); + u64* pd_table=(u64*)(PAGE(pdp_table[pdp])+offset); if(pd_table[pd] == 0){ pd_table[pd]=(u64)paging_allocate_table(); pd_table[pd]|=options; - paging_allocate_addr(pml4_table,virt,phy,options); + paging_allocate_addr(pml4_table,virt,phy,options,offset); return; } // Solve address - u64* pt_table=(u64*)PAGE(pd_table[pd]); + u64* pt_table=(u64*)(PAGE(pd_table[pd])+offset); if(pt_table[pt] == 0){ pt_table[pt]=PAGE(phy); pt_table[pt]|=options; |
