Author Topic: [solved]uefi hello world app with nasm  (Read 10114 times)

Offline unixman

  • Jr. Member
  • *
  • Posts: 3
[solved]uefi hello world app with nasm
« 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.
« Last Edit: January 26, 2016, 03:33:16 PM by unixman »

Offline duanev

  • Jr. Member
  • *
  • Posts: 4
Re: uefi hello world app with nasm
« Reply #1 on: December 30, 2015, 03:06:07 AM »
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.

Offline unixman

  • Jr. Member
  • *
  • Posts: 3
Re: uefi hello world app with nasm
« Reply #2 on: December 30, 2015, 10:42:01 AM »
@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"

Code: [Select]
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/

Code: [Select]
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.
« Last Edit: December 30, 2015, 10:52:17 AM by unixman »

Offline unixman

  • Jr. Member
  • *
  • Posts: 3
Re: uefi hello world app with nasm
« Reply #3 on: January 26, 2016, 03:31:46 PM »
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.

Code: [Select]
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


Offline mnasm

  • Jr. Member
  • *
  • Posts: 3
Re: [solved]uefi hello world app with nasm
« Reply #4 on: September 29, 2016, 07:13:38 AM »
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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2498
  • Country: us
Re: [solved]uefi hello world app with nasm
« Reply #5 on: September 29, 2016, 07:41:56 AM »
Hi mnasm,

Welcome to the forum. "It does not work" doesn't give us a lot of information. Any symptoms?

Best,
Frank


Offline mnasm

  • Jr. Member
  • *
  • Posts: 3
Re: [solved]uefi hello world app with nasm
« Reply #6 on: September 29, 2016, 08:06:59 AM »
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.

Offline mnasm

  • Jr. Member
  • *
  • Posts: 3
Re: [solved]uefi hello world app with nasm
« Reply #7 on: September 29, 2016, 06:55:49 PM »
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.



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/.

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.