diff --git a/src/booboot/file.c b/src/booboot/file.c index fd232ec..ee90b2f 100644 --- a/src/booboot/file.c +++ b/src/booboot/file.c @@ -60,17 +60,21 @@ EfiFp *_Nonnull efi_rootdir(void) return _rootdir; } -char *_Nonnull efi_read_file(uint16_t *_Nonnull path, size_t *_Nullable len) +char *_Nonnull efi_read_file(char const *_Nonnull path, size_t *_Nullable len) { EfiFp *file; + uint16_t lpath[256] = {0}; + for (size_t i = 0; i < strlen(path); i++) + { + lpath[i] = path[i]; + } EfiStatus status = - efi_rootdir()->open(efi_rootdir(), &file, path, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); + efi_rootdir()->open(efi_rootdir(), &file, lpath, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); if (status != EFI_SUCCESS) { - error$("failed to open file: "); - efi_console_write(path); + error$("failed to open file: %s", path); for (;;) { __asm__("hlt"); diff --git a/src/booboot/file.h b/src/booboot/file.h index 3b2856b..2953704 100644 --- a/src/booboot/file.h +++ b/src/booboot/file.h @@ -9,4 +9,4 @@ EfiSfsp *_Nonnull efi_rootfs(void); EfiFp *_Nonnull efi_rootdir(void); -char *_Nonnull efi_read_file(uint16_t *_Nonnull path, size_t *_Nullable len); \ No newline at end of file +char *_Nonnull efi_read_file(char const *_Nonnull path, size_t *_Nullable len); \ No newline at end of file diff --git a/src/booboot/handover.c b/src/booboot/handover.c index 7803939..457b705 100644 --- a/src/booboot/handover.c +++ b/src/booboot/handover.c @@ -2,8 +2,10 @@ #include #include +#include #include "config.h" +#include "file.h" #include "handover.h" #include "loader.h" #include "mem.h" @@ -143,12 +145,79 @@ void handover_apply(uintptr_t entry, uintptr_t stack) (HandoverRecord){ .tag = HANDOVER_CMDLINE, .flags = 0, - .start = handover_add_string(handover, selected_entry().cmdline), + .start = (uintptr_t)selected_entry().cmdline, .size = strlen(selected_entry().cmdline) + 1, }); break; } + case HANDOVER_FB: + { + EfiGuid guid = EFI_GOP_GUID; + EfiGop *gop; + size_t infoSize; + EfiGopModeInfo *info; + + efi_assert_success(efi_st()->boot_services->locate_protocol(&guid, NULL, (void **)&gop)); + efi_assert_success(gop->query_mode(gop, gop->mode->max_mode - 1, &infoSize, &info)); + efi_assert_success(gop->set_mode(gop, gop->mode->max_mode - 1)); + + debug$("setting GOP mode to %dx%d", info->horizontal_resolution, info->vertical_resolution); + + handover_insert( + handover, + handover->count, + (HandoverRecord){ + .tag = HANDOVER_FB, + .flags = 0, + .start = gop->mode->framebuffer_base, + .size = gop->mode->framebuffer_size, + .fb = { + .width = gop->mode->info->horizontal_resolution, + .height = gop->mode->info->vertical_resolution, + .pitch = gop->mode->info->pixels_per_scan_line * sizeof(uint32_t), + .format = HANDOVER_BGRX8888, + }}); + + break; + } + case HANDOVER_FILE: + { + size_t length; + for (size_t i = 0; i < selected_entry().modules.len; i++) + { + debug$("loading module %s", selected_entry().modules.buf[i].string); + char const *content = efi_read_file(selected_entry().modules.buf[i].string, &length); + handover_append( + handover, + (HandoverRecord){ + .tag = HANDOVER_FILE, + .flags = 0, + .start = (uintptr_t)content, + .size = length, + .file = { + .name = handover_add_string(handover, selected_entry().modules.buf[i].string), + }, + }); + } + + break; + } + + case HANDOVER_RSDP: + { + handover_append( + handover, + (HandoverRecord){ + .tag = HANDOVER_RSDP, + .flags = 0, + .start = uefi_find_rsdp(), + .size = 0x1000, + }); + + break; + } + default: { error$("unsupported request %s", handover_tag_name(reqs[i].tag)); diff --git a/src/booboot/loader.c b/src/booboot/loader.c index 7fb1d85..5de1708 100644 --- a/src/booboot/loader.c +++ b/src/booboot/loader.c @@ -11,13 +11,7 @@ size_t _ehdr_size = 0; uintptr_t load_binary(char const *_Nonnull path) { - uint16_t lpath[256] = {0}; - for (size_t i = 0; i < strlen(path); i++) - { - lpath[i] = path[i]; - } - - char *_Nonnull hdr = efi_read_file(lpath, &_ehdr_size); + char *_Nonnull hdr = efi_read_file(path, &_ehdr_size); _ehdr = hdr; char magic[4] = {hdr[EI_MAG0], hdr[EI_MAG1], hdr[EI_MAG2], hdr[EI_MAG3]}; diff --git a/src/booboot/main.c b/src/booboot/main.c index a48a42a..82da5f4 100644 --- a/src/booboot/main.c +++ b/src/booboot/main.c @@ -40,7 +40,7 @@ EfiStatus efi_main(EfiHandle handle, EfiSystemTable *st) info$("booting from Booboot..."); - char *_Nonnull cfg = efi_read_file(L"loader.json", NULL); + char *_Nonnull cfg = efi_read_file("loader.json", NULL); efi_assert_success(config_parse(cfg)); menu(); diff --git a/src/booboot/protocols.h b/src/booboot/protocols.h index f84c66f..8ba00f5 100644 --- a/src/booboot/protocols.h +++ b/src/booboot/protocols.h @@ -2,4 +2,11 @@ #include +typedef struct +{ + uint64_t width; + uint64_t height; + uint64_t bpp; +} Resolution; + uintptr_t apply_protocol(char const *_Nonnull protocol_name, uintptr_t entry, uintptr_t stack); \ No newline at end of file diff --git a/src/booboot/utils.c b/src/booboot/utils.c new file mode 100644 index 0000000..9144d15 --- /dev/null +++ b/src/booboot/utils.c @@ -0,0 +1,27 @@ +#include +#include +#include + +uintptr_t uefi_find_rsdp(void) +{ + EfiGuid acpi = ACPI_TABLE_GUID; + EfiGuid acpi2 = ACPI2_TABLE_GUID; + void *acpi_table = NULL; + + for (size_t i = 0; i < efi_st()->num_table_entries; i++) + { + if (memcmp(&efi_st()->config_table[i].vendor_guid, &acpi, sizeof(EfiGuid)) == 0) + { + acpi_table = efi_st()->config_table[i].vendor_table; + break; + } + else if (memcmp(&efi_st()->config_table[i].vendor_guid, &acpi2, sizeof(EfiGuid)) == 0) + { + acpi_table = efi_st()->config_table[i].vendor_table; + break; + } + } + + debug$("ACPI table at %p", acpi_table); + return (uintptr_t)acpi_table; +} \ No newline at end of file diff --git a/src/booboot/utils.h b/src/booboot/utils.h index b852601..3be767b 100644 --- a/src/booboot/utils.h +++ b/src/booboot/utils.h @@ -23,3 +23,5 @@ #define align_up$(x, align) (((x) + (align) - 1) & ~((align) - 1)) #define align_down$(x, align) ((x) & ~((align) - 1)) + +uintptr_t uefi_find_rsdp(void); \ No newline at end of file