Software #1617
closedXXX Create a HelloWorld.efi with GNU-efi
100%
Description
Memtest86+ efi-file seems to be created with GNU-efi libraries.
Create a HelloWorld program with GNU efi instead of edk2.
Create a separate debug symbols file.
Connect it with GDB
Updated by Regina Koenig over 1 year ago
- Project changed from memtest86+ EFI to GDB debug script for memtest86+
Updated by Regina Koenig over 1 year ago
Hint:
gcc -g -O0 Hello.c
objcopy --only-keep-debug kernel.elf kernel.debug
objcopy --strip kernel.elf
Updated by Regina Koenig over 1 year ago
When efi executable is created from elf shared objectfile, only limited set of sections are copied into resulted image:
.text .sdata .data .dynamic .dynsym .rel .rela.reloc
If compile with "-ggdb" option, additional symbols .debug_info .debug_abbrev .debug_loc .debug_ranges .debug_line .debug_macinfo .debug_str but that does not launch in EFI Firmware
Actually you just need to run objcopy utility twice with different set of sections to copy and different output files
Updated by Regina Koenig over 1 year ago
try:
CpuDeadLoop(void) {
volatile int Index;
for(Index=0; Index==0; ) {
asm volatile("pause");
}
}
Updated by Regina Koenig over 1 year ago
This minimal example/setup creates a working hello.efi binary:
hello.c
#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;
}
Makefile
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
OBJS = hello.o
TARGET = hello.efi
EFIINC = /usr/include/efi
EFFINCS = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
EFILIB = /usr/lib
EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS = $(EFFINCS) -fno-stack-protector -fpic \
-fshort-wchar -mno-red-zone -Wall
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) $(EFI_CRT_OBJS)
all: $(TARGET)
hello.so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc \
--target=efi-app-$(ARCH) $^ $@
Updated by Regina Koenig over 1 year ago
This is a working example. The Makefile creates an efi-file without debug symbols and a debug-file with debug symbols.
hello.c:
#include <efi.h>
#include <efilib.h>
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
EFI_LOADED_IMAGE *loaded_image = NULL;
EFI_STATUS status;
InitializeLib(ImageHandle, SystemTable);
Print(L"Hello, world!\n");
status = uefi_call_wrapper(SystemTable->BootServices->HandleProtocol,
3,
ImageHandle,
&LoadedImageProtocol,
(void **)&loaded_image);
if (EFI_ERROR(status)) {
Print(L"handleprotocol: %r\n", status);
}
Print(L"Image base: 0x%lx\n", loaded_image->ImageBase);
DEBUG((D_ERROR, "AllocatePool: out of pool %x\n", status));
volatile int wait = 1;
while(wait) {
__asm__ __volatile__("pause");
}
return EFI_SUCCESS;
}
Makefile:
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,)
OBJS = hello.o
TARGET = hello.efi
TARGET_DEBUG = hello.debug
EFIINC = /usr/include/efi
EFFINCS = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
EFILIB = /usr/lib
EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS = $(EFFINCS) -fno-stack-protector -fpic \
-fshort-wchar -mno-red-zone -Wall
CFLAGS += -ggdb3 -O0 -DDEBUG -DEFI_DEBUG=1
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) $(EFI_CRT_OBJS)
SECTIONS = .text .sdata .data .dynamic .dynsym .rel .rela .reloc
DEBUG_SECTIONS = .debug_info .debug_abbrev .debug_aranges \
.debug_line .debug_str
all: clear $(TARGET) $(TARGET_DEBUG)
cp hello.efi ../test_code/hda-contents/
hello.so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy $(foreach sec,$(SECTIONS),-j $(sec)) \
--target=efi-app-$(ARCH) $^ $@
%.debug: %.so
objcopy $(foreach sec,$(SECTIONS) $(DEBUG_SECTIONS),-j $(sec)) \
--target=efi-app-$(ARCH) $^ $@
clear:
rm -f *.efi
rm -f *.debug
rm -f *.o
rm -f *.so
ImageBase is output from hello.efi
Via
(gdb) file hello.efi
(gdb) info files
(gdb) file
it is possible to get .text and .data offset
Symbol-file can be loaded via
(gdb) add-symbol-file /path/to/debug/file/hello.debug (ImageBase + text-offset) -s .data (ImageBase + data-offset)
Updated by Regina Koenig over 1 year ago
- Subject changed from Create a HelloWorld.efi with GNU-efi to XXX Create a HelloWorld.efi with GNU-efi
Updated by Regina Koenig over 1 year ago
- Status changed from New to Closed
The remaining tasks will be directly done with memtest