Parse EFI command line arguments (#12)

This commit is contained in:
Justine Tunney 2021-02-21 23:33:44 -08:00
parent 537c21338b
commit ac3b1dfb21
3 changed files with 81 additions and 14 deletions

View file

@ -53,7 +53,7 @@ XARGS ?= xargs -P4 -rs8000
NICE ?= build/actuallynice NICE ?= build/actuallynice
DOT ?= dot DOT ?= dot
GZ ?= gzip GZ ?= gzip
CLANG = clang-10 CLANG = clang
FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran
# see build/compile, etc. which run third_party/gcc/unbundle.sh # see build/compile, etc. which run third_party/gcc/unbundle.sh

View file

@ -91,6 +91,13 @@
#define EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 #define EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
#define EFI_EVT_RUNTIME_CONTEXT 0x20000000 #define EFI_EVT_RUNTIME_CONTEXT 0x20000000
#define LOADED_IMAGE_PROTOCOL \
{ \
0x5B1B31A1, 0x9562, 0x11d2, { \
0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B \
} \
}
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
@ -210,6 +217,12 @@ typedef struct {
uint32_t Reserved; uint32_t Reserved;
} EFI_TABLE_HEADER; } EFI_TABLE_HEADER;
typedef struct {
uint8_t Type;
uint8_t SubType;
uint8_t Length[2];
} EFI_DEVICE_PATH_PROTOCOL;
typedef EFI_STATUS(EFIAPI *EFI_EXIT)(EFI_HANDLE ImageHandle, typedef EFI_STATUS(EFIAPI *EFI_EXIT)(EFI_HANDLE ImageHandle,
EFI_STATUS ExitStatus, EFI_STATUS ExitStatus,
uintptr_t ExitDataSize, uintptr_t ExitDataSize,
@ -242,6 +255,10 @@ typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)(
uintptr_t *out_MapKey, uintptr_t *out_DescriptorSize, uintptr_t *out_MapKey, uintptr_t *out_DescriptorSize,
uint32_t *out_DescriptorVersion); uint32_t *out_DescriptorVersion);
typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_POOL)(EFI_MEMORY_TYPE PoolType,
uintptr_t Size, void *out_Buffer);
typedef EFI_STATUS(EFIAPI *EFI_FREE_POOL)(void *Buffer);
typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT Event); typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT Event);
typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT Event); typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT Event);
typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT Event); typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT Event);
@ -318,6 +335,18 @@ typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)(
typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)( typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)(
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool Visible); EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool Visible);
typedef EFI_STATUS(EFIAPI *EFI_HANDLE_PROTOCOL)(EFI_HANDLE Handle,
EFI_GUID *Protocol,
void *out_Interface);
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_LOAD)(bool BootPolicy,
EFI_HANDLE ParentImageHandle,
EFI_DEVICE_PATH_PROTOCOL *DevicePath,
void *opt_SourceBuffer,
uintptr_t SourceSize,
EFI_HANDLE *out_ImageHandle);
typedef EFI_STATUS(EFIAPI *EFI_IMAGE_UNLOAD)(EFI_HANDLE ImageHandle);
typedef struct { typedef struct {
EFI_TABLE_HEADER Hdr; EFI_TABLE_HEADER Hdr;
EFI_GET_TIME GetTime; EFI_GET_TIME GetTime;
@ -343,8 +372,8 @@ typedef struct {
EFI_ALLOCATE_PAGES AllocatePages; EFI_ALLOCATE_PAGES AllocatePages;
EFI_FREE_PAGES FreePages; EFI_FREE_PAGES FreePages;
EFI_GET_MEMORY_MAP GetMemoryMap; EFI_GET_MEMORY_MAP GetMemoryMap;
void *AllocatePool; EFI_ALLOCATE_POOL AllocatePool;
void *FreePool; EFI_FREE_POOL FreePool;
EFI_CREATE_EVENT CreateEvent; EFI_CREATE_EVENT CreateEvent;
EFI_SET_TIMER SetTimer; EFI_SET_TIMER SetTimer;
EFI_WAIT_FOR_EVENT WaitForEvent; EFI_WAIT_FOR_EVENT WaitForEvent;
@ -354,16 +383,16 @@ typedef struct {
void *InstallProtocolInterface; void *InstallProtocolInterface;
void *ReinstallProtocolInterface; void *ReinstallProtocolInterface;
void *UninstallProtocolInterface; void *UninstallProtocolInterface;
void *HandleProtocol; EFI_HANDLE_PROTOCOL HandleProtocol;
void *Reserved; void *Reserved;
void *RegisterProtocolNotify; void *RegisterProtocolNotify;
void *LocateHandle; void *LocateHandle;
void *LocateDevicePath; void *LocateDevicePath;
void *InstallConfigurationTable; void *InstallConfigurationTable;
void *LoadImage; EFI_IMAGE_LOAD LoadImage;
void *StartImage; void *StartImage;
EFI_EXIT Exit; EFI_EXIT Exit;
void *UnloadImage; EFI_IMAGE_UNLOAD UnloadImage;
void *ExitBootServices; void *ExitBootServices;
EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
EFI_STALL Stall; EFI_STALL Stall;
@ -419,6 +448,22 @@ struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode; EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
}; };
typedef struct {
uint32_t Revision;
EFI_HANDLE ParentHandle;
EFI_SYSTEM_TABLE *SystemTable;
EFI_HANDLE DeviceHandle;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
void *Reserved;
uint32_t LoadOptionsSize;
void *LoadOptions;
void *ImageBase;
uint64_t ImageSize;
EFI_MEMORY_TYPE ImageCodeType;
EFI_MEMORY_TYPE ImageDataType;
EFI_IMAGE_UNLOAD Unload;
} EFI_LOADED_IMAGE;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_NT_EFI_H_ */ #endif /* COSMOPOLITAN_LIBC_NT_EFI_H_ */

View file

@ -18,10 +18,19 @@
*/ */
#include "libc/calls/efi.h" #include "libc/calls/efi.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/macros.h"
#include "libc/nt/efi.h" #include "libc/nt/efi.h"
#include "libc/nt/thunk/msabi.h" #include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
struct EfiArgs {
char *args[4096];
char argblock[ARG_MAX];
};
static const EFI_GUID kEfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
/** /**
* EFI Application Entrypoint. * EFI Application Entrypoint.
* *
@ -39,7 +48,7 @@
* *
* qemu-system-x86_64 \ * qemu-system-x86_64 \
* -bios OVMF.fd \ * -bios OVMF.fd \
* -serial stdio \ * -nographic \
* -net none \ * -net none \
* -drive format=raw,file=fat:rw:o/tool/viz * -drive format=raw,file=fat:rw:o/tool/viz
* FS0: * FS0:
@ -56,17 +65,30 @@
*/ */
__msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, __msabi noasan EFI_STATUS EfiMain(EFI_HANDLE ImageHandle,
EFI_SYSTEM_TABLE *SystemTable) { EFI_SYSTEM_TABLE *SystemTable) {
intptr_t argc;
struct EfiArgs *ea;
EFI_LOADED_IMAGE *img;
extern char os asm("__hostos"); extern char os asm("__hostos");
os = UEFI; os = UEFI;
__efi_image_handle = ImageHandle; __efi_image_handle = ImageHandle;
__efi_system_table = SystemTable; __efi_system_table = SystemTable;
asm("push\t$0\n\t" SystemTable->BootServices->AllocatePool(EfiConventionalMemory, sizeof(*ea),
"push\t$0\n\t" &ea);
"push\t$0\n\t" SystemTable->BootServices->HandleProtocol(ImageHandle,
"push\t$0\n\t" &kEfiLoadedImageProtocol, &img);
"push\t$0\n\t" argc = GetDosArgv(img->LoadOptions, ea->argblock, ARG_MAX, ea->args,
"xor\t%edi,%edi\n\t" ARRAYLEN(ea->args));
asm("push\t$0\n\t" /* auxv[0][1] */
"push\t$0\n\t" /* auxv[0][0] */
"push\t$0\n\t" /* envp[0] */
"sub\t%2,%%rsp\n\t"
"mov\t%%rsp,%%rdi\n\t"
"rep movsb\n\t" /* argv */
"push\t%0\n\t" /* argc */
"xor\t%%edi,%%edi\n\t"
".weak\t_start\n\t" ".weak\t_start\n\t"
"jmp\t_start"); "jmp\t_start"
: /* no outputs */
: "a"(argc), "S"(ea->args), "c"((argc + 1) * 8));
unreachable; unreachable;
} }