aboutsummaryrefslogtreecommitdiff
path: root/src/boot/trampoline.cc
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2021-04-27 19:02:17 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2021-04-27 19:02:17 +0200
commitf13b26eeb4f9afba3a1aed2516655b34139979aa (patch)
tree9ec48586fa57749f2c1cb40d940863d2251bd401 /src/boot/trampoline.cc
parent9dc527b3be9d493dcf8cf1baf78477373eb5990d (diff)
Making kernel Higher-Half
Diffstat (limited to 'src/boot/trampoline.cc')
-rw-r--r--src/boot/trampoline.cc94
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