X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/28c176b668c841a3b7fb093faccf0efa39257603..34f6af4f61e0eec9c96113e07f140b609b4113c8:/lunaix-os/arch/x86/boot/i386/kremap32.c?ds=sidebyside diff --git a/lunaix-os/arch/x86/boot/i386/kremap32.c b/lunaix-os/arch/x86/boot/i386/kremap32.c index c73c2a3..eac5793 100644 --- a/lunaix-os/arch/x86/boot/i386/kremap32.c +++ b/lunaix-os/arch/x86/boot/i386/kremap32.c @@ -2,14 +2,19 @@ #include #include +#include #include -#include +#include + +#define PF_X 0x1 +#define PF_W 0x2 +#define ksection_maps autogen_name(ksecmap) + +extern_autogen(ksecmap); -bridge_farsym(__kexec_start); -bridge_farsym(__kexec_end); bridge_farsym(__kexec_text_start); -bridge_farsym(__kexec_text_end); +bridge_farsym(ksection_maps); // define the initial page table layout struct kernel_map; @@ -17,7 +22,8 @@ struct kernel_map; static struct kernel_map kernel_pt __section(".kpg"); export_symbol(debug, boot, kernel_pt); -struct kernel_map { +struct kernel_map +{ pte_t l0t[_PAGE_LEVEL_SIZE]; pte_t pg_mnt[_PAGE_LEVEL_SIZE]; @@ -36,12 +42,12 @@ do_remap() pte_t* ktep = (pte_t*) kpt_pa->kernel_lfts; pte_t* boot_l0tep = (pte_t*) kpt_pa; - set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_DATA))); + set_pte(boot_l0tep, pte_mkhuge(mkpte_prot(KERNEL_PGTAB))); // --- 将内核重映射至高半区 --- // Hook the kernel reserved LFTs onto L0T - pte_t pte = mkpte((ptr_t)ktep, KERNEL_DATA); + pte_t pte = mkpte((ptr_t)ktep, KERNEL_PGTAB); for (u32_t i = 0; i < KEXEC_RSVD; i++) { pte = pte_setpaddr(pte, (ptr_t)&kpt_pa->kernel_lfts[i]); @@ -50,50 +56,58 @@ do_remap() klptep++; } + struct ksecmap* maps; + struct ksection* section; + pfn_t pgs; + pte_t *kmntep; + + maps = (struct ksecmap*)to_kphysical(__far(ksection_maps)); + ktep += pfn(to_kphysical(__far(__kexec_text_start))); + // Ensure the size of kernel is within the reservation - pfn_t kimg_pagecount = - pfn(__far(__kexec_end) - __far(__kexec_start)); - if (kimg_pagecount > KEXEC_RSVD * _PAGE_LEVEL_SIZE) { + if (leaf_count(maps->ksize) > KEXEC_RSVD * _PAGE_LEVEL_SIZE) + { // ERROR: require more pages // here should do something else other than head into blocking asm("ud2"); } - // Now, map the kernel + // Now, map the sections - pfn_t kimg_end = pfn(to_kphysical(__far(__kexec_end))); - pfn_t i = pfn(to_kphysical(__far(__kexec_text_start))); - ktep += i; + for (unsigned int i = 0; i < maps->num; i++) + { + section = &maps->secs[i]; - // kernel .text - pte = pte_setprot(pte, KERNEL_EXEC); - pfn_t ktext_end = pfn(to_kphysical(__far(__kexec_text_end))); - for (; i < ktext_end; i++) { - pte = pte_setpaddr(pte, page_addr(i)); - set_pte(ktep, pte); + if (section->va < KERNEL_RESIDENT) { + continue; + } - ktep++; - } + pte = mkpte_prot(KERNEL_RDONLY); + if ((section->flags & PF_X)) { + pte = pte_mkexec(pte); + } + if ((section->flags & PF_W)) { + pte = pte_mkwritable(pte); + } - // all remaining kernel sections - pte = pte_setprot(pte, KERNEL_DATA); - for (; i < kimg_end; i++) { - pte = pte_setpaddr(pte, page_addr(i)); - set_pte(ktep, pte); + pgs = leaf_count(section->size); + for (pfn_t j = 0; j < pgs; j++) + { + pte = pte_setpaddr(pte, section->pa + page_addr(j)); + set_pte(ktep, pte); - ktep++; + ktep++; + } } - // XXX: Mapping the kernel .rodata section? - // set mount point - pte_t* kmntep = (pte_t*) &kpt_pa->l0t[pfn_at(PG_MOUNT_1, L0T_SIZE)]; - set_pte(kmntep, mkpte((ptr_t)kpt_pa->pg_mnt, KERNEL_DATA)); + kmntep = (pte_t*) &kpt_pa->l0t[pfn_at(PG_MOUNT_1, L0T_SIZE)]; + set_pte(kmntep, mkpte((ptr_t)kpt_pa->pg_mnt, KERNEL_PGTAB)); // Build up self-reference int level = (VMS_SELF / L0T_SIZE) & _PAGE_LEVEL_MASK; - pte = mkpte_root((ptr_t)kpt_pa, KERNEL_DATA); + pte = mkpte_root((ptr_t)kpt_pa, KERNEL_PGTAB); set_pte(&boot_l0tep[level], pte); }