multiboot2: Add mb2_alloc() for quirky allocation locations
This commit is contained in:
parent
382e8d1711
commit
89466b9125
@ -308,22 +308,7 @@ struct elf_section_hdr_info* elf64_section_hdr_info(uint8_t *elf) {
|
|||||||
info->section_entry_size = hdr.shdr_size;
|
info->section_entry_size = hdr.shdr_size;
|
||||||
info->section_hdr_size = info->num * info->section_entry_size;
|
info->section_hdr_size = info->num * info->section_entry_size;
|
||||||
info->str_section_idx = hdr.shstrndx;
|
info->str_section_idx = hdr.shstrndx;
|
||||||
info->section_hdrs = ext_mem_alloc(info->section_hdr_size);
|
info->section_offset = hdr.shoff;
|
||||||
|
|
||||||
memcpy(info->section_hdrs, elf + (hdr.shoff), info->section_hdr_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < info->num; i++) {
|
|
||||||
struct elf64_shdr *shdr = info->section_hdrs + i * hdr.shdr_size;
|
|
||||||
|
|
||||||
if (shdr->sh_addr != 0 || shdr->sh_size == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *section = conv_mem_alloc(shdr->sh_size);
|
|
||||||
memcpy(section, elf + shdr->sh_offset, shdr->sh_size);
|
|
||||||
|
|
||||||
shdr->sh_addr = (uintptr_t)section;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -340,22 +325,7 @@ struct elf_section_hdr_info* elf32_section_hdr_info(uint8_t *elf) {
|
|||||||
info->section_entry_size = hdr.shdr_size;
|
info->section_entry_size = hdr.shdr_size;
|
||||||
info->section_hdr_size = info->num * info->section_entry_size;
|
info->section_hdr_size = info->num * info->section_entry_size;
|
||||||
info->str_section_idx = hdr.shstrndx;
|
info->str_section_idx = hdr.shstrndx;
|
||||||
info->section_hdrs = ext_mem_alloc(info->section_hdr_size);
|
info->section_offset = hdr.shoff;
|
||||||
|
|
||||||
memcpy(info->section_hdrs, elf + (hdr.shoff), info->section_hdr_size);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < info->num; i++) {
|
|
||||||
struct elf32_shdr *shdr = info->section_hdrs + i * hdr.shdr_size;
|
|
||||||
|
|
||||||
if (shdr->sh_addr != 0 || shdr->sh_size == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *section = conv_mem_alloc(shdr->sh_size);
|
|
||||||
memcpy(section, elf + shdr->sh_offset, shdr->sh_size);
|
|
||||||
|
|
||||||
shdr->sh_addr = (uintptr_t)section;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ struct elf_section_hdr_info {
|
|||||||
uint32_t section_entry_size;
|
uint32_t section_entry_size;
|
||||||
uint32_t str_section_idx;
|
uint32_t str_section_idx;
|
||||||
uint32_t num;
|
uint32_t num;
|
||||||
void* section_hdrs;
|
uint32_t section_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
int elf_bits(uint8_t *elf);
|
int elf_bits(uint8_t *elf);
|
||||||
|
@ -55,6 +55,20 @@ static size_t get_multiboot2_info_size(
|
|||||||
|
|
||||||
#define append_tag(P, TAG) ({ (P) += ALIGN_UP((TAG)->size, MULTIBOOT_TAG_ALIGN); })
|
#define append_tag(P, TAG) ({ (P) += ALIGN_UP((TAG)->size, MULTIBOOT_TAG_ALIGN); })
|
||||||
|
|
||||||
|
static uint32_t kernel_top;
|
||||||
|
|
||||||
|
static void *mb2_alloc(size_t size) {
|
||||||
|
void *ret = (void *)(uintptr_t)ALIGN_UP(kernel_top, 4096);
|
||||||
|
|
||||||
|
while (!memmap_alloc_range((uintptr_t)ret, size, MEMMAP_KERNEL_AND_MODULES,
|
||||||
|
true, false, false, false)) {
|
||||||
|
ret += 0x200000;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_top = (uintptr_t)ret + size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool multiboot2_load(char *config, char* cmdline) {
|
bool multiboot2_load(char *config, char* cmdline) {
|
||||||
struct file_handle *kernel_file;
|
struct file_handle *kernel_file;
|
||||||
|
|
||||||
@ -175,8 +189,6 @@ bool multiboot2_load(char *config, char* cmdline) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t kernel_top;
|
|
||||||
|
|
||||||
if (addresstag != NULL) {
|
if (addresstag != NULL) {
|
||||||
if (addresstag->load_addr > addresstag->header_addr)
|
if (addresstag->load_addr > addresstag->header_addr)
|
||||||
panic(true, "multiboot2: Illegal load address");
|
panic(true, "multiboot2: Illegal load address");
|
||||||
@ -284,6 +296,42 @@ bool multiboot2_load(char *config, char* cmdline) {
|
|||||||
struct multiboot2_start_tag *mbi_start = (struct multiboot2_start_tag *)mb2_info;
|
struct multiboot2_start_tag *mbi_start = (struct multiboot2_start_tag *)mb2_info;
|
||||||
info_idx += sizeof(struct multiboot2_start_tag);
|
info_idx += sizeof(struct multiboot2_start_tag);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
// Create ELF info tag
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
if (section_hdr_info == NULL) {
|
||||||
|
if (is_elf_info_requested) {
|
||||||
|
panic(true, "multiboot2: Cannot return ELF file information");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint32_t size = sizeof(struct multiboot_tag_elf_sections) + section_hdr_info->section_hdr_size;
|
||||||
|
struct multiboot_tag_elf_sections *tag = (struct multiboot_tag_elf_sections*)(mb2_info + info_idx);
|
||||||
|
|
||||||
|
tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS;
|
||||||
|
tag->size = size;
|
||||||
|
|
||||||
|
tag->num = section_hdr_info->num;
|
||||||
|
tag->entsize = section_hdr_info->section_entry_size;
|
||||||
|
tag->shndx = section_hdr_info->str_section_idx;
|
||||||
|
|
||||||
|
memcpy(tag->sections, kernel + section_hdr_info->section_offset, section_hdr_info->section_hdr_size);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < section_hdr_info->num; i++) {
|
||||||
|
struct elf64_shdr *shdr = (void *)kernel + section_hdr_info->section_offset + i * section_hdr_info->section_entry_size;
|
||||||
|
|
||||||
|
if (shdr->sh_addr != 0 || shdr->sh_size == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *section = mb2_alloc(shdr->sh_size);
|
||||||
|
memcpy(section, kernel + shdr->sh_offset, shdr->sh_size);
|
||||||
|
|
||||||
|
shdr->sh_addr = (uintptr_t)section;
|
||||||
|
}
|
||||||
|
|
||||||
|
append_tag(info_idx, tag);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
// Create modules tag
|
// Create modules tag
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
@ -298,19 +346,14 @@ bool multiboot2_load(char *config, char* cmdline) {
|
|||||||
if ((f = uri_open(module_path)) == NULL)
|
if ((f = uri_open(module_path)) == NULL)
|
||||||
panic(true, "multiboot2: Failed to open module with path `%s`. Is the path correct?", module_path);
|
panic(true, "multiboot2: Failed to open module with path `%s`. Is the path correct?", module_path);
|
||||||
|
|
||||||
void *module_addr = (void *)(uintptr_t)ALIGN_UP(kernel_top, 4096);
|
|
||||||
|
|
||||||
// Module commandline can be null, so we guard against that and make the
|
// Module commandline can be null, so we guard against that and make the
|
||||||
// string "".
|
// string "".
|
||||||
char *module_cmdline = conf_tuple.value2;
|
char *module_cmdline = conf_tuple.value2;
|
||||||
if (!module_cmdline) module_cmdline = "";
|
if (!module_cmdline) module_cmdline = "";
|
||||||
|
|
||||||
while (!memmap_alloc_range((uintptr_t)module_addr, f->size, MEMMAP_KERNEL_AND_MODULES,
|
void *module_addr = mb2_alloc(f->size);
|
||||||
true, false, false, false)) {
|
|
||||||
module_addr += 0x200000;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel_top = (uintptr_t)module_addr + f->size;
|
|
||||||
fread(f, module_addr, 0, f->size);
|
fread(f, module_addr, 0, f->size);
|
||||||
|
|
||||||
struct multiboot_tag_module *module_tag = (struct multiboot_tag_module *)(mb2_info + info_idx);
|
struct multiboot_tag_module *module_tag = (struct multiboot_tag_module *)(mb2_info + info_idx);
|
||||||
@ -548,30 +591,6 @@ bool multiboot2_load(char *config, char* cmdline) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Create ELF info tag
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
{
|
|
||||||
if (section_hdr_info == NULL) {
|
|
||||||
if (is_elf_info_requested) {
|
|
||||||
panic(true, "multiboot2: Cannot return ELF file information");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uint32_t size = sizeof(struct multiboot_tag_elf_sections) + section_hdr_info->section_hdr_size;
|
|
||||||
struct multiboot_tag_elf_sections *tag = (struct multiboot_tag_elf_sections*)(mb2_info + info_idx);
|
|
||||||
|
|
||||||
tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS;
|
|
||||||
tag->size = size;
|
|
||||||
|
|
||||||
tag->num = section_hdr_info->num;
|
|
||||||
tag->entsize = section_hdr_info->section_entry_size;
|
|
||||||
tag->shndx = section_hdr_info->str_section_idx;
|
|
||||||
|
|
||||||
memcpy(tag->sections, section_hdr_info->section_hdrs, section_hdr_info->section_hdr_size);
|
|
||||||
append_tag(info_idx, tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if uefi == 1
|
#if uefi == 1
|
||||||
efi_exit_boot_services();
|
efi_exit_boot_services();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user