From 025fab14d053052e8bc3a1433aeede52d0b55b22 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 5 Jun 2021 09:06:00 +0300 Subject: [PATCH] initial commit --- .gdbinit | 3 ++ .gitignore | 7 ++++ Makefile | 33 +++++++++++++++ NOTES | 76 +++++++++++++++++++++++++++++++++++ efitest.asm | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hdr.asm | 64 ++++++++++++++++++++++++++++++ 6 files changed, 311 insertions(+) create mode 100644 .gdbinit create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 NOTES create mode 100644 efitest.asm create mode 100644 hdr.asm diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..fafe796 --- /dev/null +++ b/.gdbinit @@ -0,0 +1,3 @@ +target remote localhost:1234 +disp/i $pc +set disassembly-flavor intel diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65d44d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o +*.d +*.swp +*.bin +*.img +*.efi +disasm diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a2b0638 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +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 $< >$@ diff --git a/NOTES b/NOTES new file mode 100644 index 0000000..2ee210a --- /dev/null +++ b/NOTES @@ -0,0 +1,76 @@ +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; +}; diff --git a/efitest.asm b/efitest.asm new file mode 100644 index 0000000..2cc79a2 --- /dev/null +++ b/efitest.asm @@ -0,0 +1,128 @@ +; 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 diff --git a/hdr.asm b/hdr.asm new file mode 100644 index 0000000..c9620d4 --- /dev/null +++ b/hdr.asm @@ -0,0 +1,64 @@ +; 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: -- 1.7.10.4