NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: unixman on December 29, 2015, 02:51:50 PM
-
hi friends. i am trying to make a uefi "hello world" application with nasm.
i wants it be written as pure assembly code and not any C library included.
Then it will run on my x86_64 version 2.31 uefi firmware on my laptop.
i dont type the same so related question asks by me is there:
https://bbs.archlinux.org/viewtopic.php?id=206763
Someone help me a bit please.
is The uefi firmware push uefi app arguments (imegehandle and systab) to stack or load it rcx and rdx registers?
How about relocation things? i have to put some code into ".reloc" section? what be is it in this simple case?
i am on Linux so use gcc toolchains. How about my linker(ld) flags? i have to use "-shared -Bdynamic" as flags?
Should i use nasm's "wrt ...gotpc" mechanism? thanks.
-
Hi unixman, I'm not the expert but having done both nasm and uefi work, I would guess that you want to ignore the GCC tool chain and just use nasm to create raw binaries. But this means you will have to understand the uefi ABI (know the entry point to your code and the memory map and system calls that your program will need to use) and create the data structures that make your binary look like a valid uefi executable. It should all be documented in various uefi docs so it shouldn't be too hard, but I'll bet you won't need anything but nasm.
-
@duanev thank you for your reply. appreticated.
... but having done both nasm and uefi work
if you(or someone) already have a "hello-world-uefi" (i means pure assembly no C code/library included) please share.
I would guess that you want to ignore the GCC tool chain and just use nasm to create raw binaries. But this means you will have to understand the uefi ABI (know the entry point to your code and the memory map and system calls that your program will need to use) and create the data structures that make your binary look like a valid uefi executable. It should all be documented in various uefi docs so it shouldn't be too hard, but I'll bet you won't need anything but nasm.
Make sense. i am already dont like to have to depend gcc or any other toolchains to build uefi executable. i will try this way.
im hoping i will figure out needed stuff and implement them.
By the way why below code returns "nasm.asm:14: error: ELF64 requires ..gotoff references to be qword"?
"nasm -f elf64 nasm.asm"
bits 64
section .text
global _start:function, hello:data (16)
extern _GLOBAL_OFFSET_TABLE_
_start:
sub rsp, 32
add rbx, _GLOBAL_OFFSET_TABLE_+$$-_start wrt ..gotpc
mov rcx, [rdx+60]
mov rdi, [rdx+68]
mov rdx, [rbx+hello wrt ..gotoff]
call [rdi]
add rsp, 32
mov rax, 0
retn
section .data
hello db 'h',0,'e',0,'l',0,'l',0,'o',0,10,0,13,0,0,0
section .reloc
label1:
dq 0
EDIT: i found this but for fasm assembler.im on linux.
http://x86asm.net/articles/uefi-programming-first-steps/
format pe64 dll efi
entry main
section '.text' code executable readable
include 'efi.inc'
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]
call [rcx + SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString]
add rsp, 4*8
mov eax, EFI_SUCCESS
retn
section '.data' data readable writeable
Handle dq ?
SystemTable dq ?
_hello du 'Hello World',13,10,'(From EFI app written in FASM)',13,10,0
section '.reloc' fixups data discardable
thanks.
-
it is a bit late that i managed to success!
its so simple as just put a pe32(efi) header in front of code then compile with "nasm -f bin". code below.
bits 64
section .header
DOS:
dw 0x5a4d ;e_magic
times 29 dw 0 ;unused
dd 0x40 ;e_lfanew
PECOFF:
dd `PE\0\0` ;Signature
dw 0x8664 ;Machine
dw 3 ;NumberOfSections
dd 0 ;TimeDateStamp
dd 0 ;PointerToSymbolTable
dd 0 ;NumberOfSymbols
dw 160 ;SizeOfOptionalHeader
dw 0x202 ;Characteristics
dw 0x20b ;Magic
db 0 ;MajorLinkerVersion
db 0 ;MinorLinkerVersion
dd 0x200 ;SizeOfCode
dd 0x400 ;SizeOfInitializedData
dd 0 ;SizeOfUninitializedData
dd 0x0 ;AddressOfEntryPoint
dd 0x0 ;BaseOfCode
dq 0x0 ;ImageBase
dd 0x1000 ;SectionAlignment
dd 0x200 ;FileAlignment
dw 0 ;MajorOperatingSystemVersion
dw 0 ;MinorOperatingSystemVersion
dw 0 ;MajorImageVersion
dw 0 ;MinorImageVersion
dw 0 ;MajorSubsystemVersion
dw 0 ;MinorSubsystemVersion
dd 0 ;Reserved
dd 0x3000 ;SizeOfImage
dd 0x200 ;SizeOfHeaders
dd 0 ;CheckSum
dw 10 ;Subsystem
dw 0 ;DllCharacteristics
dq 0 ;SizeOfStackReserve
dq 0 ;SizeOfStackCommit
dq 0 ;SizeOfHeapReserve
dq 0 ;SizeOfHeapCommit
dd 0 ;LoaderFlags
dd 6 ;NumberOfRvaAndSizes
DIRS:
times 40 db 0 ;unused dirs for this app
dd 0x1000 ;VirtualAddress(.reloc)
dd 8 ;Size(.reloc)
SECTS:
.1:
dq `.text` ;Name
dd codesize ;VirtualSize
dd 0x0 ;VirtualAddress
dd 0x200 ;SizeOfRawData
dd 0x200 ;PointerToRawData
dd 0 ;PointerToRelocations
dd 0 ;PointerToLinenumbers
dw 0 ;NumberOfRelocations
dw 0 ;NumberOfLinenumbers
dd 0x60500020 ;Characteristics
.2:
dq `.reloc`
dd 0x8
dd 0x1000
dd 0x200
dd 0x400
dd 0
dd 0
dw 0
dw 0
dd 0x42100040
.3:
dq `.data`
dd datasize
dd 0x2000
dd 0x200
dd 0x600
dd 0
dd 0
dw 0
dw 0
dd 0xc0100040
section .text follows=.header align=0x200
sub rsp, 40
mov rcx, [rdx+64]
lea rdx, [rel hello]
call [rcx+8]
add rsp, 40
ret
codesize equ $ - $$
section .reloc follows=.text align=0x200
dd 0 ;PageRVA
dd 8 ;BlockSize
section .data follows=.reloc align=0x200 vstart=0x2200
hello:
db __utf16__ `hello world!\n\r\0`
datasize equ $ - $$
align 0x200,db 0
-
I just tested this code on the latest versions of VMWare (12.5) and tried to run it from the full shell of EDK2. It does not work.
-
Hi mnasm,
Welcome to the forum. "It does not work" doesn't give us a lot of information. Any symptoms?
Best,
Frank
-
UEFI fails to load it. It doesn't give any error messages if it is renamed BOOTX64.EFI. If you run it from the shell, its not a valid program. I have another hello world example written in FASM and it works fine in both scenarios.
-
Here is a little more detail. This is the error that is returned in the shell. As I said, on boot, it fails to load this. Although a similar FASM program functions fine.
(http://i.imgur.com/Ld3CKnj.jpg)
I tried replacing the PE header with a PE macro that builds the exe. I tried this with both PE64 and DLL64. Both fail. The key difference between the FASM program and the NASM program, is that the FASM program has structures for EFI, as well as an EFI macro. The source code of the FASM program can be found at the end of this guide http://x86asm.net/articles/uefi-programming-first-steps/ (http://x86asm.net/articles/uefi-programming-first-steps/).
I'm presuming at this point that VMware has a strict implementation of UEFI and cannot boot simple PE files. It requires some EFI format.