initial commit
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 5 Jun 2021 06:06:00 +0000 (09:06 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 5 Jun 2021 06:06:00 +0000 (09:06 +0300)
.gdbinit [new file with mode: 0644]
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
NOTES [new file with mode: 0644]
efitest.asm [new file with mode: 0644]
hdr.asm [new file with mode: 0644]

diff --git a/.gdbinit b/.gdbinit
new file mode 100644 (file)
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 (file)
index 0000000..65d44d9
--- /dev/null
@@ -0,0 +1,7 @@
+*.o
+*.d
+*.swp
+*.bin
+*.img
+*.efi
+disasm
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
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 (file)
index 0000000..2cc79a2
--- /dev/null
@@ -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 (file)
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: