commit 8480760936e723c1b4425b92d51ffe503f9f5d15
parent 493f032641f1862d93c123e8eaa58217844a58dc
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 28 Mar 2024 14:21:59 +0900
add ElfHdr
Diffstat:
5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
@@ -1,6 +1,6 @@
void
kernel_main(void)
{
- for(int x ;; x++) {
+ for(int x = 0;; x++) {
}
}
\ No newline at end of file
diff --git a/loader.c b/loader.c
@@ -55,22 +55,23 @@ EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *systab)
efi_printf("open file \"kernel.elf\": %d\n", stat);
return stat;
}
-
EFI_PHYSICAL_ADDRESS kernel_base = 0x100000;
- UINTN fib_size = 1024;
- char fibuf[1024];
+ UINTN fib_size = sizeof(EFI_FILE_INFO) + sizeof(CHAR16) * 11;
+ char fibuf[fib_size];
EFI_FILE_INFO *fileInfo = (EFI_FILE_INFO *) fibuf;
stat = kernel->GetInfo(kernel, &EFI_FILE_INFO_ID, &fib_size, (VOID *)fibuf);
if (stat != EFI_SUCCESS) {
efi_printf("get info of \"kernel.elf\": %d\n", stat);
return stat;
}
- stat = kernel->SetPosition(kernel, 0x1000);
+ UINT64 kernel_size = fileInfo->FileSize;
+ ElfHdr kernel_hdr;
+ read_elf_hdr(kernel, &kernel_hdr);
+ stat = kernel->SetPosition(kernel, kernel_hdr.entry);
if (stat != EFI_SUCCESS) {
efi_printf("set position of \"kernel.elf\": %d\n", stat);
return stat;
}
- UINTN kernel_size = 0x100;
stat = kernel->Read(kernel, &kernel_size, (VOID *)kernel_base);
if (stat != EFI_SUCCESS) {
efi_printf("read file \"kernel.elf\": %d\n", stat);
diff --git a/uefi.h b/uefi.h
@@ -36,6 +36,7 @@ typedef struct EFI_GUID {
// EFI_STATUS
enum {
EFI_SUCCESS = 0,
+ EFI_INVALID_PARAMETER = 2,
};
typedef struct _EFI_SYSTEM_TABLE EFI_SYSTEM_TABLE;
diff --git a/utils.c b/utils.c
@@ -123,3 +123,29 @@ efi_printf(char *fmt, ...)
}
return (int) (buf - _buf);
}
+
+EFI_STATUS
+read_elf_hdr(EFI_FILE_PROTOCOL *elf, ElfHdr *hdr)
+{
+ EFI_STATUS stat;
+ UINTN buf_size = 1024;
+ char buf[buf_size];
+
+ stat = elf->SetPosition(elf, 0);
+ if (stat != EFI_SUCCESS) {
+ efi_printf("set position: %d\n", stat);
+ return stat;
+ }
+ stat = elf->Read(elf, &buf_size, (VOID *) buf);
+ if (stat != EFI_SUCCESS) {
+ efi_printf("read: %d\n", stat);
+ return stat;
+ }
+ if (buf[0] != 0x7f || buf[1] != 'E' || buf[2] != 'L' || buf[3] != 'F') {
+ efi_printf("not an elf file\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ efi_printf("it is an elf file\n");
+ hdr->entry = 0x1000;
+ return EFI_SUCCESS;
+}
+\ No newline at end of file
diff --git a/utils.h b/utils.h
@@ -17,3 +17,13 @@ char *wstr2str(CHAR16 *s16, char *s8);
// Can't format a string longer than 1024 CHAR16s.
// It returns number of CHAR16s written excluding the final NULL.
int efi_printf(char *fmt, ...);
+
+// ELF header.
+typedef struct {
+ UINTN entry;
+ UINTN ehsize; // ELF header's size.
+} ElfHdr;
+
+// Read_elf_hdr reads elf header and populates hdr struct.
+// It modifies elf's offset.
+EFI_STATUS read_elf_hdr(EFI_FILE_PROTOCOL *elf, ElfHdr *hdr);
+\ No newline at end of file