diff options
| author | Ada Christine <adachristine18@gmail.com> | 2025-01-23 00:24:57 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2025-01-23 00:24:57 +0000 |
| commit | d855c0a219a180497c2e50f9bc19bfce69b937a6 (patch) | |
| tree | 1ff8523d41b222fb356fb3404d2a53c26a7d6a3d /boot/efi | |
| parent | edd52bd1464ee9ae4f0cdf7ff90a20ca175580fe (diff) | |
it printfs with the efi interface
Diffstat (limited to 'boot/efi')
| -rw-r--r-- | boot/efi/bind.c | 52 | ||||
| -rw-r--r-- | boot/efi/fexecve.c | 23 | ||||
| -rw-r--r-- | boot/efi/file.c | 2 | ||||
| -rw-r--r-- | boot/efi/handle.h | 19 | ||||
| -rw-r--r-- | boot/efi/image.c | 105 | ||||
| -rw-r--r-- | boot/efi/start.c | 18 | ||||
| -rw-r--r-- | boot/efi/status.h | 110 | ||||
| -rw-r--r-- | boot/efi/system_table.h | 31 | ||||
| -rw-r--r-- | boot/efi/table.h | 26 |
9 files changed, 304 insertions, 82 deletions
diff --git a/boot/efi/bind.c b/boot/efi/bind.c new file mode 100644 index 0000000..53522a5 --- /dev/null +++ b/boot/efi/bind.c @@ -0,0 +1,52 @@ +#include "kjarna_efi.h" + +int open(const char *path, int flags, int mode) +{ + return efi_open(path, flags, mode); +} + +int close(int fd) +{ + return efi_close(fd); +} + +off_t lseek(int fd, off_t offset, int whence) +{ + return efi_lseek(fd, offset, whence); +} + +ssize_t read(int fd, void *buffer, size_t length) +{ + return efi_read(fd, buffer, length); +} + +ssize_t write(int fd, const void *buffer, size_t length) +{ + return efi_write(fd, buffer, length); +} + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) +{ + return efi_mmap(addr, length, prot, flags, fd, offset); +} + +int munmap(void *addr, size_t length) +{ + return efi_munmap(addr, length); +} + +void *malloc(size_t size) +{ + return efi_alloc_pool(size); +} + +void *calloc(size_t count, size_t size) +{ + return efi_calloc_pool(count, size); +} + +void free(void *block) +{ + efi_free_pool(block); +} + diff --git a/boot/efi/fexecve.c b/boot/efi/fexecve.c new file mode 100644 index 0000000..57cb035 --- /dev/null +++ b/boot/efi/fexecve.c @@ -0,0 +1,23 @@ +#include <posix/unistd.h> +#include <api/elf/elf64.h> + +int fexecve(int fd, char *const argv[] char *const envp[]) +{ + (void)argv; + (void)envp; + + if (!elf64_validate_fd(fd, ET_DYN, EM_X86_64)) + { + return -1; + } + + size_t memsz; + + if ((memsz = elf64_size_fd(fd)) == 0) + { + return -1; + } + + +} + diff --git a/boot/efi/file.c b/boot/efi/file.c index 9178654..e45ce78 100644 --- a/boot/efi/file.c +++ b/boot/efi/file.c @@ -78,7 +78,7 @@ int efi_open(const char *path, int flags, int mode) { static EFI_GUID lip_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; static EFI_GUID sfsp_guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; - + EFI_LOADED_IMAGE_PROTOCOL *lip = efi_get_protocol(efi_context->handle, &lip_guid); if (lip == nullptr) diff --git a/boot/efi/handle.h b/boot/efi/handle.h new file mode 100644 index 0000000..1381a30 --- /dev/null +++ b/boot/efi/handle.h @@ -0,0 +1,19 @@ +#pragma once + +extern "C" +{ + struct efi_handle + { + void *m_Value; + }; +} + +namespace Efi +{ + class Handle : private efi_handle + { + public: + Handle(efi_handle &); + }; +} + diff --git a/boot/efi/image.c b/boot/efi/image.c index 42dab7d..25e1911 100644 --- a/boot/efi/image.c +++ b/boot/efi/image.c @@ -2,7 +2,11 @@ #include <posix/fcntl.h> #include <kjarna/interface.h> #include <libc/string.h> +#include <libc/stdio.h> +#include <libc/stdlib.h> #include <lib/elf.h> +#include <posix/unistd.h> +#include <posix/sys/mman.h> #include "kjarna_efi.h" @@ -16,77 +20,26 @@ struct image_buffer size_t length; }; -static ssize_t read_ehdr(int fd, Elf64_Ehdr *ehdr) +static int create_image_buffer(int fd, struct image_buffer *buffer) { - ssize_t result; - - if (efi_lseek(fd, 0, SEEK_SET) == -1) - { - return -1; - } - else if ((result = efi_read(fd, ehdr, sizeof(*ehdr))) == -1) + if ((buffer->length = elf64_size_fd(fd)) == 0) { return -1; } - else if (!elf64_validate(ehdr, ET_DYN, EM_X86_64)) - { - return -1; - } - - return result; -} -static ssize_t read_phdrs(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs) -{ - if (efi_lseek(fd, ehdr->e_phoff, SEEK_SET) != -1) - { - return efi_read(fd, phdrs, ehdr->e_phnum * ehdr->e_phentsize); - } - - return -1; -} - -static void create_image_buffer(Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs, struct image_buffer *buffer) -{ - buffer->length = elf64_size(ehdr, phdrs); - buffer->base = efi_mmap(nullptr, buffer->length, 0, 0, -1, 0); -} + printf("creating image buffer, %d bytes\n", buffer->length); -static ssize_t load_segment(int fd, Elf64_Phdr *phdr, char *buffer) -{ - if (efi_lseek(fd, phdr->p_offset, SEEK_SET) == -1) + if((buffer->base = mmap(nullptr, buffer->length, 0, 0, -1, 0)) == MAP_FAILED) { + buffer->length = 0; + buffer->base = nullptr; + return -1; } - int result = efi_read(fd, &buffer[phdr->p_offset], phdr->p_filesz); + printf("image buffer base %p\n", buffer->base); - if (result > 0 && phdr->p_memsz > phdr->p_filesz) - { - memset(&buffer[phdr->p_offset + phdr->p_filesz], 0, phdr->p_memsz - phdr->p_filesz); - } - - return result; -} - -static ssize_t load_segments(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs, char *buffer) -{ - int i; - - for (i = 0; i < ehdr->e_phnum; i++) - { - if (phdrs[i].p_type != PT_LOAD) - { - continue; - } - - if (load_segment(fd, &phdrs[i], buffer) == -1) - { - return -1; - } - } - - return i; + return 0; } static struct image_buffer load_image(void) @@ -97,37 +50,29 @@ static struct image_buffer load_image(void) struct image_buffer buffer = { nullptr, 0 }; - if ((image_fd = efi_open(image_entry_path, O_RDONLY, 0)) == -1) + if ((image_fd = open(image_entry_path, O_RDONLY, 0)) == -1) { return buffer; } - Elf64_Ehdr ehdr; - - if (read_ehdr(image_fd, &ehdr) == -1) + if (!elf64_validate_fd(image_fd, ET_DYN, EM_X86_64)) { return buffer; } - - Elf64_Phdr *phdrs = efi_calloc_pool(ehdr.e_phnum, ehdr.e_phentsize); - - if (phdrs == nullptr) + + if (create_image_buffer(image_fd, &buffer) < 0) { return buffer; } - else if(read_phdrs(image_fd, &ehdr, phdrs) != -1) - { - create_image_buffer(&ehdr, phdrs, &buffer); - } - if (buffer.base != nullptr && load_segments(image_fd, &ehdr, phdrs, buffer.base) == -1) + if (buffer.base != nullptr && elf64_load_segments(image_fd, buffer.length, buffer.base) < 0) { - efi_munmap(buffer.base, buffer.length); + printf("error detected: buffer {base: %p, length: %zu}\n", buffer.base, buffer.length); + munmap(buffer.base, buffer.length); buffer.base = nullptr; } - efi_close(image_fd); - efi_free_pool(phdrs); + close(image_fd); return buffer; } @@ -179,17 +124,17 @@ int image_start(void) image_entry(¶ms); } - if (efi_munmap(buffer.base, buffer.length) == -1) + if (munmap(buffer.base, buffer.length) == -1) { - efi_write(STDOUT_FILENO, "failed unmap\r\n", -1); + write(STDOUT_FILENO, "failed unmap\r\n", -1); if (efi_errno == EFI_NOT_FOUND) { - efi_write(STDOUT_FILENO, "not found\r\n", -1); + write(STDOUT_FILENO, "not found\r\n", -1); } else { - efi_write(STDOUT_FILENO, "bad alignment?\r\n", -1); + write(STDOUT_FILENO, "bad alignment?\r\n", -1); } } diff --git a/boot/efi/start.c b/boot/efi/start.c index 8ef8cbe..f1f4ec7 100644 --- a/boot/efi/start.c +++ b/boot/efi/start.c @@ -4,6 +4,9 @@ #include <efi/tables.h> #include "../kjarna.h" +#include "../config.h" + +#include <libc/stdio.h> #include "kjarna_efi.h" struct efi_context const *efi_context; @@ -21,12 +24,25 @@ EFI_STATUS _start(EFI_HANDLE handle, EFI_SYSTEM_TABLE *system_table) system_table->ConOut->ClearScreen(system_table->ConOut); +#ifdef DEBUG_WAIT + EFI_GUID lip_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; + EFI_LOADED_IMAGE_PROTOCOL *lip = efi_get_protocol(efi_context->handle, &lip_guid); + + printf("DEBUG: EFI_LOADED_IMAGE_PROTOCOL { .ImageBase = %p }\n", lip->ImageBase); + __asm__ volatile ("movq %0, %%rax" :: "r"(lip->ImageBase) : "rax"); + bool wait = true; + + while(wait) + { + __asm__ ("hlt"); + } +#endif + if (main(0, nullptr) != 0) { efi_errno = EFI_ABORTED; } - return _exit(efi_errno); } diff --git a/boot/efi/status.h b/boot/efi/status.h new file mode 100644 index 0000000..bcb6b96 --- /dev/null +++ b/boot/efi/status.h @@ -0,0 +1,110 @@ +#pragma once + +#include <cstddef> +#include <limits> +#include <type_traits> + +namespace Efi +{ + class Status + { + using size_t = std::size_t; + using ssize_t = std::make_signed_t<size_t>; + + size_t m_Value; + + constexpr Status(size_t value) + : m_Value(value) + { + } + + constexpr bool IsError() const + { + return static_cast<ssize_t>(m_Value) < 0; + } + + constexpr bool IsWarning() const + { + return m_Value > 0; + } + + constexpr bool IsSuccess() const + { + return m_Value == 0; + } + + constexpr static Status ErrorStatus(size_t code) + { + auto errorBit = std::numeric_limits<ssize_t>::min(); + return Status(static_cast<size_t>(errorBit) | code); + } + + constexpr static Status WarningStatus(size_t code) + { + return Status(code); + } + + public: + + operator size_t() const + { + return m_Value; + } + + static const Status Success; + + class Warning + { + public: + + static const Status UnknownGlyph; + static const Status DeleteFailure; + static const Status WriteFailure; + static const Status BufferTooSmall; + static const Status StaleData; + static const Status FileSystem; + static const Status ResetRequired; + }; + + class Error + { + public: + + static const Status LoadError; + static const Status InvalidParameter; + static const Status Unsupported; + static const Status BadBufferSize; + static const Status BufferTooSmall; + static const Status NotReady; + static const Status DeviceError; + static const Status WriteProtected; + static const Status OutOfResources; + static const Status VolumeCorrupted; + static const Status VolumeFull; + static const Status NoMedia; + static const Status MediaChanged; + static const Status NotFound; + static const Status AccessDenied; + static const Status NoResponse; + static const Status NoMapping; + static const Status Timeout; + static const Status NotStarted; + static const Status AlreadyStarted; + static const Status Aborted; + static const Status IcmpError; + static const Status TftpError; + static const Status ProtocolError; + static const Status IncompatibleVersion; + static const Status SecurityViolation; + static const Status CrcError; + static const Status EndOfMedia; + static const Status EndOfFile; + static const Status InvalidLanguage; + static const Status CompromisedData; + static const Status IpAddressConflict; + static const Status HttpError; + }; + + }; +} + diff --git a/boot/efi/system_table.h b/boot/efi/system_table.h new file mode 100644 index 0000000..93e839d --- /dev/null +++ b/boot/efi/system_table.h @@ -0,0 +1,31 @@ +#pragma once + +#include "table.h" + +extern "C" +{ + struct efi_system_table + { + void *m_Value; + }; +} + +namespace Efi +{ + class SystemTable : private Table + { + char16_t *m_FirmwareVendor; + uint32_t m_FirmwareRevision; + Handle m_ConsoleInHandle; + void *m_ConIn; + Handle m_ConsoleOutHandle; + void *m_ConOut; + Handle m_StandardErrorHandle; + void *m_StdErr; + void *m_RuntimeServices; + void *m_BootServices; + size_t m_NumberOfTableEntries; + void *m_ConfigurationTable; + }; +} + diff --git a/boot/efi/table.h b/boot/efi/table.h new file mode 100644 index 0000000..660bd1e --- /dev/null +++ b/boot/efi/table.h @@ -0,0 +1,26 @@ +#pragma once + +#include <cstddef> +#include <cstdint> + +namespace Efi +{ + class TableHeader + { + using uint64_t = std::uint64_t; + using uint32_t = std::uint32_t; + using size_t = std::size_t; + + uint64_t m_Signature; + uint32_t m_Revision; + uint32_t m_HeaderSize; + uint32_t m_Crc32; + uint32_t m_Reserved; + }; + + class Table + { + TableHeader m_Header; + }; +} + |
