diff options
| author | Ada Christine <adachristine18@gmail.com> | 2024-03-03 08:44:42 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2024-03-03 08:44:42 +0000 |
| commit | f61da8be06fdfebc598cba783e78117319231140 (patch) | |
| tree | 0ef21f89e98a985ab5d985aaac1e032c868e8b81 /kjarna/efi | |
| parent | 9681d6a6cbde12b00beab62683b8db98f680ba2b (diff) | |
build changes
Diffstat (limited to 'kjarna/efi')
| -rw-r--r-- | kjarna/efi/file.c | 274 | ||||
| -rw-r--r-- | kjarna/efi/image.c | 196 | ||||
| -rw-r--r-- | kjarna/efi/kjarna_efi.h | 37 | ||||
| -rw-r--r-- | kjarna/efi/memory.c | 83 | ||||
| -rw-r--r-- | kjarna/efi/protocol.c | 33 | ||||
| -rw-r--r-- | kjarna/efi/start.c | 32 |
6 files changed, 0 insertions, 655 deletions
diff --git a/kjarna/efi/file.c b/kjarna/efi/file.c deleted file mode 100644 index 517e09e..0000000 --- a/kjarna/efi/file.c +++ /dev/null @@ -1,274 +0,0 @@ -#include <efi/types.h> -#include <efi/error.h> -#include <efi/media.h> -#include <efi/tables.h> - -#include <posix/unistd.h> -#include <libc/stdlib.h> -#include <libc/string.h> - -#include "kjarna_efi.h" - -#define FD_COUNT 16 -#define FD_MIN 3 -#define FD_MAX (FD_MIN + FD_COUNT - 1) - -static EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *fd_to_outconsole(int fd) -{ - switch (fd) - { - case STDOUT_FILENO: - return efi_context->system_table->ConOut; - case STDERR_FILENO: - return efi_context->system_table->StdErr; - default: - return nullptr; - } -} - -static EFI_SIMPLE_TEXT_INPUT_PROTOCOL *fd_to_inconsole(int fd) -{ - return fd == STDIN_FILENO ? efi_context->system_table->ConIn : nullptr; -} - -static EFI_FILE_PROTOCOL *open_files[FD_COUNT]; - -static EFI_FILE_PROTOCOL *fd_to_file(int fd) -{ - if (fd < FD_MIN || fd > FD_MAX) - { - return nullptr; - } - - return open_files[fd]; -} - -static int alloc_fd(void) -{ - for (int i = 0; i < FD_COUNT; i++) - { - if (open_files[i] == nullptr) - { - return FD_MIN + i; - } - } - - return -1; -} - -static void free_fd(int fd) -{ - if (fd < FD_MIN || fd > FD_MAX) - { - open_files[fd] = nullptr; - } -} - -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) - { - return -1; - } - - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *sfsp = efi_get_protocol(lip->DeviceHandle, &sfsp_guid); - - if (sfsp == nullptr) - { - return -1; - } - - EFI_FILE_PROTOCOL *root = nullptr; - - efi_errno = sfsp->OpenVolume(sfsp, &root); - - if (root == nullptr) - { - return -1; - } - - int fd = alloc_fd(); - - if (fd < FD_MIN) - { - return -1; - } - - size_t path_len = strlen(path) + 1; - CHAR16 *wcpath = efi_calloc_pool(path_len, sizeof(*wcpath)); - - if (mbstowcs(wcpath, path, path_len) == (size_t)-1) - { - efi_errno = EFI_INVALID_PARAMETER; - } - else - { - efi_errno = root->Open( - root, - &open_files[fd], - wcpath, - EFI_FILE_MODE_READ, - 0); - } - - efi_close_protocol(lip->DeviceHandle, &lip_guid); - efi_close_protocol(efi_context->handle, &sfsp_guid); - efi_free_pool(wcpath); - - (void)flags; - (void)mode; - - return !EFI_ERROR(efi_errno) ? fd : -1; -} - -int efi_close(int fd) -{ - EFI_FILE_PROTOCOL *file = fd_to_file(fd); - - if (file == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - free_fd(fd); - - efi_errno = file->Close(file); - - return !EFI_ERROR(efi_errno) ? 0 : -1; -} - -off_t efi_lseek(int fd, off_t offset, int whence) -{ - EFI_FILE_PROTOCOL *file = fd_to_file(fd); - - if (file == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - off_t current = 0; - - if (whence == SEEK_END) - { - efi_errno = file->SetPosition(file, (UINTN)-1); - } - - if (EFI_ERROR(efi_errno)) - { - return -1; - } - - if (whence == SEEK_CUR || whence == SEEK_END) - { - efi_errno = file->GetPosition(file, (UINTN *)¤t); - } - - if (EFI_ERROR(efi_errno)) - { - return -1; - } - - efi_errno = file->SetPosition(file, (UINTN)(offset + current)); - - return !EFI_ERROR(efi_errno) ? offset : -1; -} - -static ssize_t efi_console_read(EFI_SIMPLE_TEXT_INPUT_PROTOCOL *console, CHAR16 *buffer, size_t length) -{ - //TODO: implement user input - (void)console; - (void)buffer; - efi_errno = EFI_INVALID_PARAMETER; - return !EFI_ERROR(efi_errno) ? length : -1; -} - -ssize_t efi_read(int fd, void *buffer, size_t length) -{ - if (buffer == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - EFI_SIMPLE_TEXT_INPUT_PROTOCOL *console = fd_to_inconsole(fd); - - if (console != nullptr) - { - return efi_console_read(console, buffer, length); - } - - EFI_FILE_PROTOCOL *file = fd_to_file(fd); - - if (file == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - size_t bytes = length; - efi_errno = file->Read(file, &bytes, buffer); - - return !EFI_ERROR(efi_errno) ? bytes : -1; -} - -static ssize_t efi_console_write(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *console, const void *buffer, size_t length) -{ - if (length == (size_t)-1) - { - length = strlen(buffer); - } - - wchar_t *ws = efi_calloc_pool(length + 2, sizeof(*ws)); - - if(mbstowcs(ws, buffer, length + 2) == (size_t)-1) - { - efi_errno = EFI_INVALID_PARAMETER; - } - else - { - if (ws[length - 1] == L'\n') - ws[length] = L'\r'; - efi_errno = console->OutputString(console, ws); - } - - efi_free_pool(ws); - - return !EFI_ERROR(efi_errno) ? length : -1; -} - -ssize_t efi_write(int fd, const void *buffer, size_t length) -{ - if (buffer == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *console = fd_to_outconsole(fd); - - if (console != nullptr) - { - return efi_console_write(console, buffer, length); - } - - EFI_FILE_PROTOCOL *file = fd_to_file(fd); - - if (file == nullptr) - { - efi_errno = EFI_INVALID_PARAMETER; - return -1; - } - - size_t bytes = length; - efi_errno = file->Write(file, &bytes, (void *)buffer); - - return !EFI_ERROR(efi_errno) ? bytes : -1; -} - diff --git a/kjarna/efi/image.c b/kjarna/efi/image.c deleted file mode 100644 index c26b588..0000000 --- a/kjarna/efi/image.c +++ /dev/null @@ -1,196 +0,0 @@ -#include <posix/unistd.h> -#include <posix/fcntl.h> -#include <kjarna/interface.h> -#include <libc/string.h> -#include <lib/elf.h> - -#include "kjarna_efi.h" - -#include <efi/error.h> - -struct image_buffer -{ - char *base; - size_t length; -}; - -static ssize_t read_ehdr(int fd, Elf64_Ehdr *ehdr) -{ - ssize_t result; - - if (efi_lseek(fd, 0, SEEK_SET) == -1) - { - return -1; - } - else if ((result = efi_read(fd, ehdr, sizeof(*ehdr))) == -1) - { - 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); -} - -static ssize_t load_segment(int fd, Elf64_Phdr *phdr, char *buffer) -{ - if (efi_lseek(fd, phdr->p_offset, SEEK_SET) == -1) - { - return -1; - } - - int result = efi_read(fd, &buffer[phdr->p_offset], phdr->p_filesz); - - 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; -} - -static struct image_buffer load_image(void) -{ - const char *image_entry_path = "\\adasoft\\sophia\\kjarna.os"; - - int image_fd; - - struct image_buffer buffer = { nullptr, 0 }; - - if ((image_fd = efi_open(image_entry_path, O_RDONLY, 0)) == -1) - { - return buffer; - } - - Elf64_Ehdr ehdr; - - if (read_ehdr(image_fd, &ehdr) == -1) - { - return buffer; - } - - Elf64_Phdr *phdrs = efi_calloc_pool(ehdr.e_phnum, ehdr.e_phentsize); - - if (phdrs == nullptr) - { - 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) - { - efi_munmap(buffer.base, buffer.length); - buffer.base = nullptr; - } - - efi_close(image_fd); - efi_free_pool(phdrs); - - 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); -} - -int image_start(void) -{ - struct kjarna_interface interface = - { - efi_open, - efi_close, - efi_lseek, - efi_read, - efi_write, - efi_mmap, - efi_munmap - }; - - struct kjarna_entry_params params = - { - &interface, - 0, - nullptr, - nullptr - }; - - struct image_buffer buffer = load_image(); - - kjarna_image_entry_func *image_entry = nullptr; - - if (buffer.base != nullptr) - { - image_entry = image_entry_addr(&buffer); - } - - if (image_entry != nullptr) - { - image_entry(¶ms); - } - - if (efi_munmap(buffer.base, buffer.length) == -1) - { - efi_write(STDOUT_FILENO, "failed unmap\r\n", -1); - - if (efi_errno == EFI_NOT_FOUND) - { - efi_write(STDOUT_FILENO, "not found\r\n", -1); - } - else - { - efi_write(STDOUT_FILENO, "bad alignment?\r\n", -1); - } - } - - return -1; -} - diff --git a/kjarna/efi/kjarna_efi.h b/kjarna/efi/kjarna_efi.h deleted file mode 100644 index ea9d3f1..0000000 --- a/kjarna/efi/kjarna_efi.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <posix/sys/types.h> - -#include <efi/types.h> -#include <efi/tables.h> - -#include "../kjarna.h" - -struct efi_context -{ - EFI_HANDLE const handle; - EFI_SYSTEM_TABLE * const system_table; -}; - -extern struct efi_context const *efi_context; -extern EFI_STATUS efi_errno; - -#define gST efi_context->system_table -#define gBS efi_context->system_table->BootServices - -void *efi_get_protocol(EFI_HANDLE handle, EFI_GUID *guid); -void efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid); - -int SYSV_ABI efi_open(const char *path, int flags, int mode); -int SYSV_ABI efi_close(int fd); -off_t SYSV_ABI efi_lseek(int fd, off_t offset, int whence); -ssize_t SYSV_ABI efi_read(int fd, void *buffer, size_t length); -ssize_t SYSV_ABI efi_write(int fd, const void *buffer, size_t length); - -void * SYSV_ABI efi_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); -int SYSV_ABI efi_munmap(void *addr, size_t length); - -void *efi_alloc_pool(size_t size); -void *efi_calloc_pool(size_t count, size_t size); -void efi_free_pool(void *block); - diff --git a/kjarna/efi/memory.c b/kjarna/efi/memory.c deleted file mode 100644 index 7fbb4a8..0000000 --- a/kjarna/efi/memory.c +++ /dev/null @@ -1,83 +0,0 @@ -#include <libc/string.h> - -#include <efi/services.h> -#include <efi/error.h> - -#include <stddef.h> - -#include "kjarna_efi.h" - -void *efi_alloc_pool(size_t size) -{ - void *buffer; - - efi_errno = gBS->AllocatePool( - EfiLoaderData, - size, - &buffer); - - if (EFI_ERROR(efi_errno)) - { - return nullptr; - } - - return buffer; -} - -void *efi_calloc_pool(size_t count, size_t size) -{ - void *buffer = efi_alloc_pool(count * size); - - if (buffer != nullptr) - { - memset(buffer, 0, count * size); - } - - return buffer; -} - -void efi_free_pool(void *buffer) -{ - efi_errno = gBS->FreePool(buffer); -} - -#define KjarnaData EFIX_OS_MEMORY_TYPE(1) - -void *efi_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) -{ - (void)prot; - (void)flags; - (void)fd; - (void)offset; - - EFI_ALLOCATE_TYPE alloc_type = AllocateAnyPages; - EFI_MEMORY_TYPE memory_type = KjarnaData; - - void *buffer; - - if (addr != nullptr) - { - alloc_type = AllocateAddress; - } - - efi_errno = gBS->AllocatePages( - alloc_type, - memory_type, - EFI_SIZE_TO_PAGES(length), - (uintptr_t *)&buffer); - - if (EFI_ERROR(efi_errno)) - { - return nullptr; - } - - return buffer; -} - -int efi_munmap(void *addr, size_t length) -{ - efi_errno = gBS->FreePages((uintptr_t)addr, EFI_SIZE_TO_PAGES(length)); - - return !EFI_ERROR(efi_errno) ? 0 : -1; -} - diff --git a/kjarna/efi/protocol.c b/kjarna/efi/protocol.c deleted file mode 100644 index 6bf8123..0000000 --- a/kjarna/efi/protocol.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <efi/error.h> - -#include "kjarna_efi.h" - -void *efi_get_protocol(EFI_HANDLE handle, EFI_GUID *guid) -{ - void *protocol; - - efi_errno = gBS->OpenProtocol( - handle, - guid, - &protocol, - efi_context->handle, - nullptr, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (EFI_ERROR(efi_errno)) - { - return nullptr; - } - - return protocol; -} - -void efi_close_protocol(EFI_HANDLE handle, EFI_GUID *guid) -{ - efi_errno = gBS->CloseProtocol( - handle, - guid, - efi_context->handle, - nullptr); -} - diff --git a/kjarna/efi/start.c b/kjarna/efi/start.c deleted file mode 100644 index 8ef8cbe..0000000 --- a/kjarna/efi/start.c +++ /dev/null @@ -1,32 +0,0 @@ -#include <efi/types.h> -#include <efi/error.h> -#include <efi/media.h> -#include <efi/tables.h> - -#include "../kjarna.h" -#include "kjarna_efi.h" - -struct efi_context const *efi_context; -EFI_STATUS efi_errno = EFI_SUCCESS; - -EFI_STATUS _exit(EFI_STATUS status) -{ - return gBS->Exit(efi_context->handle, status, 0, nullptr); -} - -EFI_STATUS _start(EFI_HANDLE handle, EFI_SYSTEM_TABLE *system_table) -{ - struct efi_context app_context = { handle, system_table }; - efi_context = &app_context; - - system_table->ConOut->ClearScreen(system_table->ConOut); - - if (main(0, nullptr) != 0) - { - efi_errno = EFI_ABORTED; - } - - - return _exit(efi_errno); -} - |
