diff options
Diffstat (limited to 'kernel/mboot')
| -rw-r--r-- | kernel/mboot/elf.c | 77 | ||||
| -rw-r--r-- | kernel/mboot/mboot.c | 7 | ||||
| -rw-r--r-- | kernel/mboot/mmap.c | 17 |
3 files changed, 83 insertions, 18 deletions
diff --git a/kernel/mboot/elf.c b/kernel/mboot/elf.c new file mode 100644 index 0000000..88b61a7 --- /dev/null +++ b/kernel/mboot/elf.c @@ -0,0 +1,77 @@ +#include "lib/kio.h" +#include <lib.h> +#include <elf.h> +#include <comus/mboot.h> + +#include "mboot.h" + +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 + +struct multiboot_tag_elf_sections { + uint32_t type; + uint32_t size; + uint32_t num; + uint32_t entsize; + uint32_t shndx; + Elf64_Shdr sections[]; +}; + +static struct multiboot_tag_elf_sections *elf = NULL; +static Elf64_Shdr *symtab = NULL; +static Elf64_Shdr *symstrtab = NULL; + +static Elf64_Shdr *mboot_get_elf_sec(uint32_t sh_type) +{ + for (uint32_t i = 0; i < elf->num; i++) { + Elf64_Shdr *ent = &elf->sections[i]; + if (ent->sh_type == sh_type) + return ent; + } + + return NULL; +} + +static int mboot_load_elf(void) +{ + void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_ELF_SECTIONS); + if (tag == NULL) + return 1; + + // found elf sections + elf = (struct multiboot_tag_elf_sections *)tag; + + // load symtab + if ((symtab = mboot_get_elf_sec(SHT_SYMTAB)) == NULL) + return 1; + + // load strsymtab + if ((symstrtab = mboot_get_elf_sec(symtab->sh_link)) == NULL) + return 1; + + return 0; +} + +const char *mboot_get_elf_sym(uint64_t addr) +{ + if (symstrtab == NULL) + if (mboot_load_elf()) + return NULL; + + // walk symbol table + Elf64_Sym *syms = (Elf64_Sym *)symtab->sh_addr; + Elf64_Sym *best = NULL; + for (uint32_t i = 0; i < symtab->sh_size / symtab->sh_entsize; i++) { + Elf64_Sym *sym = &syms[i]; + if (sym->st_value < addr) + continue; + if (best == NULL || (best->st_value < sym->st_value)) + best = sym; + } + + if (best != NULL) { + char *buf = (char *)symstrtab->sh_addr; + return &buf[best->st_name]; + } + + return "???"; +} diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c index e10f33c..949337d 100644 --- a/kernel/mboot/mboot.c +++ b/kernel/mboot/mboot.c @@ -3,7 +3,7 @@ #include "mboot.h" -static volatile void *mboot; +static volatile void *mboot = NULL; void mboot_init(long magic, volatile void *ptr) { @@ -14,9 +14,12 @@ void mboot_init(long magic, volatile void *ptr) void *locate_mboot_table(uint32_t type) { + if (mboot == NULL) + return NULL; + struct multiboot *info = (struct multiboot *)mboot; - const char *mboot_end = ((char *)info) + info->total_size; + const char *mboot_end = ((char *)info) + info->total_size; char *tag_ptr = info->tags; while (tag_ptr < mboot_end) { diff --git a/kernel/mboot/mmap.c b/kernel/mboot/mmap.c index e93421d..e0963ca 100644 --- a/kernel/mboot/mmap.c +++ b/kernel/mboot/mmap.c @@ -20,11 +20,6 @@ struct multiboot_tag_mmap { struct multiboot_mmap_entry entries[]; }; -static const char *segment_type[] = { "Reserved", "Free", - "Reserved", "ACPI Reserved", - "Hibernation", "Defective", - "Unknown" }; - int mboot_get_mmap(struct memory_map *res) { void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MMAP); @@ -35,22 +30,12 @@ int mboot_get_mmap(struct memory_map *res) int idx = 0; uintptr_t i = (uintptr_t)mmap->entries; - kprintf("MEMORY MAP\n"); - char buf[20]; for (; i < (uintptr_t)mmap->entries + mmap->size; i += mmap->entry_size, idx++) { struct multiboot_mmap_entry *seg = (struct multiboot_mmap_entry *)i; - const char *type = NULL; - if (seg->type > 6) - type = segment_type[6]; - else - type = segment_type[seg->type]; - kprintf("ADDR: %16p LEN: %4s TYPE: %s (%d)\n", (void *)seg->addr, - btoa(seg->len, buf), type, seg->type); - if (seg->type != 1 || seg->len < 1) - continue; res->entries[idx].addr = seg->addr; res->entries[idx].len = seg->len; + res->entries[idx].type = seg->type; } res->entry_count = idx; |