commit d1b06f3b59bca0a6a7ab9ec3fc8748ed05d61bfa
parent 820b923e9d99e71684cc5e079f14cccf783dcebe
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 30 Mar 2024 14:46:19 +0900
divide directory
Diffstat:
M | Makefile | | | 29 | +++++++++++++---------------- |
D | kernel.c | | | 29 | ----------------------------- |
D | kernel.ld | | | 13 | ------------- |
D | loader.c | | | 121 | ------------------------------------------------------------------------------- |
D | uefi.h | | | 408 | ------------------------------------------------------------------------------- |
D | utils.c | | | 265 | ------------------------------------------------------------------------------- |
D | utils.h | | | 71 | ----------------------------------------------------------------------- |
7 files changed, 13 insertions(+), 923 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,32 +4,30 @@ EFI_CFLAGS = -nostdlib -fpic -mno-red-zone -fno-stack-protector -static \
KERN_CFLAGS = -nostdlib -fpic -mno-red-zone -ffreestanding -Wall -g
KERN_LDFLAGS = -e kernel_main -static
OBJCOPY = objcopy
-SRC = loader.c utils.c
-HDR = uefi.h
all: disk.img
-disk.img: loader.efi kernel.elf
+disk.img: uefi/uefi.efi kernel/setos.elf
qemu-img create -f raw disk.img 200M
mkfs.fat -n 'SETOS' -s 2 -f 2 -R 32 -F 32 disk.img
mkdir -p image
doas mount disk.img image
doas mkdir -p image/EFI/BOOT
- doas cp loader.efi image/EFI/BOOT/BOOTX64.EFI
- doas cp kernel.elf image/kernel.elf
+ doas cp uefi/uefi.efi image/EFI/BOOT/BOOTX64.EFI
+ doas cp kernel/setos.elf image/setos.elf
doas umount image
-loader.dll: $(SRC) $(HDR)
- x86_64-w64-mingw32-gcc $(EFI_CFLAGS) -o $@ $(SRC)
+uefi/uefi.dll: uefi/uefi.c uefi/uefi.h uefi/utils.c uefi/utils.h
+ x86_64-w64-mingw32-gcc $(EFI_CFLAGS) -o $@ uefi/uefi.c uefi/utils.c
-loader.efi: loader.dll
+uefi/uefi.efi: uefi/uefi.dll
$(OBJCOPY) --target=efi-app-x86_64 $< $@
%.o: %.c
gcc $(KERN_CFLAGS) -c -o $@ $<
-kernel.elf: kernel.o kernel.ld
- ld $(KERN_LDFLAGS) -T kernel.ld -o $@ $<
+kernel/setos.elf: kernel/main.o kernel/memmap.ld
+ ld $(KERN_LDFLAGS) -T kernel/memmap.ld -o $@ $<
run: disk.img OVMF.fd
qemu-system-x86_64 \
@@ -38,7 +36,7 @@ run: disk.img OVMF.fd
gdb: disk.img OVMF.fd
qemu-system-x86_64 \
- -bios /usr/share/edk2/x64/OVMF.fd \
+ -bios OVMF.fd \
-drive format=raw,file=disk.img \
-gdb tcp::1234 -S
@@ -46,9 +44,7 @@ gdb: disk.img OVMF.fd
# curl -OL https://downloads.sourceforge.net/project/edk2/OVMF/OVMF-X64-r15214.zip
# unzip OVMF-X64-r15214.zip OVMF.fd
-test: test/* $(SRC) $(HDR)
- (cd test && make)
-
clean:
- rm -rf *.o *.efi *.elf *.dll disk.img image #OVMF*
- (cd test && make clean)
+ rm -rf *.o *.efi *.elf *.dll disk.img image
+ rm -r uefi/*.efi uefi/*.dll
+ rm -r kernel/*.o kernel/*.elf
+\ No newline at end of file
diff --git a/kernel.c b/kernel.c
@@ -1,28 +0,0 @@
-#include "uefi.h"
-
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
-
-// Argument order is to interface to the MS-ABI
-void
-kernel_main(void *dummy0, void *dummy1, void *dummy2,
- EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
-{
- uint32_t *fb_base = (uint32_t *)gop->Mode->FrameBufferBase;
- uint32_t hrez = gop->Mode->Info->HorizontalResolution;
- uint32_t vrez = gop->Mode->Info->VerticalResolution;
- uint32_t sl = gop->Mode->Info->PixelsPerScanLine;
- uint32_t cx = hrez / 2;
- uint32_t cy = vrez / 2;
- for (int i = 0; i < vrez; i++) {
- for (int j = 0; j < hrez; j++) {
- if ((cx-j)*(cx-j) + (cy-i)*(cy-i) < (vrez/3) * (vrez/3)) {
- fb_base[i * sl + j] = 0xff << 16;
- } else {
- fb_base[i * sl + j] = 0xffffff;
- }
- }
- }
- for(;;);
-}
-\ No newline at end of file
diff --git a/kernel.ld b/kernel.ld
@@ -1,12 +0,0 @@
-SECTIONS
-{
- .text 0x100000 : {
- *(.text)
- }
- .data : {
- *(.data)
- }
- .bss : {
- *(.bss)
- }
-}
-\ No newline at end of file
diff --git a/loader.c b/loader.c
@@ -1,121 +0,0 @@
-#include "uefi.h"
-#include "utils.h"
-EFI_SYSTEM_TABLE *SystemTable;
-
-EFI_STATUS
-EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *systab)
-{
- // init global variable.
- SystemTable = systab;
-
- EFI_STATUS stat;
- char s8[32];
-
- // Output firmware bender.
- SystemTable->ConOut->ClearScreen(SystemTable->ConOut);
- efi_printf("vendor: %s\n", wstr2str(SystemTable->FirmwareVendor, s8));
- efi_printf("EfiMain: 0x%x\n", EfiMain);
-
- // Output memory map information.
- UINTN mmsize = 8196;
- char mmbuf[8196];
- EFI_MEMORY_DESCRIPTOR *mmap;
- UINTN mkey;
- UINTN dsize;
- UINT32 dver;
- mmap = (EFI_MEMORY_DESCRIPTOR *) mmbuf;
- stat = SystemTable->BootServices->GetMemoryMap(&mmsize, mmap, &mkey, &dsize, &dver);
- if (stat != EFI_SUCCESS) {
- efi_printf("get memory map: %d\n", stat);
- return stat;
- }
-
- for (; mmap < (EFI_MEMORY_DESCRIPTOR *)(mmbuf + mmsize);
- mmap = (EFI_MEMORY_DESCRIPTOR *) (((char *)mmap) + dsize)) {
- if (mmap->Type != EfiConventionalMemory) {
- continue;
- }
- efi_printf("%d\t%x\t%x\t%x\t%x\n", mmap->Type, mmap->VirtualStart,
- mmap->PhysicalStart, mmap->NumberOfPages, mmap->Attribute);
- }
-
- EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
- stat = open_gop(ImageHandle, &gop);
- if (stat != EFI_SUCCESS) {
- efi_printf("open_gop: %d\n", stat);
- return stat;
- }
- UINT32 *frame_buffer = (UINT32 *)gop->Mode->FrameBufferBase;
- for (UINTN i = 0; i < gop->Mode->FrameBufferSize/4; i++) {
- frame_buffer[i] = 0x427f94;
- }
- efi_printf("frame buffer: base: %x, size: %x\n", frame_buffer,
- gop->Mode->FrameBufferSize);
-
- EFI_FILE_PROTOCOL *root, *kernel;
- stat = open_root(ImageHandle, &root);
- if (stat != EFI_SUCCESS) {
- efi_printf("open_root: %d\n", stat);
- return stat;
- }
- stat = root->Open(root, &kernel, L"kernel.elf",
- EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
- if (stat != EFI_SUCCESS) {
- efi_printf("open file \"kernel.elf\": %d\n", stat);
- return stat;
- }
- ElfHdr kernel_ehdr;
- stat = read_ehdr(kernel, &kernel_ehdr);
- if (stat != EFI_SUCCESS) {
- efi_printf("read ehdr of \"kernel.elf\": %d\n", stat);
- return stat;
- }
- efi_printf("type:\t%x\nphoff:\t%x\nphentsize:\t%x\nphnum:\t%x\n",
- kernel_ehdr.type, kernel_ehdr.phoff,
- kernel_ehdr.phentsize, kernel_ehdr.phnum);
- if (kernel_ehdr.phnum > 32) {
- efi_printf("too many phdrs\n");
- return EFI_BUFFER_TOO_SMALL;
- }
- Phdr kernel_phdr[32];
- stat = read_phdr(kernel, &kernel_ehdr, kernel_phdr);
- if (stat != EFI_SUCCESS) {
- efi_printf("read phdr of \"kernel.elf\": %d\n", stat);
- return stat;
- }
- for (UINT16 i = 0; i < kernel_ehdr.phnum; i++) {
- efi_printf("type: %x, offset: %x, vaddr: %x\n",
- kernel_phdr[i].type, kernel_phdr[i].offset, kernel_phdr[i].vaddr);
- }
- stat = load_elf(kernel, &kernel_ehdr, kernel_phdr);
- if (stat != EFI_SUCCESS) {
- efi_printf("load \"kernel.elf\": %d\n", stat);
- return stat;
- }
- stat = kernel->Close(kernel);
- if (stat != EFI_SUCCESS) {
- efi_printf("close file: %d\n", stat);
- return stat;
- }
-
- efi_printf("frame buffer: base: %x, %x, size: %x\n", frame_buffer,
- gop->Mode->FrameBufferBase,
- gop->Mode->FrameBufferSize);
-
- mmsize = 8196;
- stat = SystemTable->BootServices->GetMemoryMap(&mmsize, mmap, &mkey, &dsize, &dver);
- if (stat != EFI_SUCCESS) {
- efi_printf("get memory map: %d\n", stat);
- return stat;
- }
- stat = SystemTable->BootServices->ExitBootServices(ImageHandle, mkey);
- if (stat != EFI_SUCCESS) {
- efi_printf("exit boot services: %d\n", stat);
- return stat;
- }
-
- typedef void (* Kernel) (EFI_GRAPHICS_OUTPUT_PROTOCOL *);
- ((Kernel) kernel_ehdr.entry)(gop);
-
- return EFI_SUCCESS;
-}
diff --git a/uefi.h b/uefi.h
@@ -1,408 +0,0 @@
-#define IN
-#define OUT
-#define OPTIONAL
-#define CONST
-#define EFIAPI
-
-#define NULL 0L
-
-typedef unsigned short CHAR16;
-typedef unsigned long long UINTN;
-typedef unsigned char UINT8;
-typedef short INT16;
-typedef unsigned short UINT16;
-typedef unsigned UINT32;
-typedef unsigned long long UINT64;
-typedef UINTN EFI_STATUS;
-typedef void *EFI_HANDLE;
-typedef UINT64 EFI_PHYSICAL_ADDRESS;
-typedef UINT64 EFI_VIRTUAL_ADDRESS;
-typedef void VOID;
-typedef struct EFI_GUID {
- UINT32 Data1;
- UINT16 Data2;
- UINT16 Data3;
- UINT8 Data4[8];
-} EFI_GUID;
-
-#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
- {0x5b1b31a1, 0x9562, 0x11d2, \
- {0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
-#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
- {0x9042a9de, 0x23dc, 0x4a38, \
- {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a}}
-#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
- {0x964e5b22, 0x6459, 0x11d2, \
- {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
-#define EFI_FILE_INFO_ID \
- {0x9576e92, 0x6d3f, 0x11d2, \
- {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
-
-// EFI_STATUS
-enum {
- EFI_SUCCESS = 0,
-
- EFI_INVALID_PARAMETER = 0x8000000000000002,
- EFI_BUFFER_TOO_SMALL = 0x8000000000000005,
-};
-
-typedef struct _EFI_SYSTEM_TABLE EFI_SYSTEM_TABLE;
-
-typedef struct {
- UINT16 ScanCode;
- CHAR16 UnicodeChar;
-} EFI_INPUT_KEY;
-
-typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_INPUT_READ_KEY)(
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- OUT EFI_INPUT_KEY *Key
- );
-
-typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL {
- void *dummy;
- EFI_INPUT_READ_KEY ReadKeyStroke;
-} EFI_SIMPLE_TEXT_INPUT_PROTOCOL;
-
-typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_TEXT_STRING)(
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
- IN CHAR16 *String
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_TEXT_CLEAR_SCREEN)(
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
- );
-
-struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
- void *dummy;
- EFI_TEXT_STRING OutputString;
- void *dummy1[4];
- EFI_TEXT_CLEAR_SCREEN ClearScreen;
-};
-
-typedef enum {
- EfiReservedMemoryType,
- EfiLoaderCode,
- EfiLoaderData,
- EfiBootServicesCode,
- EfiBootServicesData,
- EfiRuntimeServicesCode,
- EfiRuntimeServicesData,
- EfiConventionalMemory,
- EfiUnusableMemory,
- EfiACPIReclaimMemory,
- EfiACPIMemoryNVS,
- EfiMemoryMappedIO,
- EfiMemoryMappedIOPortSpace,
- EfiPalCode,
- EfiPersistentMemory,
- EfiUnacceptedMemoryType,
- EfiMaxMemoryType,
-} EFI_MEMORY_TYPE;
-
-typedef struct {
- UINT32 Type;
- EFI_PHYSICAL_ADDRESS PhysicalStart;
- EFI_VIRTUAL_ADDRESS VirtualStart;
- UINT64 NumberOfPages;
- UINT64 Attribute;
-} EFI_MEMORY_DESCRIPTOR;
-
-typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
-
-typedef enum {
- PixelRedGreenBlueReserved8BitPerColor,
- PixelBlueGreenRedReserved8BitPerColor,
- PixelBitMask,
- PixelBltOnly,
- PixelFormatMax,
-} EFI_GRAPHICS_PIXEL_FORMAT;
-
-typedef struct {
- UINT32 RedMask;
- UINT32 GreenMask;
- UINT32 BlueMask;
- UINT32 ReservedMask;
-} EFI_PIXEL_BITMASK;
-
-typedef struct {
- UINT32 Version;
- UINT32 HorizontalResolution;
- UINT32 VerticalResolution;
- EFI_GRAPHICS_PIXEL_FORMAT PixelFromat; // This is not fixed in size.
- EFI_PIXEL_BITMASK PixelInformation;
- UINT32 PixelsPerScanLine;
-} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
-
-typedef struct {
- UINT32 MaxMode;
- UINT32 Mode;
- EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
- UINTN SizeOfInfo;
- EFI_PHYSICAL_ADDRESS FrameBufferBase;
- UINTN FrameBufferSize;
-} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
- );
-
-struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {
- EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
- EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
- EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
- EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
-};
-
-typedef struct _EFI_FILE_PROTOCOL EFI_FILE_PROTOCOL;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_OPEN) (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
- );
-
-#define EFI_FILE_MODE_READ 0x0000000000000001
-#define EFI_FILE_MODE_WRITE 0x0000000000000002
-#define EFI_FILE_MODE_CREATE 0x8000000000000000
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_CLOSE) (
- IN EFI_FILE_PROTOCOL *This
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_DELETE) (
- IN EFI_FILE_PROTOCOL *This
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_READ) (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_WRITE) (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_SET_POSITION) (
- IN EFI_FILE_PROTOCOL *This,
- IN UINT64 Position
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_GET_POSITION) (
- IN EFI_FILE_PROTOCOL *This,
- OUT UINT64 *Position
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_FILE_GET_INFO) (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
-
-struct _EFI_FILE_PROTOCOL {
- UINT64 Revision;
- EFI_FILE_OPEN Open;
- EFI_FILE_CLOSE Close;
- EFI_FILE_DELETE Delete;
- EFI_FILE_READ Read;
- EFI_FILE_WRITE Write;
- EFI_FILE_GET_POSITION GetPosition;
- EFI_FILE_SET_POSITION SetPosition;
- EFI_FILE_GET_INFO GetInfo;
- void *dummy1[6];
-};
-
-typedef struct {
- UINT16 Year;
- UINT8 Month;
- UINT8 Day;
- UINT8 Hour;
- UINT8 Minute;
- UINT8 Second;
- UINT8 Pad1;
- UINT32 NanoSecond;
- INT16 TimeZone;
- UINT8 Daylight;
- UINT8 Pad2;
-} EFI_TIME;
-
-typedef struct {
- UINT64 Size;
- UINT64 FileSize;
- UINT64 PhysicalSize;
- EFI_TIME CreateTime;
- EFI_TIME LastAccessTime;
- EFI_TIME ModificationTime;
- UINT64 Attribute;
- CHAR16 FileName[];
-} EFI_FILE_INFO;
-
-typedef struct _EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL;
-
-struct _EFI_LOADED_IMAGE_PROTOCOL{
- UINT32 Revision;
- EFI_HANDLE ParentHandle;
- EFI_SYSTEM_TABLE *SystemTable;
-
- EFI_HANDLE DeviceHandle;
- void *dummy[2];
-
- UINT32 LoadOptionSize;
- VOID *LoadOptions;
-
- VOID *ImageBase;
- UINT64 ImageSize;
- char dummy1[4 + 4];
- void *dummy2;
-};
-
-typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)(
- IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **Root
- );
-
-struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
- UINT64 Revision;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;
-};
-
-typedef enum {
- AllocateAnyPages,
- AllocateMaxAddress,
- AllocateAddress,
- MaxAllocateType
-} EFI_ALLOCATE_TYPE;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_ALLOCATE_PAGES)(
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- IN OUT EFI_PHYSICAL_ADDRESS *Memory
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_GET_MEMORY_MAP)(
- IN OUT UINTN *MemoryMapSize,
- OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- OUT UINTN *MapKey,
- OUT UINTN *DescriptorSize,
- OUT UINT32 *DescriptorVersion
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_EXIT_BOOT_SERVICES)(
- IN EFI_HANDLE ImageHandle,
- IN UINTN MapKey
- );
-
-typedef
-EFI_STATUS (EFIAPI *EFI_OPEN_PROTOCOL)(
- IN EFI_HANDLE Handle,
- IN EFI_GUID *Protocol,
- OUT VOID **Interface OPTIONAL,
- IN EFI_HANDLE AgentHandle,
- IN EFI_HANDLE ControllerHandle,
- IN UINT32 Attributes
- );
-
-typedef enum {
- AllHandles,
- ByRegisterNotify,
- ByProtocol
-} EFI_LOCATE_SEARCH_TYPE;
-
-typedef
-EFI_STATUS (EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
- IN EFI_GUID *Protocol OPTIONAL,
- IN VOID *SearchKey OPTIONAL,
- OUT UINTN *NoHandles,
- OUT EFI_HANDLE **Buffer
- );
-
-#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x1
-
-typedef struct {
-} EFI_RUNTIME_SERVICES;
-
-typedef struct {
- UINT64 Signature;
- UINT32 Revision;
- UINT32 HeaderSize;
- UINT32 CRC32;
- UINT32 Reserved;
-} EFI_TABLE_HEADER;
-
-typedef struct {
- EFI_TABLE_HEADER Hdr;
- // task priority services
- void *task_priority_services[2];
- // memory services
- EFI_ALLOCATE_PAGES AllocatePages;
- void *memory_services0[1];
- EFI_GET_MEMORY_MAP GetMemoryMap;
- void *memory_services1[2];
- // event timer services
- void *event_timer_services[6];
- // protocol handler services
- void *protocol_handler_services[9];
- // image services
- void *image_services0[4];
- EFI_EXIT_BOOT_SERVICES ExitBootServices;
- void *miscellaneus_services[3];
- void *driversupport_services[2];
- EFI_OPEN_PROTOCOL OpenProtocol;
- void *open_and_close_protocol_services[2];
- void *library_servies0[1];
- EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
- void *library_servies1[3];
- void *crc_services[1];
- void *miscellaneus_services1[3];
-} EFI_BOOT_SERVICES;
-
-struct _EFI_SYSTEM_TABLE {
- EFI_TABLE_HEADER Hdr;
- CHAR16 *FirmwareVendor;
- char dummy1[4];
- EFI_HANDLE ConsoleInHandle;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
- EFI_HANDLE ConsoleOutHandle;
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
- EFI_HANDLE StandardErrorHandle;
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
- EFI_RUNTIME_SERVICES *RuntimeServices;
- EFI_BOOT_SERVICES *BootServices;
- char dummy2[16];
-};
diff --git a/utils.c b/utils.c
@@ -1,265 +0,0 @@
-#include <stdarg.h> // TODO: implement stdarg.h by my self
-
-#include "uefi.h"
-#include "utils.h"
-
-CHAR16 *
-sprinth(UINT64 n, CHAR16 s[19])
-{
- int i;
- int d;
- s[0] = L'0';
- s[1] = L'x';
- for (i = 0; i < 16; i++) {
- d = (n >> (64 - (i + 1) * 4)) & 0xf;
- if (d <= 9)
- s[i + 2] = L'0' + d;
- else
- s[i + 2] = L'a' + d - 10;
- }
- s[19] = L'\0';
- return s;
-}
-
-char *
-wstr2str(CHAR16 *s16, char *s8)
-{
- char *s = s8;
- for (;*s16;) {
- *s8++ = (char) (*s16++ & 0xff);
- }
- *s8 = '\0';
- return s;
-}
-
-int
-efi_printf(char *fmt, ...)
-{
- va_list ap;
- CHAR16 _buf[1024], *buf = _buf;
- EFI_STATUS stat;
-
- char *s;
- CHAR16 *w;
- long long d, e;
- unsigned long long f, g, h;
-
- va_start(ap, fmt);
- for (;*fmt;) {
- if (*fmt != '%') {
- if (*fmt == '\n') {
- *buf++ = (CHAR16) '\n';
- *buf++ = (CHAR16) '\r';
- fmt++;
- continue;
- } else {
- *buf++ = (CHAR16) *fmt++;
- continue;
- }
- }
- fmt++;
- switch (*fmt++) {
- case '%':
- *buf++ = L'%';
- break;
- case 's':
- s = va_arg(ap, char *);
- for (;*s;) {
- *buf++ = (CHAR16) *s++;
- }
- break;
- case 'w':
- w = va_arg(ap, CHAR16 *);
- for (;*w;) {
- *buf++ = *w++;
- }
- break;
- case 'd':
- d = va_arg(ap, int);
- if (d == 0) {
- *buf++ = '0';
- break;
- } else if (d < 0) {
- *buf++ = '-';
- d = -d;
- }
- for (e = 1; e <= d; e *= 10) {
- if (e > e * 10) { // integer too big;
- return -1;
- }
- }
- for (e /= 10; e >= 1; e /= 10) {
- *buf++ = (CHAR16) ('0' + ((d / e) % 10));
- }
- break;
- case 'x':
- f = va_arg(ap, unsigned int);
- if (f == 0) {
- *buf++ = '0';
- break;
- }
- for (g = 1; g <= f; g *= 0x10) {
- if (g > g * 0x10) { // integer too big.
- return -1;
- }
- }
- for (g /= 0x10; g >= 1; g /= 0x10) {
- h = ((f / g) % 0x10);
- if (h < 0xa) {
- *buf++ = (CHAR16) ('0' + h);
- } else {
- *buf++ = (CHAR16) ('a' + h - 0xa);
- }
- }
- break;
- }
- }
- va_end(ap);
- *buf = L'\0';
-
- stat = SystemTable->ConOut->OutputString(SystemTable->ConOut, _buf);
- if (stat != EFI_SUCCESS) {
- return -1;
- }
- return (int) (buf - _buf);
-}
-
-EFI_STATUS
-open_root(EFI_HANDLE ImageHandle, EFI_FILE_PROTOCOL **root)
-{
- EFI_STATUS stat;
- EFI_LOADED_IMAGE_PROTOCOL *li;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fs;
-
- stat = SystemTable->BootServices->OpenProtocol(
- ImageHandle, &(EFI_GUID)EFI_LOADED_IMAGE_PROTOCOL_GUID,
- (VOID **) &li, ImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (stat != EFI_SUCCESS) {
- return stat;
- }
-
- stat = SystemTable->BootServices->OpenProtocol(
- li->DeviceHandle, &(EFI_GUID)EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
- (VOID **) &fs, ImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (stat != EFI_SUCCESS) {
- return stat;
- }
-
- stat = fs->OpenVolume(fs, root);
- return stat;
-}
-
-EFI_STATUS
-open_gop(EFI_HANDLE ImageHandle, EFI_GRAPHICS_OUTPUT_PROTOCOL **gop)
-{
- EFI_STATUS stat;
- UINTN n = 0;
- EFI_HANDLE *_gop;
- stat = SystemTable->BootServices->LocateHandleBuffer(
- ByProtocol, &(EFI_GUID)EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, NULL,
- &n, &_gop
- );
- if (stat != EFI_SUCCESS) {
- efi_printf("locate handle buffer: %d\n", stat);
- return stat;
- }
- stat = SystemTable->BootServices->OpenProtocol(
- _gop[0], &(EFI_GUID)EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID,
- (VOID **) gop, ImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (stat != EFI_SUCCESS) {
- efi_printf("open protocol: %d\n", stat);
- return stat;
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-read_ehdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr)
-{
- EFI_STATUS stat;
- UINTN ehdr_size = sizeof(ElfHdr);
-
- stat = elf->SetPosition(elf, 0);
- if (stat != EFI_SUCCESS) {
- efi_printf("set position: %d\n", stat);
- return stat;
- }
- stat = elf->Read(elf, &ehdr_size, (VOID *) ehdr);
- if (stat != EFI_SUCCESS) {
- efi_printf("read: %d\n", stat);
- return stat;
- }
- // TODO: check file format.
- // for now, it assumes that elf is 2's complement, 64-bit little endian,
- // System V ABI...
- if (ehdr->ident[0] != 0x7f || ehdr->ident[1] != 'E' ||
- ehdr->ident[2] != 'L' || ehdr->ident[3] != 'F') {
- efi_printf("not an elf file\n");
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-read_phdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[])
-{
- EFI_STATUS stat;
- UINTN n;
-
- stat = elf->SetPosition(elf, ehdr->phoff);
- if (stat != EFI_SUCCESS) {
- efi_printf("set position: %d\n", stat);
- return stat;
- }
- // TODO: need overflow check??
- n = ehdr->phentsize * ehdr->phnum;
- stat = elf->Read(elf, &n, (VOID *) phdr);
- if (stat != EFI_SUCCESS) {
- efi_printf("read phdr: %d\n", stat);
- return stat;
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-load_elf(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[])
-{
- EFI_STATUS stat;
- EFI_PHYSICAL_ADDRESS addr;
- UINT64 size;
- for (UINT16 i = 0; i < ehdr->phnum; i++) {
- if (phdr[i].type != PT_LOAD) {
- continue;
- }
- efi_printf("load_elf: allocate %d at %x\n",
- phdr[i].memsz, phdr[i].vaddr
- );
- stat = SystemTable->BootServices->AllocatePages(
- AllocateAddress, EfiLoaderData,
- (phdr[i].memsz + 0xfff) / 0x1000, &phdr[i].vaddr
- );
- if (stat != EFI_SUCCESS) {
- efi_printf("allocate pages: %d\n", stat);
- return stat;
- }
- efi_printf("load_elf: phdr[i].vaddr: %x\n", phdr[i].vaddr);
- stat = elf->SetPosition(elf, phdr[i].offset);
- if (stat != EFI_SUCCESS) {
- efi_printf("set position: %d\n", stat);
- return stat;
- }
- addr = (EFI_PHYSICAL_ADDRESS) phdr[i].vaddr;
- efi_printf("load_elf: read to %x\n", addr);
- size = phdr[i].filesz;
- stat = elf->Read(elf, &size, (VOID *)addr);
- if (stat != EFI_SUCCESS) {
- efi_printf("read to memory: %d\n", stat);
- return stat;
- }
- }
- return EFI_SUCCESS;
-}
diff --git a/utils.h b/utils.h
@@ -1,70 +0,0 @@
-// #include "uefi.h"
-
-extern EFI_SYSTEM_TABLE *SystemTable;
-
-// Printh converts the integer into a string of hex representation.
-// It returns the second argument.
-// The second argument should have length of 19 ("0x" + "0123456789abcdef" + "\0").
-CHAR16 *sprinth(UINT64, CHAR16[19]);
-
-// Wstr2str converts UTF16-encoded string s16 to string.
-// It ignores the high byte.
-// caller must ensure that s has enough space.
-// It returns s.
-char *wstr2str(CHAR16 *s16, char *s8);
-
-// Efi_printf prints formatted string to ConOut.
-// Can't format a string longer than 1024 CHAR16s.
-// It returns number of CHAR16s written excluding the final NULL.
-int efi_printf(char *fmt, ...);
-
-// Open_gop opens the graphics output protocol.
-EFI_STATUS open_gop(EFI_HANDLE, EFI_GRAPHICS_OUTPUT_PROTOCOL **);
-
-// Open_root opens the root directory of the efi image.
-EFI_STATUS open_root(EFI_HANDLE, EFI_FILE_PROTOCOL **);
-
-// ELF header.
-typedef struct {
- unsigned char ident[16];
- UINT16 type;
- UINT16 machine;
- UINT32 version;
- UINTN entry;
- UINTN phoff;
- UINTN shoff;
- UINT32 flags;
- UINT16 ehsize; // ELF header's size.
- UINT16 phentsize;
- UINT16 phnum;
- UINT16 shentsize;
- UINT16 shnum;
- UINT16 shstrndx;
-} ElfHdr;
-
-typedef struct {
- UINT32 type;
- UINT32 flags;
- UINTN offset;
- UINTN vaddr;
- UINTN paddr;
- UINT64 filesz;
- UINT64 memsz;
- UINT64 align;
-} Phdr;
-
-#define PT_LOAD 1
-
-// Read_ehdr reads elf header and populates ehdr.
-// It modifies elf's offset.
-EFI_STATUS read_ehdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr);
-
-// Read_phdr reads elf's program headers and populates phdr.
-// It uses ehdr to read phdr.
-// It modifies elf's offset.
-// Caller should allocate enough space in phdr.
-EFI_STATUS read_phdr(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[]);
-
-// Load_elf copies loadable segments of elf to the memory specified by the
-// vaddr field of each Phdr.
-EFI_STATUS load_elf(EFI_FILE_PROTOCOL *elf, ElfHdr *ehdr, Phdr phdr[]);
-\ No newline at end of file