3 #include <lunaix/boot_generic.h>
4 #include <sys/boot/bstage.h>
5 #include <sys/boot/multiboot.h>
6 #include <sys/mm/mempart.h>
8 #define BHCTX_ALLOC 4096
9 #define MEM_1M 0x100000UL
12 u8_t bhctx_buffer[BHCTX_ALLOC] boot_bss;
14 #define check_buffer(ptr) \
15 if ((ptr) >= ((ptr_t)bhctx_buffer + BHCTX_ALLOC)) { \
20 mb_memcpy(u8_t* destination, u8_t* base, unsigned int size)
23 for (; i < size; i++) {
24 *(destination + i) = *(base + i);
30 mb_strcpy(char* destination, char* base)
34 while ((c = base[i])) {
54 mb_parse_cmdline(struct boot_handoff* bhctx, void* buffer, char* cmdline)
58 size_t slen = mb_strlen(cmdline);
64 mb_memcpy(buffer, (u8_t*)cmdline, slen);
65 bhctx->kexec.len = slen;
66 bhctx->kexec.cmdline = buffer;
72 mb_parse_mmap(struct boot_handoff* bhctx,
73 struct multiboot_info* mb,
76 struct multiboot_mmap_entry* mb_mmap =
77 (struct multiboot_mmap_entry*)__ptr(mb->mmap_addr);
78 size_t mmap_len = mb->mmap_length / sizeof(struct multiboot_mmap_entry);
80 struct boot_mmapent* bmmap = (struct boot_mmapent*)buffer;
81 for (size_t i = 0; i < mmap_len; i++) {
82 struct boot_mmapent* bmmapent = &bmmap[i];
83 struct multiboot_mmap_entry* mb_mapent = &mb_mmap[i];
85 if (mb_mapent->type == MULTIBOOT_MEMORY_AVAILABLE) {
86 bmmapent->type = BOOT_MMAP_FREE;
87 } else if (mb_mapent->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE) {
88 bmmapent->type = BOOT_MMAP_RCLM;
90 bmmapent->type = BOOT_MMAP_RSVD;
93 bmmapent->start = mb_mapent->addr_low;
94 bmmapent->size = mb_mapent->len_low;
97 bhctx->mem.size = (mb->mem_upper << 10) + MEM_1M;
98 bhctx->mem.mmap = bmmap;
99 bhctx->mem.mmap_len = mmap_len;
101 return mmap_len * sizeof(struct boot_mmapent);
105 mb_parse_mods(struct boot_handoff* bhctx,
106 struct multiboot_info* mb,
109 if (!mb->mods_count) {
110 bhctx->mods.mods_num = 0;
114 struct boot_modent* modents = (struct boot_modent*)buffer;
115 struct multiboot_mod_list* mods =
116 (struct multiboot_mod_list*)__ptr(mb->mods_addr);
118 ptr_t mod_str_ptr = __ptr(&modents[mb->mods_count]);
120 for (size_t i = 0; i < mb->mods_count; i++) {
121 struct multiboot_mod_list* mod = &mods[i];
122 modents[i] = (struct boot_modent){ .start = mod->mod_start,
124 .str = (char*)mod_str_ptr };
126 mod_str_ptr += mb_strcpy((char*)mod_str_ptr,
127 (char*)__ptr(mod->cmdline));
130 bhctx->mods.mods_num = mb->mods_count;
131 bhctx->mods.entries = modents;
133 return mod_str_ptr - (ptr_t)buffer;
137 mb_prepare_hook(struct boot_handoff* bhctx)
143 mb_release_hook(struct boot_handoff* bhctx)
148 #define align_addr(addr) (((addr) + (sizeof(ptr_t) - 1)) & ~(sizeof(ptr_t) - 1))
150 struct boot_handoff* boot_text
151 mb_parse(struct multiboot_info* mb)
153 struct boot_handoff* bhctx = (struct boot_handoff*)bhctx_buffer;
154 ptr_t bhctx_ex = (ptr_t)&bhctx[1];
156 *bhctx = (struct boot_handoff){ };
158 /* Parse memory map */
159 if ((mb->flags & MULTIBOOT_INFO_MEM_MAP)) {
160 bhctx_ex += mb_parse_mmap(bhctx, mb, (void*)bhctx_ex);
161 bhctx_ex = align_addr(bhctx_ex);
165 if ((mb->flags & MULTIBOOT_INFO_CMDLINE)) {
167 mb_parse_cmdline(bhctx, (void*)bhctx_ex, (char*)__ptr(mb->cmdline));
168 bhctx_ex = align_addr(bhctx_ex);
171 /* Parse sys modules */
172 if ((mb->flags & MULTIBOOT_INFO_MODS)) {
173 bhctx_ex += mb_parse_mods(bhctx, mb, (void*)bhctx_ex);
174 bhctx_ex = align_addr(bhctx_ex);
177 check_buffer(bhctx_ex);
179 bhctx->prepare = mb_prepare_hook;
180 bhctx->release = mb_release_hook;