flat assembler
Message board for the users of flat assembler.

flat assembler > Examples and Tutorials > UEFI basics tutorial by MrFox

Author
Thread Post new topic Reply to topic
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
Hello. I've been learning UEFI for a few months and I would like to start a series of tutorials to share what I have learned by now. Traditionally, programming in a new environment starts off with a 'Hello world' program.
Here it is (code and some explanations in comments):
Code:
; ; Hello.asm ; Hello UEFI in assembly ; Flat Assembler v1.71.54 ; 2016 MrFox ; ; Symbols and structures ; The UEFI favorite data type: Unsigned Integer Native width ; (32-bit width in 32-bit systems, 64-bit in 64-bit systems) ; I use 32-bit width because my EFI is 32-bit (rd) ; Data alignment must be same as width ; (all UEFI data stuff must be native aligned) struc UINTN { align 4 . rd 1 } ; Error codes EFI_SUCCESS = 0 EFIERR = 0x80000000 EFI_LOAD_ERROR = EFIERR or 1 EFI_INVALID_PARAMETER = EFIERR or 2 EFI_UNSUPPORTED = EFIERR or 3 ; Etc (more error codes in EFI spec) ; Our program on entry gets two pointers as arguments: ; ImageHandle and SystemTable (see below at the beginning of code) ; ImageHandle is just like an ID of our running app ; SystemTable is just a table somewhere in memory ; which contains pointers to all functionality of UEFI ; (without it our program is blind and can't contact with UEFI ; functions just because it doesn't know where they are) ; SystemTable structure virtual at 0 EFI_SYSTEM_TABLE: ; Table header .Signature rq 1 .Revision UINTN .HeaderSize UINTN .CRC32 UINTN .Reserved UINTN ; Rest of the table .FirmwareVendor UINTN .FirmwareRevision UINTN .ConsoleInHandle UINTN .ConIn UINTN .ConsoleOutHandle UINTN .ConOut UINTN ; We need this one to handle screen output .StandardErrorHandle UINTN .StdErr UINTN .RuntimeServices UINTN .BootServices UINTN .NumberOfTableEntries UINTN .ConfigurationTable UINTN end virtual ; Simple Text Output is a Protocol (like just a set of functions). ; The ConOut pointer in SystemTable (above) points to the memory address ; where the table described just below is located. ; The table itself contains memory addresses to 'call' ; if we want to use a specific UIFI function virtual at 0 SIMPLE_TEXT_OUTPUT: .Reset UINTN .OutputString UINTN ; Calling this address will run this function .TestString UINTN .QueryMode UINTN .SetMode UINTN .SetAttribute UINTN .ClearScreen UINTN .SetCursorPosition UINTN .EnableCursor UINTN .Mode UINTN end virtual ; Some initial format settings for the linker regarding ; the executable file format used by UEFI format pe dll efi entry main section '.text' code executable readable ; Program entry point main: push ebp ; get args (ImageHandle and SystemTable pointers) mov eax, [esp+8] mov [ImageHandle], eax mov ebx, [esp+12] mov [SystemTable], ebx ; Call OutputString function of SIMPLE_TEXT_OUTPUT protocol ; Function OutputString when entered, looks for two args in the stack: ; 1. The address of the zero-ended UCS2 string to print ; 2. The address of the Simple Text Output interface (aka *This in C language) ; so we 'push' them before calling the function and then ; restore the stack pointer (add esp,8 ) when the function returns ; 8 is the total size of our two args of type UINTN ; More info is in UEFI spec, page 474 (UEFI Specification Version 2.6) ; http://www.uefi.org/specifications ; Pay attention to the reversed order of the arguments pushed on stack lea eax, [Text] push eax ; This is out text address mov eax, [SystemTable] mov ebx, [eax+EFI_SYSTEM_TABLE.ConOut] push ebx ; push ConOut address and call one of its functions call [ebx+SIMPLE_TEXT_OUTPUT.OutputString] add esp, 8 ; restore stack pointer (UEFI uses C calling convention) ; so restoring stack pointer is caller's responsibility ; Exit program mov eax, EFI_SUCCESS pop ebp ret section '.data' data readable writeable ImageHandle dd ? SystemTable dd ? Text du 'Hello UEFI',13,10,0 ; 13 and 10 are Line Feed and Form Feed characters section '.reloc' fixups data discardable

