--- /dev/null
+target remote localhost:1234
+disp/i $pc
+set disassembly-flavor intel
--- /dev/null
+*.o
+*.d
+*.swp
+*.bin
+*.img
+*.efi
+disasm
--- /dev/null
+bootx64.efi: efitest.bin hdr.asm
+ nasm -o $@ -f bin hdr.asm
+
+efitest.bin: efitest.asm
+ nasm -o $@ -f bin $<
+
+part.img: bootx64.efi
+ dd if=/dev/zero of=$@ bs=1024 count=2080
+ mkfs -t vfat $@
+ mmd -i $@ ::/EFI
+ mmd -i $@ ::/EFI/BOOT
+ mcopy -i $@ $< ::/EFI/BOOT
+
+disk.img: part.img
+ dd if=/dev/zero of=$@ bs=1024 count=2048
+ echo start=2048 type=ef | sfdisk $@
+ dd if=$< of=$@ bs=512 seek=2048 conv=notrunc
+
+.PHONY: clean
+clean:
+ rm -f bootx64.efi efitest.bin
+
+.PHONY: run
+run: disk.img
+ qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -hda $<
+
+.PHONY: debug
+debug: disk.img
+ qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -S -s -hda $<
+
+
+disasm: bootx64.efi
+ ndisasm -b 64 -o 0x100000 -e 4096 $< >$@
--- /dev/null
+UEFI notes
+==========
+
+/efi/boot/bootx64.efi
+
+rcx: efi handle
+rdx: efi system table pointer
+rsp: return address?
+
+after loading call EFI_BOOT_SERVICES.ExitBootServices()
+
+struct EFI_TABLE_HEADER {
+ uint64_t signature;
+ uint32_t revision;
+ uint32_t header_size;
+ uint32_t crc32;
+ uint32_t rsvd;
+};
+
+EFI_SYSTEM_TABLE signature: 0x5453595320494249
+0 EFI_TABLE_HEADER
+24 wchar_t *firmware_vendor
+32 uint32_t firmware_revision
+36 padding
+40 void *console_in_handle
+48 EFI_SIMPLE_TEXT_INPUT_PROTOCOL*
+56 void *console_out_handle
+64 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
+72 EFI_RUNTIME_SERVICES *runtime_services;
+80 EFI_BOOT_SERVICES *boot_services;
+ uint64_t num_of_table_entries;
+ EFI_CONFIGURATION_TABLE *cfg_table;
+
+EFI_BOOT_SERVICES signature: 0x56524553544f4f42
+0 EFI_TABLE_HEADER
+24 EFI_RAISE_TPL
+32 EFI_RESTORE_TPL
+40 EFI_ALLOCATE_PAGES
+48 EFI_FREE_PAGES
+56 EFI_GET_MEMORY_MAP
+64 EFI_ALLOCATE_POOL
+72 EFI_FREE_POOL
+80 EFI_CREATE_EVENT
+88 EFI_SET_TIMER
+96 EFI_WAIT_FOR_EVENT
+104 EFI_SIGNAL_EVENT
+112 EFI_CLOSE_EVENT
+120 EFI_CHECK_EVENT
+128 EFI_INSTALL_PROTOCOL_INTERFACE
+136 EFI_REINSTALL_PROTOCOL_INTERFACE
+144 EFI_UNINSTALL_PROTOCOL_INTERFACE
+152 EFI_HANDLE_PROTOCOL
+160 void *rsvd
+168 EFI_REGISTER_PROTOCOL_NOTIFY
+176 EFI_LOCATE_HANDLE
+184 EFI_LOCATE_DEVICE_PATH
+192 EFI_INSTALL_CONFIGURATION_TABLE
+200 EFI_IMAGE_LOAD
+208 EFI_IMAGE_START
+216 EFI_EXIT
+224 EFI_IMAGE_UNLOAD
+232 EFI_EXIT_BOOT_SERVICES
+ ... more ...
+
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
+0 EFI_TEXT_RESET
+8 EFI_TEXT_STRING
+16 EFI_TEXT_TEST_STRING
+24 EFI_TEXT_QUERY_MODE
+32 EFI_TEXT_SET_MODE
+40 EFI_TEXT_SET_ATTRIBUTE
+48 EFI_TEXT_CLEAR_SCREEN
+56 EFI_TEXT_SET_CURSOR_POSITION
+64 EFI_TEXT_ENABLE_CURSOR
+72 SIMPLE_TEXT_OUPUT_MODE *mode;
+};
--- /dev/null
+; vi:ft=nasm:
+ bits 64
+ org 100000h
+ default rel
+
+ ; EFI_SYSTEM_TABLE offsets
+SIMPLE_TEXT_OUTPUT equ 64
+BOOT_SERVICES equ 80
+
+ ; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL function offsets
+TEXT_OUT_STRING equ 8
+TEXT_SET_ATTR equ 40
+TEXT_CLEAR_SCREEN equ 48
+
+ ; EFI_BOOT_SERVICES function offsets
+BOOT_GET_MEMORY_MAP equ 56
+BOOT_EXIT_BOOT_SERVICES equ 232
+
+
+start:
+ mov [efihandle], rcx
+ mov [systab], rdx
+
+ mov rax, [rdx + BOOT_SERVICES]
+ mov [bootsrv], rax
+ sub rsp, 32 ; leave space for shadow area
+ and rsp, 0xfffffffffffffff0 ; make sure sp is 16-byte aligned
+
+ mov rcx, [rdx + SIMPLE_TEXT_OUTPUT]
+ mov rdx, 0x0c
+ call [rcx + TEXT_SET_ATTR]
+
+ mov rax, [systab]
+ mov rcx, [rax + SIMPLE_TEXT_OUTPUT]
+ call [rcx + TEXT_CLEAR_SCREEN]
+
+ mov rax, [systab]
+ mov rcx, [rax + SIMPLE_TEXT_OUTPUT]
+ lea rdx, [str_hello]
+ call [rcx + TEXT_OUT_STRING]
+
+
+ mov rax, [systab]
+ mov rcx, [rax + SIMPLE_TEXT_OUTPUT]
+ mov rdx, 0x07
+ call [rcx + TEXT_SET_ATTR]
+
+ call get_rip
+ mov rdi, rax
+ call printhex64
+ call newline
+
+ ; retrieve memory map
+ ; args: RCX, RDX, R8, and R9.
+ lea rcx, [mmap_size]
+ lea rdx, [mmapbuf]
+ lea r8, [mmap_key]
+ lea r9, [mmap_descsz]
+ lea rax, [mmap_descver]
+ push rax
+ push rax
+ mov rax, [systab]
+ mov rbx, [rax + BOOT_SERVICES]
+ call [rbx + BOOT_GET_MEMORY_MAP]
+ add rsp, 16
+
+ mov rcx, [efihandle]
+ mov rdx, [mmap_key]
+ mov rax, [systab]
+ mov rbx, [rax + BOOT_SERVICES]
+ call [rbx + BOOT_EXIT_BOOT_SERVICES]
+
+.hang: jmp .hang
+
+get_rip:
+ mov rax, [rsp]
+ ret
+
+ ; expects number in rdi
+printhex64:
+ mov rcx, 16
+ lea rbx, [hexbuf]
+.loop: rol rdi, 4
+ mov rax, rdi
+ and rax, 0xf
+ lea rdx, [hexdig]
+ shl rax, 1
+ add rdx, rax
+ mov ax, [rdx]
+ mov [rbx], ax
+ add rbx, 2
+ dec rcx
+ jnz .loop
+ mov word [rbx], 0
+ lea rdi, [hexbuf]
+
+ ; expects string in rdi
+printstr:
+ mov rcx, [systab]
+ mov rcx, [rcx + SIMPLE_TEXT_OUTPUT]
+ mov rdx, rdi
+ sub rsp, 32
+ call [rcx + TEXT_OUT_STRING]
+ add rsp, 32
+ ret
+
+newline:
+ lea rdi, [str_hello + 18]
+ jmp printstr
+
+hexdig dw __utf16__ "0123456789abcdef"
+hexbuf: times 40 db 0
+
+ align 8
+efihandle dq 0
+systab dq 0
+bootsrv dq 0
+str_hello dw __utf16__(`qurashee!\r\n`),0
+
+ align 8
+; memory map data
+mmap_size dq 0
+mmap_key dq 0
+mmap_descsz dq 0
+mmap_descver dq 0
+
+ align 4096
+mmapbuf: times 4096 db 0
--- /dev/null
+; vi:ft=nasm:
+ org 0
+
+ ; DOS stub
+ db "MZ"
+ times 3ah db 0
+ dd 40h ; PE offset
+ ; PE signature
+ db "PE",0,0
+ ; COFF header
+ dw 8664h ; machine type: x86-64
+ dw 1 ; number of sections
+ dd 0 ; creation time
+ dd 0 ; offset to symbol table
+ dd 0 ; number of symbols
+ dw opthdr_end - opthdr ; size of optional header
+ dw 2022h ; characteristics: DLL, exec image, can handle > 2gb addr
+ ; optional header - standard fields
+opthdr: dw 020bh ; magic: PE32+
+ dw 0 ; linker version
+ dd prog_end - prog ; size of code
+ dd 0 ; size of init data
+ dd 0 ; size of uninit data
+ dd prog ; entry point
+ dd prog ; base of code
+ ; optional header - windows-specific fields
+ dq 100000h ; image base
+ dd 4096 ; section alignment
+ dd 4096 ; file alignment
+ dd 0 ; os version
+ dd 0 ; img version
+ dd 0 ; subsys version
+ dd 0
+ dd image_end ; size of image
+ dd prog ; size of headers
+ dd 0 ; checksum
+ dw 10 ; subsystem: EFI application
+ dw 0040h ; DLL characteristics: relocatable at runtime
+ dq 4096 ; size of stack reserve
+ dq 4096 ; size of stack commit
+ dq 4096 ; size of heap reserve
+ dq 0 ; size of heap commit
+ dd 0
+ dd 0 ; number of rva and sizes
+opthdr_end:
+
+ ; sections
+ db ".text",0,0,0
+ dd image_end - prog ; virtual size
+ dd prog ; virtual address
+ dd image_end - prog ; raw data size
+ dd prog ; raw data
+ dd 0 ; relocations offset
+ dd 0 ; line numbers offset
+ dw 0 ; num reloc
+ dw 0 ; num line numbers
+ dd 60000020h ; characteristics: exec, readable, code
+
+ align 4096
+prog:
+ incbin "efitest.bin"
+prog_end:
+ align 4096
+image_end: