3 #include <lunaix/mm/pagetable.h>
4 #include <lunaix/compiler.h>
6 #include <sys/boot/bstage.h>
7 #include <sys/mm/mm_defs.h>
9 // Provided by linker (see linker.ld)
10 extern u8_t __kexec_start[];
11 extern u8_t __kexec_end[];
12 extern u8_t __kexec_text_start[];
13 extern u8_t __kexec_text_end[];
14 extern u8_t __kboot_start[];
15 extern u8_t __kboot_end[];
17 // define the initial page table layout
19 pte_t l0t[_PAGE_LEVEL_SIZE];
22 pte_t _lft[_PAGE_LEVEL_SIZE];
26 static struct kernel_map kernel_pt __section(".kpg");
27 export_symbol(debug, boot, kernel_pt);
33 struct kernel_map* kpt_pa = (struct kernel_map*)to_kphysical(&kernel_pt);
35 pte_t* kl0tep = (pte_t*) &kpt_pa->l0t[pfn_at(KERNEL_RESIDENT, L0T_SIZE)];
36 pte_t* kl1tep = (pte_t*) kpt_pa->kernel_lfts;
37 pte_t* boot_l0tep = (pte_t*) kpt_pa;
39 set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_DATA)));
43 // Hook the kernel reserved LFTs onto L0T
44 pte_t pte = mkpte((ptr_t)kl1tep, KERNEL_DATA);
46 for (u32_t i = 0; i < KEXEC_RSVD; i++) {
47 pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->kernel_lfts[i]);
53 // Ensure the size of kernel is within the reservation
54 pfn_t kimg_pagecount =
55 pfn((ptr_t)__kexec_end - (ptr_t)__kexec_start);
56 if (kimg_pagecount > KEXEC_RSVD * _PAGE_LEVEL_SIZE) {
57 // ERROR: require more pages
58 // here should do something else other than head into blocking
62 // Now, map the kernel
64 pfn_t kimg_end = pfn(to_kphysical(__kexec_end));
65 pfn_t i = pfn(to_kphysical(__kexec_text_start));
69 pte = pte_setprot(pte, KERNEL_EXEC);
70 pfn_t ktext_end = pfn(to_kphysical(__kexec_text_end));
71 for (; i < ktext_end; i++) {
72 pte = pte_setpaddr(pte, page_addr(i));
78 // all remaining kernel sections
79 pte = pte_setprot(pte, KERNEL_DATA);
80 for (; i < kimg_end; i++) {
81 pte = pte_setpaddr(pte, page_addr(i));
87 // XXX: Mapping the kernel .rodata section?
89 // Build up self-reference
90 pte = mkpte_root((ptr_t)kpt_pa, KERNEL_DATA);
91 set_pte(boot_l0tep + _PAGE_LEVEL_MASK, pte);
97 ptr_t kmap_pa = to_kphysical(&kernel_pt);
98 for (size_t i = 0; i < sizeof(kernel_pt); i++) {
99 ((u8_t*)kmap_pa)[i] = 0;