【发布时间】:2023-04-08 11:25:01
【问题描述】:
我正在尝试创建一个可引导的 UEFI ISO,但 Hyper-V 不认为它是一个有效的 UEFI 文件系统。我做错了什么?
创建 ISO:
xorriso -as mkisofs -o uefi.iso -iso-level 3 -V UEFI isoFiles
isoFiles 有一个文件,boot/hello.efi。在存档管理器中安装或打开时,该文件存在。
编辑: 让我们有更多的背景信息好吗?
这是 EFI 代码,它使用 gnu-efi v3.0.8:
#include <efi.h>
#include <efilib.h>
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable){
EFI_STATUS Status;
EFI_INPUT_KEY Key;
ST = SystemTable;
Status = ST->ConOut->OutputString(ST->ConOut, L"Hello world!\n\r");
if(EFI_ERROR(Status)){
return Status;
}
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;
}
这是它的 Makefile:
DIR_OUT := ..
TARGET := uefi
OUT := $(DIR_OUT)/out/boot
DIR_SRC := src
DIR_BLD := build
EFI_DIR := gnu-efi-3.0.8
EFI_LIB := $(EFI_DIR)/x86_64/gnuefi/ $(EFI_DIR)/x86_64/lib
EFI_INC := $(EFI_DIR)/inc $(EFI_DIR)/inc/x86_64 $(EFI_DIR)/inc/protocol
EFI_CRT := $(EFI_DIR)/x86_64/gnuefi/crt0-efi-x86_64.o
EFI_LDS := $(EFI_DIR)/gnuefi/elf_x86_64_efi.lds
CFILES := $(wildcard $(DIR_SRC)/*.c)
OFILES := $(patsubst $(DIR_SRC)/%.c,$(DIR_BLD)/%.o,$(CFILES))
PREFIX :=
CC := $(PREFIX)gcc
LD := $(PREFIX)ld
OBJCPY := $(PREFIX)objcopy
INCLUDES := $(addprefix -I,$(EFI_INC))
CFLAGS := -fno-stack-protector -fpic -fshort-wchar -mno-red-zone -Wall -ffreestanding -DEFI_FUNCTION_WRAPPER -c $(INCLUDES)
LDFLAGS := -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic $(addprefix -L,$(EFI_LIB)) $(EFI_CRT)
all: builddir bootdir $(OUT)/$(TARGET).efi
.PRECIOUS: $(OFILES)
clean:
rm -vrf $(OFILES) $(OUT)/$(TARGET).efi
$(OUT)/$(TARGET).efi: $(DIR_BLD)/$(TARGET).efi
cp $< $@
%.efi: %.so
$(OBJCPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc --target=efi-app-x86_64 $^ $@
$(DIR_BLD)/$(TARGET).so: $(OFILES)
$(LD) $(LDFLAGS) $< -o $@ -lefi -lgnuefi
$(DIR_BLD)/%.o: $(DIR_SRC)/%.c
$(CC) $(CFLAGS) $< -o $@
bootdir:
mkdir -p $(OUT)
builddir:
mkdir -p $(DIR_BLD)
这是创建 ISO 的 Makefile:
ISO_DIR := ..
ISO_FILE := uefi.iso
ISO_LABEL := UEFI
DIR_BLD := build
MKFSISO := xorriso -as mkisofs
FATSIZE := 8M
MKFSVFAT := /sbin/mkfs.vfat
MOUNT := sudo mount
UMOUNT := sudo umount
UID := $(shell id -u gudenau)
GID := $(shell id -g gudenau)
all: buildDir $(ISO_DIR)/$(ISO_FILE)
.PRECIOUS: $(ISO_DIR)/$(ISO_FILE) $(DIR_BLD)/efi.img
$(ISO_DIR)/%.iso: $(DIR_BLD)/efi.img
$(MKFSISO) -o $@ -iso-level 3 -V "$(ISO_LABEL)" $(DIR_BLD)/efi.img -e /efi.img -no-emul-boot
%.img:
dd if=/dev/zero of=$@ bs=1024 count=1024
$(MKFSVFAT) $@
mkdir -p $(DIR_BLD)/image
$(MOUNT) -o gid=$(GID),uid=$(UID) $@ $(DIR_BLD)/image
mkdir -p $(DIR_BLD)/image/EFI/BOOT/
cp ../bootloader/build/uefi.efi $(DIR_BLD)/image/EFI/BOOT/BOOTX64.EFI
$(UMOUNT) $(DIR_BLD)/image
rm -vfr $(DIR_BLD)/image
clean:
rm -vf $(DIR_BLD)/efi.img $(ISO_DIR)/$(ISO_FILE)
buildDir:
mkdir -p $(DIR_BLD)
我知道 Makefile 目前真的很糟糕,但我现在只是想让它工作。以后我会改进的。
编辑: 经过更多研究,我现在有了这个 Makefile:
ISO_DIR := ..
ISO_FILE := uefi.iso
ISO_LABEL := UEFI
DIR_BLD := build
MKFSISO := xorriso -as mkisofs
FATHEADS := 32
FATTRACKS := 32
FATSECTOR := 512
FATTHING := 128
FATFORMAT := mformat
MMD := mmd
MCOPY := mcopy
all: buildDir $(ISO_DIR)/$(ISO_FILE)
.PRECIOUS: $(ISO_DIR)/$(ISO_FILE) $(DIR_BLD)/efi.img
$(ISO_DIR)/%.iso: $(DIR_BLD)/efi.img
$(MKFSISO) -o $@ -iso-level 3 -V "$(ISO_LABEL)" $(DIR_BLD)/efi.img -e /efi.img -no-emul-boot
%.img:
$(FATFORMAT) -i $@ -F -h $(FATHEADS) -t $(FATTRACKS) -n $(FATTHING) -c 1 -C
$(MDD) -i $@ ::/EFI
$(MDD) -i $@ ::/EFI/BOOT
$(MCOPY) -i $@ ../bootloader/build/uefi.efi ::/EFI/BOOT/BOOTX64.EFI
clean:
rm -vf $(DIR_BLD)/efi.img $(ISO_DIR)/$(ISO_FILE)
buildDir:
mkdir -p $(DIR_BLD)
但我不知道如何用它制作 GPT 图像,因为 mkgpt 似乎不存在。
【问题讨论】:
-
在 GNU/Linux 上,您可以在新 dd'ed 映像文件上使用 gdisk 来创建具有“ef00”类型分区的 GPT。然后使用带有字节偏移量的 losttup -o 匹配分区开始来创建一个循环设备,您可以在其中创建和填充 FAT 文件系统。然后将镜像作为硬盘提交给虚拟机。