7f324e486aee5ae9565eb5a3fe935313c268984d
[lunaix-os.git] / lunaix-os / kernel / boot_helper.c
1 #include <klibc/string.h>
2 #include <lunaix/boot_generic.h>
3 #include <lunaix/mm/pmm.h>
4 #include <lunaix/mm/vmm.h>
5 #include <lunaix/spike.h>
6 #include <lunaix/kcmd.h>
7 #include <sys/mm/mm_defs.h>
8
9 extern unsigned char __kexec_end[], __kexec_start[];
10
11 /**
12  * @brief Reserve memory for kernel bootstrapping initialization
13  *
14  * @param bhctx
15  */
16 void
17 boot_begin(struct boot_handoff* bhctx)
18 {
19     bhctx->prepare(bhctx);
20     
21     // Identity-map the first 3GiB address spaces
22     pte_t* ptep  = mkl0tep(mkptep_va(VMS_SELF, 0));
23     pte_t pte    = mkpte_prot(KERNEL_DATA);
24     size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE);
25
26     vmm_set_ptes_contig(ptep, pte_mkhuge(pte), L0T_SIZE, count);
27
28     // 将内核占据的页,包括前1MB,hhk_init 设为已占用
29     size_t pg_count = leaf_count(to_kphysical(__kexec_end));
30     pmm_onhold_range(0, pg_count);
31
32     size_t i;
33     struct boot_mmapent* ent;
34     for (i = 0; i < bhctx->mem.mmap_len; i++) {
35         ent = &bhctx->mem.mmap[i];
36
37         if (reserved_memregion(ent) || reclaimable_memregion(ent)) {
38             unsigned int counts = leaf_count(ent->size);
39             pmm_onhold_range(pfn(ent->start), counts);
40         }
41     }
42
43     /* Reserve region for all loaded modules */
44     for (i = 0; i < bhctx->mods.mods_num; i++) {
45         struct boot_modent* mod = &bhctx->mods.entries[i];
46         unsigned int counts = leaf_count(mod->end - mod->start);
47
48         pmm_onhold_range(pfn(mod->start), counts);
49     }
50 }
51
52 extern u8_t __kboot_end; /* link/linker.ld */
53
54 /**
55  * @brief Release memory for kernel bootstrapping initialization
56  *
57  * @param bhctx
58  */
59 void
60 boot_end(struct boot_handoff* bhctx)
61 {
62     struct boot_mmapent* ent;
63     for (size_t i = 0; i < bhctx->mem.mmap_len; i++) {
64         ent = &bhctx->mem.mmap[i];
65
66         if (reclaimable_memregion(ent)) {
67             unsigned int counts = leaf_count(ent->size);
68             pmm_unhold_range(pfn(ent->start), counts);
69         }
70     }
71
72     bhctx->release(bhctx);
73 }
74
75 /**
76  * @brief Clean up the boot stage code and data
77  *
78  */
79 void
80 boot_cleanup()
81 {
82     pte_t* ptep  = mkl0tep(mkptep_va(VMS_SELF, 0));
83     size_t count = page_count(KERNEL_RESIDENT, L0T_SIZE);
84     vmm_unset_ptes(ptep, count);
85 }
86
87 void
88 boot_parse_cmdline(struct boot_handoff* bhctx) {
89     if (!bhctx->kexec.len) {
90         return;
91     }
92
93     kcmd_parse_cmdline(bhctx->kexec.cmdline);
94 }