OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Apr 27, 2024 7:48 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Issues compiling UEFI application (undefined references)
PostPosted: Mon Aug 28, 2023 5:49 am 
Offline

Joined: Mon Aug 28, 2023 4:11 am
Posts: 2
Hey all,

I'm getting started with UEFI applications for a kernel project I'm working on and running into some issues with the first compilation. I've generally followed the UEFI app bare bones guide to a T, but I'm consistently hitting my head on some undefined reference errors in the final of three compilation steps (the linking of the UEFI main executable and data.o). The UEFI application I'm attempting to compile is a basic "Hello, world!" consisting of the following:

Code:
#include <efi.h>
#include <efilib.h>

EFI_STATUS EFIAPI efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    EFI_STATUS Status;
    EFI_INPUT_KEY Key;
    EFI_SYSTEM_TABLE *ST = SystemTable;
    InitializeLib(ImageHandle, SystemTable);
    Print(L"Hello, world!\r\n");

    Status = ST->ConIn->Reset(ST->ConIn, FALSE);
    if (EFI_ERROR(Status))
        return Status;
    while ((Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key)) == EFI_NOT_READY);

    return Status;
}


Build environment is a rather new install of Ubuntu 23.04, gcc-mingw-w64 version 12.2.0, binutils-mingw-w64 version 2.39.90. I've successfully installed GNU-EFI as well as made the prescribed modifications to gnuefi/lib/data.c. The error occurs on the final leg of the three-part compilation:

Code:
$ x86_64-w64-mingw32-gcc -ffreestanding -I/usr/include/efi -I/usr/include/efi/x86_64 -I/usr/include/efi/protocol -c -o uefiboot.o uefiboot.c
$ x86_64-w64-mingw32-gcc -ffreestanding -I/usr/include/efi -I/usr/include/efi/x86_64 -I/usr/include/efi/protocol -c -o data.o /usr/lib/data.c
$ x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o BOOTX64.EFI uefiboot.o data.o
# ---> /usr/bin/x86_64-w64-mingw32-ld: uefiboot.o:uefiboot.c:(.text+0x24): undefined reference to `InitializeLib'
# ---> /usr/bin/x86_64-w64-mingw32-ld: uefiboot.o:uefiboot.c:(.text+0x33): undefined reference to `Print'
# ---> collect2: error: ld returned 1 exit status


First order of business was to check to ensure I got the paths right - GNU-EFI apparently installs to /usr/lib on Ubuntu, as confirmed by dpkg:

Code:
$ dpkg -L gnu-efi
/.
/usr
/usr/include
/usr/include/efi
/usr/include/efi/efi.h
/usr/include/efi/efi_nii.h
/usr/include/efi/efi_pxe.h
/usr/include/efi/efiapi.h
# ...
/usr/include/efi/efiui.h
/usr/include/efi/ia32
# ...
/usr/include/efi/lib.h
/usr/include/efi/libsmbios.h
/usr/include/efi/pci22.h
/usr/include/efi/protocol
/usr/include/efi/protocol/adapterdebug.h
# ...
/usr/include/efi/protocol/vgaclass.h
/usr/include/efi/romload.h
/usr/include/efi/x86_64
# ...
/usr/include/efi/x86_64/pe.h
/usr/lib
/usr/lib/crt0-efi-x86_64.o
/usr/lib/elf_x86_64_efi.lds
/usr/lib/libefi.a
/usr/lib/libgnuefi.a
/usr/lib32
# ...


At this point, I'm a bit stumped. I can obviously tell something's going on with the linking (not including or correctly binding an EFI lib), but I'm lost on how to address the matter further. I found this thread which has a similar issue, although I'm uncertain what the resolution ultimately was or whether or not it applies to this particular route (using the MinGW cross-compiler). I tried my hand at cobbling a Makefile for the process, although this gives me a different series of errors and I'm almost certain I messed something up somewhere. I'm by no means a novice to C/C++, but I have virtually zero experience with make - I've always gotten by using built-in IDE build systems.