To run the program, compile it with fasm and put your .EFI file somewhere on a FAT-32 partition. Then reboot and enter the boot menu of your PC. Either find your file on bootable media via 'Boot from file' option or select 'Internal EFI Shell' and use shell commands to run it.

A quick rundown on shell commands:
(to run a command or file just type it in command prompt and press enter)
map - shows all partitions accessible for UEFI, formatted like 'fs0, fs1, etc'.
fs0: - select partition (FileSystem) #0 (fs1:, fs2:, etc)
dir - show contents of current directory
cd dirname - changes directory
yourfilename(.efi) - starts your .EFI file
exit - exits Shell and goes back to your boot menu or whatever (implementation specific, I guess). CTRL+ALT+DEL also works unless your app "hung" the PC. Use "anykey" then Wink

That's all, report bugs, ask questions, see ya soon...


Description: Hello World in UEFI
Download
Filename: Hello.asm
Filesize: 3.79 KB
Downloaded: 127 Time(s)

Post 04 Nov 2016, 07:07
View user's profile Send private message Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
Hi again.
Today we'll continue exploring SIMPLE_TEXT_OUTPUT protocol and see what else we can do with it. Today's task is to print a colored line of text in the center of the screeen. To do this, we'll have to get the screen resolution (in characters) and put the cursor to Height/2 and (Width-LenOfString)/2. Then, we'll set up the colors and finally print the text.

