Page 1 of 1

printf in EFI environment with gnuefi

Posted: Wed Feb 14, 2024 11:02 pm
by mbenatto
Hello,

I started to study a bit about writing code for the EFI environment using gnuefi, I started by the classical hello world which should be pretty straight forward.
I decided to follow https://wiki.osdev.org/GNU-EFI which guided me through the whole process of compiling my code and generating the EFI image successfully, which I'm using with QEMU
to test. However when executing the main.efi binary it seems to be printing in another encoding, resulting in a bunch of chinese characters being printed when running in no graphic mode (on
graphic mode it looks like a bunch of /r). No errors are shown.
Here you can see a chunk of my program's output to the terminal:

FS0:\> main.efi
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯
꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯꾯

The source code and the Makefile I'm using can be found at:
https://github.com/benatto/osstudy/tree ... oader/uefi

I've tried to compile one of gnuefi programs and none of the result are the same, which makes me believe it's something in the way I'm compiling the programs.

May I have your help on this? I ran out of ideas for now.

Thanks in advance,

Re: printf in EFI environment with gnuefi

Posted: Thu Feb 15, 2024 1:51 am
by klange
No errors are shown.
Really?

Code: Select all

gcc -Ignu-efi/inc -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar \
-ggdb -mno-red-zone -maccumulate-outgoing-args -c main.c -o main.o
main.c: In function ‘efi_main’:
main.c:9:24: error: ‘msg’ undeclared (first use in this function)
    9 |         Print(L"%s\n", msg);
      |                        ^~~
main.c:9:24: note: each undeclared identifier is reported only once for each function it appears in
make: *** [Makefile:12: main.o] Error 1
In the code you have on Github, you never define "msg". You are missing code.

UEFI is generally a UTF-16-native environment, and the "%s" format specifier in GNU-EFI's Print function expects a pointer to a UTF-16 string. The Korean hangul 꾯 is represented in UTF-16 as 0xAFAF, so you have passed in a pointer to memory that has 0xAF repeated over and over.

Re: printf in EFI environment with gnuefi

Posted: Thu Feb 15, 2024 7:53 am
by mbenatto
In the code you have on Github, you never define "msg". You are missing code.

UEFI is generally a UTF-16-native environment, and the "%s" format specifier in GNU-EFI's Print function expects a pointer to a UTF-16 string. The Korean hangul 꾯 is represented in UTF-16 as 0xAFAF, so you have passed in a pointer to memory that has 0xAF repeated over and over.
Ouch, sorry I ended up committing a wrong and incomplete version on the file. I have pushed the right version, but this is how it looks like:

Code: Select all

#include <efi.h>                                                
#include <efilib.h>                                             
                                                                
EFI_STATUS                                                      
EFIAPI                                                          
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{                                                               
    InitializeLib(ImageHandle, SystemTable);                    
    Print(L"Hello world\n");                                    
    return EFI_SUCCESS;                                         
}                                                               


Re: printf in EFI environment with gnuefi

Posted: Thu Feb 15, 2024 9:06 pm
by Octocontrabass
Whoever wrote that wiki article missed the .rodata section. It works fine once you tell objcopy to include it.

Re: printf in EFI environment with gnuefi

Posted: Thu Feb 15, 2024 9:48 pm
by mbenatto
Octocontrabass wrote:Whoever wrote that wiki article missed the .rodata section. It works fine once you tell objcopy to include it.
ouch, I haven't noticed that! Thanks, it worked fine right now!