Code:
SHELL   = /usr/bin/env zsh
.PHONY: clean

ARCH         = $(shell uname -m)
CC           = x86_64-w64-mingw32-gcc

CCFLAGS      = -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar \
               -mno-red-zone -maccumulate-outgoing-args
LDFLAGS      = -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main
EFIINC       = /usr/include/efi
EFIINCS      = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
LIB          = /usr/lib
EFILIB       = $(LIB)
EFI_CRT_OBJS = $(EFI_LIB)/crt0-efi-$(ARCH).o
EFI_LDS      = $(EFI_LIB)/elf_$(ARCH)_efi.lds
DATALOC      = $(LIB)/data.c

all: uefiboot data bootx64

uefiboot: uefiboot.c
   $(CC) $(CCFLAGS) $(EFIINCS) -c -o uefiboot.o uefiboot.c

data: data.c
   $(CC) $(CCFLAGS) $(EFIINCS) -c -o data.o $(DATALOC)

bootx64: uefiboot.o data.o
   $(CC) $(LDFLAGS) -o BOOTX64.EFI uefiboot.o data.o

clean:
   rm -f uefiboot.o data.o BOOTX64.EFI

# Errors:
# x86_64-w64-mingw32-gcc -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -I/usr/include/efi -I/usr/include/efi/x86_64 -I/usr/include/efi/protocol -c -o uefiboot.o uefiboot.c
# make: *** No rule to make target 'data.c', needed by 'data'.  Stop.


Any ideas? As is the case 90% of the time, I'm sure it boils down to some simple oversight of mine somewhere.


Top
 Profile  
 
 Post subject: Re: Issues compiling UEFI application (undefined references)
PostPosted: Mon Aug 28, 2023 6:16 pm 
Offline
Member
Member

Joined: Wed Mar 30, 2011 12:31 am
Posts: 676
There is no "InitializeLib" or "Print" function in UEFI.

These functions are provided by gnu-efi's utility library, and the guide you followed specifically states: "This example does not link against GNU-EFI or follow its build process; only the headers are used."

_________________
toaruos on github | toaruos.org | gitlab | twitter | bim - a text editor


Top
 Profile  
 
 Post subject: Re: Issues compiling UEFI application (undefined references)
PostPosted: Mon Aug 28, 2023 6:46 pm 
Offline

Joined: Mon Aug 28, 2023 4:11 am
Posts: 2
klange wrote:
There is no "InitializeLib" or "Print" function in UEFI.

These functions are provided by gnu-efi's utility library, and the guide you followed specifically states: "This example does not link against GNU-EFI or follow its build process; only the headers are used."


Well, I expected it to be a silly mistake, but I didn't think I would manage to checkmate myself in one.

Are there any functions I can depend on the EFI headers providing, or are all going to need to be implemented via uefi_call_wrapper()? I did a quick cat of the headers and they look to be mostly types, defines, and GUIDs.


Top
 Profile  
 
 Post subject: Re: Issues compiling UEFI application (undefined references)
PostPosted: Mon Aug 28, 2023 7:04 pm 
Offline
Member
Member

Joined: Wed Mar 30, 2011 12:31 am
Posts: 676
nukespace wrote:
Well, I expected it to be a silly mistake, but I didn't think I would manage to checkmate myself in one.

Are there any functions I can depend on the EFI headers providing, or are all going to need to be implemented via uefi_call_wrapper()? I did a quick cat of the headers and they look to be mostly types, defines, and GUIDs.

EFI does not provide any functions; instead you will find function pointers from the child members of the system table. You already have two that you are calling in your code: ST->ConIn->Reset and ST->ConIn->ReadKeyStroke.

Instead of reading the UEFI headers, you should read the UEFI specification which better describes what functions are available from different objects, and which ones you will likely want to use.

You do not need gnu-efi's uefi_call_wrapper, either, as you are using a mingw toolchain and all that wrapper does is provide the Microsoft calling convention that UEFI expects.

_________________
toaruos on github | toaruos.org | gitlab | twitter | bim - a text editor


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 23 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group