setos

拙OS
Log | Files | Refs | LICENSE

commit d1b06f3b59bca0a6a7ab9ec3fc8748ed05d61bfa
parent 820b923e9d99e71684cc5e079f14cccf783dcebe
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 30 Mar 2024 14:46:19 +0900

divide directory

Diffstat:
MMakefile | 29+++++++++++++----------------
Dkernel.c | 29-----------------------------
Dkernel.ld | 13-------------
Dloader.c | 121-------------------------------------------------------------------------------
Duefi.h | 408-------------------------------------------------------------------------------
Dutils.c | 265-------------------------------------------------------------------------------
Dutils.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