我似乎无法取得进展;我的程序不会运行,错误消息是无关紧要的.十六进制转储无缘无故地显示了错误的PE二进制文件:

I started from this tutorial

我的Makefile:

ARCH=x86_64

OBJS=hello.o
TARGET=hello.efi

EFIINC=/usr/include/efi
EFIINCS=-I$(EFIINC) -I$(EIFFINC)/$(ARCH) -I$(EFIINC)/protocol
LIB=/usr/lib64
EFILIB=/usr/lib
EFI_CRT_OJBS=$(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS=$(EFILIB)/elf_$(ARCH)_efi.lds

CFLAGS=$(EFIINCS) -fno-stack-protector -fpic -fshort-wchar -mno-red-zone -Wall -DEFI_FUNCION_WRAPPER

LDFLAGS =-nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L $(EFILIB) -L $(LIB) $(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) $^ $@

我的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;
}

我构建hello.efi,将其复制到磁盘镜像上,并使用以下命令启动QEMU:

qemu-system-x86_64 -enable-kvm -bios /usr/share/qemu/OVMF.fd -nodefaults -display gtk -vga std -hda target

但在试图运营它时:

FS0:\> dir
Directory of: FS0:\
12/31/2023    48,181  exit.efi
12/31/2023    41,494  hello.efi
FS0:\> hello.efi
Command Error Status: Unsupported

exit.efi是efi library中的一个股票演示应用程序;它启动了.我不确定它是否应该挂掉qemu,但它确实有作用.我的应用程序是hello.efi.发动不了

运行objdump以确保文件格式正确:

$ objdump -f -h hello.efi 

hello.efi:     file format pei-x86-64
architecture: i386:x86-64, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x0000000000000000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00005bf0  0000000000003000  0000000000003000  00000138  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001d00  0000000000009000  0000000000009000  00005d38  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .dynamic      00000110  000000000000b000  000000000000b000  00007b38  2**3
                  CONTENTS, ALLOC, LOAD, DATA
  3 .dynsym       000000d8  000000000000d000  000000000000d000  00007d38  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

构建和托管环境为Debian 12.4 x86_64.

编译过程中出现了很大的问题.二进制文件顶部的十六进制转储提供:

$ hexdump -C hello.efi | head -n 16
00000000  4d 5a 90 00 03 00 00 00  04 00 00 00 ff ff 00 00  |MZ..........ÿÿ..|
00000010  b8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00  |¸.......@.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 80 00 00 00  |................|
00000040  0e 1f ba 0e 00 b4 09 cd  21 b8 01 4c cd 21 54 68  |..º..´.Í!¸.LÍ!Th|
00000050  69 73 20 70 72 6f 67 72  61 6d 20 63 61 6e 6e 6f  |is program canno|
00000060  74 20 62 65 20 72 75 6e  20 69 6e 20 44 4f 53 20  |t be run in DOS |
00000070  6d 6f 64 65 2e 0d 0d 0a  24 00 00 00 00 00 00 00  |mode....$.......|
00000080  50 45 00 00 64 86 04 00  00 00 00 00 38 7f 00 00  |PE..d.......8...|
00000090  12 01 00 00 00 00 05 02  2e 74 65 78 74 00 00 00  |.........text...|
000000a0  f0 5b 00 00 00 30 00 00  00 5c 00 00 38 01 00 00  |ð[...0...\..8...|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 20 00 50 60  |............ .P`|
000000c0  2e 64 61 74 61 00 00 00  00 1d 00 00 00 90 00 00  |.data...........|
000000d0  00 1e 00 00 38 5d 00 00  00 00 00 00 00 00 00 00  |....8]..........|
000000e0  00 00 00 00 40 00 60 c0  2e 64 79 6e 61 6d 69 63  |....@.`À.dynamic|
000000f0  10 01 00 00 00 b0 00 00  00 02 00 00 38 7b 00 00  |.....°......8{..|

节头开始时太接近PE签名.该二进制文件将是可卸载的.

推荐答案

你的Makefile中有一些错别字:

  • EFIINCS=-I$(EFIINC)-I$(EIFFINC)/$(ARCH)-I$(EFIINC)/协议

  • EFI_CRT_OJBS=$(EFILIB)/crt0-efi-$(ARCH).o

  • ObjCopy-j.text-j.sdata-j.data-j.Dynamic-j.dynsym-j rel-j rela-j reloc--Target=efi-app-$(ARCH)$^$@

我用这个Makefile运行了您的代码:

ARCH=x86_64

OBJS=hello.o
TARGET=hello.efi

EFIINC=/usr/include/efi
EFIINCS=-I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
LIB=/usr/lib64
EFILIB=/usr/lib
EFI_CRT_OBJS=$(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS=$(EFILIB)/elf_$(ARCH)_efi.lds

CFLAGS=$(EFIINCS) -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -Wall -DEFI_FUNCION_WRAPPER

LDFLAGS=-shared -Bsymbolic -T $(EFI_LDS) -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)

all: $(TARGET)

hello.so: $(OBJS)
    ld $(LDFLAGS) $(OBJS) -o $@ -lgnuefi -lefi

%.efi: %.so
    objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target=efi-app-$(ARCH) --subsystem=10 $^ $@

C++相关问答推荐

%p与char* 等组合缺少的GCC Wform警告

GCC:try 使用—WError或—pedantic using pragmas

增加getaddrinfo返回的IP地址数量

我无法让LLDB正确运行我的可执行文件

如何知道我是否从非阻塞套接字读取所有内容

Ruby C Api处理异常

如何将长字符串转换为较小的缩写,该缩写由第一个字符、最后一个字符和中间的字符数组成?

防止规范模式在C++中 echo 特殊字符

为什么指针运算会产生错误的结果?

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

使用nmake for程序比Hello World稍微复杂一些

不使用任何预定义的C函数进行逐位运算

如何在C中定义指向函数的指针并将该指针赋给函数?

区分MySQL C界面中的文本和BLOB字段

可以';t从A9G模块拨打电话

为什么argc和argv即使在主函数之外也能工作?

将指针的地址加载到寄存器内联拇指组件中

#define X Defined(Y) 是有效的 C/C++ 宏定义吗?

为什么实现文件中的自由函数默认没有内部链接?

快速准确计算double的小数指数