diff options
| author | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-27 19:02:17 +0200 |
|---|---|---|
| committer | Loic Guegan <manzerbredes@mailbox.org> | 2021-04-27 19:02:17 +0200 |
| commit | f13b26eeb4f9afba3a1aed2516655b34139979aa (patch) | |
| tree | 9ec48586fa57749f2c1cb40d940863d2251bd401 /src/boot/trampoline.cc | |
| parent | 9dc527b3be9d493dcf8cf1baf78477373eb5990d (diff) | |
Making kernel Higher-Half
Diffstat (limited to 'src/boot/trampoline.cc')
| -rw-r--r-- | src/boot/trampoline.cc | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/boot/trampoline.cc b/src/boot/trampoline.cc new file mode 100644 index 0000000..b03bd43 --- /dev/null +++ b/src/boot/trampoline.cc @@ -0,0 +1,94 @@ +/** + * The usage of data that could goes + * to the .bss section is forbidden here + */ + +#include "core/types.hpp" +#include "core/paging.hpp" + + +/// @brief Define where first PAE paging paging will be +u64 trampoline_next_page; + +u64 trampoline_paging_allocate_table(){ + for(u64 i=0;i<512;i++) + ((u64*)trampoline_next_page)[i]=0; + u64 ret=trampoline_next_page; + trampoline_next_page+=4096; + return ret; +} + + +void trampoline_paging_allocate_addr(u64* pml4_table, u64 virt, u64 phy, u16 options){ + u64 pml4=virt>>39&0x1FF; + u64 pdp=virt>>30&0x1FF; + u64 pd=virt>>21&0x1FF; + u64 pt=virt>>12&0x1FF; + options&=0xFFF; // Ensure options are on 12bits + + + // Solve pdp + if(pml4_table[pml4] == 0){ + pml4_table[pml4]=(u64)trampoline_paging_allocate_table(); + pml4_table[pml4]|=options; + trampoline_paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + + // Solve pd + u64* pdp_table=(u64*)PAGE(pml4_table[pml4]); + if(pdp_table[pdp] == 0){ + pdp_table[pdp]=(u64)trampoline_paging_allocate_table(); + pdp_table[pdp]|=options; + trampoline_paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + // Solve pt + u64* pd_table=(u64*)PAGE(pdp_table[pdp]); + if(pd_table[pd] == 0){ + pd_table[pd]=(u64)trampoline_paging_allocate_table(); + pd_table[pd]|=options; + trampoline_paging_allocate_addr(pml4_table,virt,phy,options); + return; + } + // Solve address + u64* pt_table=(u64*)PAGE(pd_table[pd]); + if(pt_table[pt] == 0){ + pt_table[pt]=PAGE(phy); + pt_table[pt]|=options; + return; + } +} + +/** + * Setup High-Half Kernel Paging + */ +extern "C" void trampoline(){ + u64 kernel_vma,stack_pma; + asm("movq $__kernel_vma, %0":"=r"(kernel_vma)); + asm("movq $__userspace_pma, %0":"=r"(trampoline_next_page)); + asm("movq $__stack_pma, %0":"=r"(stack_pma)); + + // ----- Build the trampoline paging tables + u64 *pml4=(u64*)trampoline_paging_allocate_table(); + // Higher Half kernel + for(u64 i=0;i<=0x1000000;i+=4096){ + trampoline_paging_allocate_addr(pml4,kernel_vma+i,i,0x3); + } + // Stack + trampoline_paging_allocate_addr(pml4,kernel_vma-4096,stack_pma,0x3); + // First bytes for current eip + for(u64 i=0;i<=0x1000000;i+=4096){ + trampoline_paging_allocate_addr(pml4,i,i,0x3); + } + // Test + for(u64 i=0xe0000000;i<=0xef000000;i+=4096){ + trampoline_paging_allocate_addr(pml4,i,i,0x3); + } + + // Load new pml4 + asm volatile( + "movq %0, %%rax \n\t" + "movq %%rax, %%cr3 \n\t" + :: "r" (pml4)); +}
\ No newline at end of file |
