#include #include #include #include #include #include #include #include #include #include "kjarna_efi.h" #include "config.h" #include static int create_image_buffer(int fd, struct image_buffer *buffer) { if ((buffer->length = elf64_size_fd(fd)) == 0) { return -1; } printf("creating image buffer, %d bytes\n", buffer->length); if((buffer->base = mmap(nullptr, buffer->length, 0, 0, -1, 0)) == MAP_FAILED) { buffer->length = 0; buffer->base = nullptr; return -1; } printf("image buffer base %p\n", buffer->base); return 0; } static struct image_buffer load_image(void) { const char *image_entry_path = SERVICE_FILE_PATH; int image_fd; struct image_buffer buffer = { nullptr, 0 }; if ((image_fd = open(image_entry_path, O_RDONLY, 0)) == -1) { return buffer; } if (!elf64_validate_fd(image_fd, ET_DYN, EM_X86_64)) { return buffer; } if (create_image_buffer(image_fd, &buffer) < 0) { return buffer; } if (buffer.base != nullptr && elf64_load_segments(image_fd, buffer.length, buffer.base) < 0) { printf("error detected: buffer {base: %p, length: %zu}\n", buffer.base, buffer.length); munmap(buffer.base, buffer.length); buffer.base = nullptr; } close(image_fd); return buffer; } kjarna_image_entry_func *image_entry_addr(struct image_buffer *buffer) { if (buffer->base == nullptr) { return nullptr; } Elf64_Ehdr *ehdr = (Elf64_Ehdr *)buffer->base; return (kjarna_image_entry_func *)(buffer->base + ehdr->e_entry); } struct kjarna_interface get_boot_interface(void) { struct kjarna_interface result = { efi_open, efi_close, efi_lseek, efi_read, efi_write, efi_mmap, efi_munmap }; return result; } struct kjarna_boot_image get_boot_image(void) { struct kjarna_boot_image image = { { nullptr, 0 }, nullptr }; image.buffer = load_image(); if (image.buffer.base != nullptr) { image.entry = image_entry_addr(&image.buffer); } return image; } int image_start(void) { struct kjarna_interface interface = get_boot_interface(); struct kjarna_entry_params params = { &interface, 0, nullptr, nullptr }; struct kjarna_boot_image image = get_boot_image(); if (image.buffer.base != nullptr) { image.entry = image_entry_addr(&image.buffer); } if (image.entry != nullptr) { image.entry(¶ms); } if (munmap(image.buffer.base, image.buffer.length) == -1) { write(STDOUT_FILENO, "failed unmap\r\n", -1); if (efi_errno == EFI_NOT_FOUND) { write(STDOUT_FILENO, "not found\r\n", -1); } else { write(STDOUT_FILENO, "bad alignment?\r\n", -1); } } return -1; }