diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e608a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.code-workspace +*.efi +image/ \ No newline at end of file diff --git a/OVMF.fd b/OVMF.fd new file mode 100644 index 0000000..4e63653 Binary files /dev/null and b/OVMF.fd differ diff --git a/bootx64.asm b/bootx64.asm new file mode 100644 index 0000000..c75ee42 --- /dev/null +++ b/bootx64.asm @@ -0,0 +1,150 @@ +format pe64 dll efi +entry main + +section '.text' code executable readable + + + +;for 32/64 portability and automatic natural align in structure definitions + +struc int8 { + . db ? +} +struc int16 { + align 2 + . dw ? +} +struc int32 { + align 4 + . dd ? +} +struc int64 { + align 8 + . dq ? +} +struc intn { + align 8 + . dq ? +} +struc dptr { + align 8 + . dq ? +} + +;symbols + +EFIERR = 0x8000000000000000 +EFI_SUCCESS = 0 +EFI_LOAD_ERROR = EFIERR or 1 +EFI_INVALID_PARAMETER = EFIERR or 2 +EFI_UNSUPPORTED = EFIERR or 3 +EFI_BAD_BUFFER_SIZE = EFIERR or 4 +EFI_BUFFER_TOO_SMALL = EFIERR or 5 +EFI_NOT_READY = EFIERR or 6 +EFI_DEVICE_ERROR = EFIERR or 7 +EFI_WRITE_PROTECTED = EFIERR or 8 +EFI_OUT_OF_RESOURCES = EFIERR or 9 +EFI_VOLUME_CORRUPTED = EFIERR or 10 +EFI_VOLUME_FULL = EFIERR or 11 +EFI_NO_MEDIA = EFIERR or 12 +EFI_MEDIA_CHANGED = EFIERR or 13 +EFI_NOT_FOUND = EFIERR or 14 +EFI_ACCESS_DENIED = EFIERR or 15 +EFI_NO_RESPONSE = EFIERR or 16 +EFI_NO_MAPPING = EFIERR or 17 +EFI_TIMEOUT = EFIERR or 18 +EFI_NOT_STARTED = EFIERR or 19 +EFI_ALREADY_STARTED = EFIERR or 20 +EFI_ABORTED = EFIERR or 21 +EFI_ICMP_ERROR = EFIERR or 22 +EFI_TFTP_ERROR = EFIERR or 23 +EFI_PROTOCOL_ERROR = EFIERR or 24 + +;helper macro for definition of relative structure member offsets + +macro struct name +{ + virtual at 0 + name name + end virtual +} + +;structures + +struc EFI_TABLE_HEADER { + .Signature int64 + .Revision int32 + .HeaderSize int32 + .CRC32 int32 + .Reserved int32 +} +struct EFI_TABLE_HEADER + +struc EFI_SYSTEM_TABLE { + .Hdr EFI_TABLE_HEADER + .FirmwareVendor dptr + .FirmwareRevision int32 + .ConsoleInHandle dptr + .ConIn dptr + .ConsoleOutHandle dptr + .ConOut dptr + .StandardErrorHandle dptr + .StdErr dptr + .RuntimeServices dptr + .BootServices dptr + .NumberOfTableEntries intn + .ConfigurationTable dptr +} +struct EFI_SYSTEM_TABLE + +struc SIMPLE_TEXT_OUTPUT_INTERFACE { + .Reset dptr + .OutputString dptr + .TestString dptr + .QueryMode dptr + .SetMode dptr + .SetAttribute dptr + .ClearScreen dptr + .SetCursorPosition dptr + .EnableCursor dptr + .Mode dptr +} +struct SIMPLE_TEXT_OUTPUT_INTERFACE + + + +main: + sub rsp, 4*8 ; reserve space for 4 arguments + + mov [Handle], rcx ; ImageHandle + mov [SystemTable], rdx ; pointer to SystemTable + + lea rdx, [_hello] + mov rcx, [SystemTable] + mov rcx, [rcx + EFI_SYSTEM_TABLE.ConOut] + push rcx rdx + call [rcx + SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen] ;; TODO : what calling convention? clobbers rcx, what else? + ; TODO: use more modern UEFI.inc like stuff + ; TODO: update scripts build run. maybe makefile, also generating iso? + ; TODO: what is NvVars who generates it why it need + ; TODO: print some info provided by eufi like versions etc.. + ; TODO: print memory map + ; TODO: how to load kernel . See https://github.com/BrianOtto/nasm-uefi + pop rdx rcx + call [rcx + SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString] + + jmp $ + + add rsp, 4*8 + mov eax, EFI_SUCCESS + retn + + +section '.data' data readable writeable + +Handle dq ? +SystemTable dq ? +_hello du 'Hello World',13,10,0 + +section '.reloc' fixups data discardable + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..71ae609 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +fasm bootx64.asm +mkdir -p image/EFI/BOOT +cp bootx64.efi image/EFI/BOOT +qemu-system-x86_64 -cpu qemu64 -bios OVMF.fd -drive driver=vvfat,rw=on,dir=image/