我似乎无法取得进展;我的程序不会运行,错误消息是无关紧要的.十六进制转储无缘无故地显示了错误的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++相关问答推荐

错误:在.h程序中重新定义 struct

为什么在C中设置文件的位置并写入文件,填充空字符?

GCC预处理宏和#杂注GCC展开

创建一个fork导致fget无限地重新读取文件

为什么C语言允许你使用var =(struct NAME){

在列表中插入Int指针(C)

自定义变参数函数的C预处置宏和警告 suppress ?

如何在ASM中访问C struct 成员

Sizeof(&Q;字符串&Q;)的正确输出是什么?

&;(str[i])和(&;str)[i]有什么区别?

如何在C++中处理按键

为什么我从CSV文件中进行排序和搜索的代码没有显示数据的所有结果?

C语言中MPI发送接收字符串时出现的分段错误

pthread_create的用法

为什么编译器不能简单地将数据从EDI转移到EAX?

如何读取程序中嵌入的数据S自己的ELF?

Fscanf打印除退出C代码为1的程序外的所有内容

意外的C并集结果

返回指向函数内声明的复合文字的指针是否安全,还是应该使用 malloc?

strided memcpy(3) 在 libvpx 中如何工作