diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd6072d --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +NASM = nasm +NASMFLAGS = -f win64 +STANDALONE_FLAGS = -Dfill_sector + +LINKER = clang +LLD-FLAGS = --target=x86_64-unknown-windows -nostdlib -Wl,-entry:_start -Wl,-subsystem:efi_application -fuse-ld=lld + +SRC_DIR = . +SRC = $(wildcard $(SRC_DIR)/*.asm) + +OBJ_DIR = . +OBJ = $(SRC:.asm=.obj) + +EFI = uefi.efi +BIOS = bios.bin +BOOT_DRIVE = uefi.img + +.PHONY: clean qemu all standalone vhd + +all: $(OBJ) + $(LINKER) $(LLD-FLAGS) -o $(EFI) $< + +standalone: NASMFLAGS += $(STANDALONE_FLAGS) +standalone: $(OBJ) + +clean: + rm -f $(OBJ) $(BOOT_DRIVE) $(EFI) + +qemu: + qemu-system-x86_64 -bios $(BIOS) -drive file=$(BOOT_DRIVE),format=raw + +# needs dosfstools and mtools +vhd: + dd if=/dev/zero of=$(BOOT_DRIVE) bs=1M count=1 + mkfs.vfat $(BOOT_DRIVE) + mmd -i $(BOOT_DRIVE) ::EFI + mmd -i $(BOOT_DRIVE) ::EFI/BOOT + mcopy -i $(BOOT_DRIVE) uefi.efi ::EFI/BOOT/BOOTX64.EFI + +%.obj: %.asm + $(NASM) $(NASMFLAGS) -o $@ $< diff --git a/bios.bin b/bios.bin new file mode 100644 index 0000000..042188c Binary files /dev/null and b/bios.bin differ diff --git a/uefi.asm b/uefi.asm new file mode 100644 index 0000000..a59e823 --- /dev/null +++ b/uefi.asm @@ -0,0 +1,80 @@ +; generate 64-bit code +bits 64 + +; contains the code that will run +section .text + +; allows the linker to see this symbol +global _start + +; see http://www.uefi.org/sites/default/files/resources/UEFI Spec 2_7_A Sept 6.pdf#G8.1001729 +struc EFI_TABLE_HEADER + .Signature RESQ 1 + .Revision RESD 1 + .HeaderSize RESD 1 + .CRC32 RESD 1 + .Reserved RESD 1 +endstruc + +; see http://www.uefi.org/sites/default/files/resources/UEFI Spec 2_7_A Sept 6.pdf#G8.1001773 +struc EFI_SYSTEM_TABLE + .Hdr RESB EFI_TABLE_HEADER_size + .FirmwareVendor RESQ 1 + .FirmwareRevision RESD 1 + .ConsoleInHandle RESQ 1 + .ConIn RESQ 1 + .ConsoleOutHandle RESQ 1 + .ConOut RESQ 1 + .StandardErrorHandle RESQ 1 + .StdErr RESQ 1 + .RuntimeServices RESQ 1 + .BootServices RESQ 1 + .NumberOfTableEntries RESQ 1 + .ConfigurationTable RESQ 1 +endstruc + +; see http://www.uefi.org/sites/default/files/resources/UEFI Spec 2_7_A Sept 6.pdf#G16.1016807 +struc EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + .Reset RESQ 1 + .OutputString RESQ 1 + .TestString RESQ 1 + .QueryMode RESQ 1 + .SetMode RESQ 1 + .SetAttribute RESQ 1 + .ClearScreen RESQ 1 + .SetCursorPosition RESQ 1 + .EnableCursor RESQ 1 + .Mode RESQ 1 +endstruc + + +_start: + ; reserve space for 4 arguments + sub rsp, 4 * 8 + + ; rdx points to the EFI_SYSTEM_TABLE structure + ; which is the 2nd argument passed to us by the UEFI firmware + ; adding 64 causes rcx to point to EFI_SYSTEM_TABLE.ConOut + mov rcx, [rdx + 64] + + ; load the address of our string into rdx + lea rdx, [rel strHello] + + ; EFI_SYSTEM_TABLE.ConOut points to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + ; call OutputString on the value in rdx + call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString] + + ; loop forever so we can see the string before the UEFI application exits + jmp $ + +codesize equ $ - $$ + +; contains nothing - but it is required by UEFI +section .reloc + +; contains the data that will be displayed +section .data + ; this must be a Unicode string + strHello db __utf16__ `Hello World !\0` + +datasize equ $ - $$ diff --git a/uefi.efi b/uefi.efi new file mode 100644 index 0000000..74ba488 Binary files /dev/null and b/uefi.efi differ diff --git a/uefi.img b/uefi.img new file mode 100644 index 0000000..2ab46de Binary files /dev/null and b/uefi.img differ diff --git a/uefi.obj b/uefi.obj new file mode 100644 index 0000000..6e1846f Binary files /dev/null and b/uefi.obj differ