Here's the code:
Code:
; ; Center.asm ; Center colored string in UEFI in assembly ; Flat Assembler v1.71.54 ; 2016 MrFox ; ; Symbols and structures ; The UEFI favorite data type: Unsigned Integer Native width ; (32-bit width in 32-bit systems, 64-bit in 64-bit systems) ; I use 32-bit width because my EFI is 32-bit (rd) ; Data alignment must be same as width ; (all UEFI data stuff must be native aligned) struc UINTN { align 4 . rd 1 } ; Error codes EFI_SUCCESS = 0 EFIERR = 0x80000000 EFI_LOAD_ERROR = EFIERR or 1 EFI_INVALID_PARAMETER = EFIERR or 2 EFI_UNSUPPORTED = EFIERR or 3 ; Etc (more error codes in EFI spec) ; Console Colors EFI_RED = 0x04 EFI_YELLOW = 0x0E EFI_BACKGROUND_BLUE = 0x10 EFI_BACKGROUND_GREEN = 0x20 EFI_BACKGROUND_RED = 0x40 ; more colors in the Specification ; SystemTable structure virtual at 0 EFI_SYSTEM_TABLE: ; Table header .Signature rq 1 .Revision UINTN .HeaderSize UINTN .CRC32 UINTN .Reserved UINTN ; Rest of the table .FirmwareVendor UINTN .FirmwareRevision UINTN .ConsoleInHandle UINTN .ConIn UINTN .ConsoleOutHandle UINTN .ConOut UINTN ; We need this one to handle screen output .StandardErrorHandle UINTN .StdErr UINTN .RuntimeServices UINTN .BootServices UINTN .NumberOfTableEntries UINTN .ConfigurationTable UINTN end virtual ; Simple Text Output is a Protocol (like just a set of functions). ; The ConOut pointer in SystemTable (above) points to the memory address ; where the table described just below is located. ; The table itself contains memory addresses to 'call' ; if we want to use a specific UIFI function virtual at 0 SIMPLE_TEXT_OUTPUT: .Reset UINTN .OutputString UINTN ; Calling this address will run this function .TestString UINTN .QueryMode UINTN .SetMode UINTN .SetAttribute UINTN .ClearScreen UINTN .SetCursorPosition UINTN .EnableCursor UINTN .Mode UINTN end virtual ; This structure is used to get Viewport mode (GetMode function) virtual at 0 SIMPLE_TEXT_OUTPUT_MODE: .MaxMode UINTN .Mode UINTN .Attribute UINTN .CursorColumn UINTN .CursorRow UINTN .CursorVisible rb 1 end virtual ; Some initial format settings for the linker regarding ; the executable file format used by UEFI format pe dll efi entry main section '.text' code executable readable ; Program entry point main: push ebp ; 1. Get arguments that UEFI passed to my program ; 1.1. Get ImageHandle mov eax, [esp+8] mov [ImageHandle], eax ; 1.2. Get SystemTable mov ebx, [esp+12] mov [SystemTable], ebx ; 2. Get screen width and height ; 2.1. Get where ConOut protocol is located mov ebx, [SystemTable] mov ebp, [ebx+EFI_SYSTEM_TABLE.ConOut] ; 2.2. Get Console viewport width and height ; 2.2.1. Get CurrentScreenMode structure location mov eax, [ebp+SIMPLE_TEXT_OUTPUT.Mode] ; 2.2.2. Get Mode Number into ECX mov ecx, [eax+SIMPLE_TEXT_OUTPUT_MODE.Mode] ; 2.2.3. Load variables to receive data lea eax, [ScreenHeight] lea ebx, [ScreenWidth] ; 2.2.4. Send arguments to function push eax ; Height push ebx ; Width push ecx ; Mode number push ebp ; *This call [ebp+SIMPLE_TEXT_OUTPUT.QueryMode] add esp, 16 ; Clean the stack ; 3. Clear screen (to current colors, which are white on black I think) push ebp call [ebp+SIMPLE_TEXT_OUTPUT.ClearScreen] add esp,4 ; 4. Set screen Background and Foreground mov eax,EFI_YELLOW or EFI_BACKGROUND_BLUE push eax push ebp call [ebp+SIMPLE_TEXT_OUTPUT.SetAttribute] add esp,8 ; 5. Set Cursor Position to center ; 5.1. Some math first mov edx,[ScreenHeight] shr edx,1 ; Division by two mov eax,[ScreenWidth] sub eax,10 ; Length of the string shr eax,1 ; Division by two ; 5.2. Sending the coordinates to put the cursor push edx ; Row push eax ; Column push ebp ; *This call [ebp+SIMPLE_TEXT_OUTPUT.SetCursorPosition] add esp,12 ; 6. Now it's time to print the text lea eax, [Text] push eax ; This is our text address push ebp call [ebp+SIMPLE_TEXT_OUTPUT.OutputString] add esp, 8 ; restore stack pointer (UEFI uses C calling convention) ; 7. Set the coordinates back to 0,0 pushd 0 ; Row pushd 0 ; Column push ebp ; *This call [ebp+SIMPLE_TEXT_OUTPUT.SetCursorPosition] add esp,12 ; 8. Set the colors to RED on BLACK pushd EFI_RED push ebp call [ebp+SIMPLE_TEXT_OUTPUT.SetAttribute] add esp,8 ; 8. Exit program mov eax, EFI_SUCCESS pop ebp ret section '.data' data readable writeable ImageHandle dd ? SystemTable dd ? ScreenWidth dd 0 ScreenHeight dd 0 Text du 'Hello UEFI',0 section '.reloc' fixups data discardable


Description: Prints colored line of text in the center of the screen
Download
Filename: Center.asm
Filesize: 4.74 KB
Downloaded: 123 Time(s)

Post 11 Nov 2016, 11:41
View user's profile Send private message Reply with quote
ford



Joined: 21 Jan 2010
Posts: 102
I like it. Keep it coming Smile
Post 15 Nov 2016, 03:41
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.