aos/kernel/arch/armv8/kernel_multiboot2.c
Daniel Schwyn 6d444bf552 Main handout
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
2022-03-03 14:57:51 +01:00

120 lines
4.3 KiB
C

/*
* Copyright (c) 2016, Hewlett Packard Enterprise Development LP.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <multiboot2.h>
#include <arch/armv8/kernel_multiboot2.h>
// Dump the Multiboot2 structure
void multiboot2_dump(struct multiboot_tag *first_tag,
const size_t size)
{
size_t processed = 0;
char description[256];
printf("%s: %p:%ld\n", __func__, first_tag, size);
while (processed < size) {
switch (first_tag->type) {
case MULTIBOOT_TAG_TYPE_CMDLINE: {
snprintf(description, sizeof(description), "CMDLINE: [%s]",
((struct multiboot_tag_string *)first_tag)->string);
} break;
case MULTIBOOT_TAG_TYPE_EFI64: {
snprintf(description, sizeof(description), "EFI64: pointer=%lx",
((struct multiboot_tag_efi64 *)first_tag)->pointer);
} break;
case MULTIBOOT_TAG_TYPE_ACPI_NEW: {
snprintf(description, sizeof(description), "ACPI new:");
} break;
case MULTIBOOT_TAG_TYPE_EFI_MMAP: {
snprintf(description, sizeof(description), "EFI MMAP: size=%d version=%d",
((struct multiboot_tag_efi_mmap *)first_tag)->descr_size,
((struct multiboot_tag_efi_mmap *)first_tag)->descr_vers);
} break;
case MULTIBOOT_TAG_TYPE_MODULE_64: {
snprintf(description, sizeof(description), "MODULE 64: mod_start=%lx mod_end=%lx cmdline=[%s]",
((struct multiboot_tag_module_64 *)first_tag)->mod_start,
((struct multiboot_tag_module_64 *)first_tag)->mod_end,
((struct multiboot_tag_module_64 *)first_tag)->cmdline);
} break;
case MULTIBOOT_TAG_TYPE_END: {
snprintf(description, sizeof(description), "END");
} break;
default: {
snprintf(description, sizeof(description), "[%d]", first_tag->type);
} break;
}
printf("%p:%4ld: tag %d:%d %s\n", first_tag, processed, first_tag->type, first_tag->size, description);
if (first_tag->type == MULTIBOOT_TAG_TYPE_END)
break;
processed += first_tag->size;
first_tag = (void *)first_tag + first_tag->size;
}
}
struct multiboot_tag * multiboot2_find_tag(struct multiboot_tag *first_tag,
const size_t size, const multiboot_uint16_t type)
{
size_t processed = 0;
while (processed < size) {
/* encountered the end tag */
if (first_tag->type == MULTIBOOT_TAG_TYPE_END) {
return NULL;
} else if (first_tag->type == type) {
return first_tag;
}
processed += first_tag->size;
first_tag = (void *)first_tag + first_tag->size;
}
return NULL;
}
struct multiboot_tag_string * multiboot2_find_cmdline(
struct multiboot_tag *first_tag, const size_t size)
{
return (struct multiboot_tag_string *)multiboot2_find_tag(first_tag, size,
MULTIBOOT_TAG_TYPE_CMDLINE);
}
struct multiboot_tag_module_64 * multiboot2_find_module_64(
struct multiboot_tag *first_tag, const size_t size, const char *pathname)
{
size_t len = strlen(pathname);
size_t position = 0;
struct multiboot_tag *tag;
tag = multiboot2_find_tag(first_tag, size, MULTIBOOT_TAG_TYPE_MODULE_64);
while (tag) {
struct multiboot_tag_module_64 *module_64 = (struct multiboot_tag_module_64 *)tag;
// Strip off trailing whitespace
char *modname = module_64->cmdline;
char *endstr;
endstr = strchr(modname, ' ');
if (!endstr) {
endstr = modname + strlen(modname);
}
if(!strncmp(endstr - len, pathname, len)) {
return module_64;
}
tag = (void *)tag + tag->size;
position += tag->size;
tag = multiboot2_find_tag(tag, size - position, MULTIBOOT_TAG_TYPE_MODULE_64);
}
return NULL;
}