UEFI固件安全 · 2023年2月20日 0

CSM兼容的OVMF制作

自己编译半天不如直接用官方现成的:)

制作CSM兼容OVMF

环境:

  • ubuntu 22.04
  • gcc11
  • python3.10.4

获取edk2源码:

git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init

注意一定要等待子模块也克隆成功,如有更新,使用下面的命令获取更新:

cd edk2
git pull
git submodule update

安装依赖:

sudo apt install build-essential uuid-dev iasl git nasm python-is-python3 make libncurses5-dev libncursesw5-dev

安装BaseTools:

cd edk2/BaseTools
make -C ./

edksetup:

cd edk2
./edksetup.sh

构建Csm16.bin模块,获取seabios源码:

git clone https://git.seabios.org/seabios.git
cd seabios

编辑.config文件:

#
# Automatically generated file; DO NOT EDIT.
# SeaBIOS Configuration
#

#
# General Features
#
# CONFIG_COREBOOT is not set
# CONFIG_QEMU is not set
CONFIG_CSM=y
CONFIG_QEMU_HARDWARE=y
CONFIG_THREADS=y
CONFIG_RELOCATE_INIT=y
CONFIG_BOOTMENU=y
CONFIG_BOOTSPLASH=y
CONFIG_BOOTORDER=y
CONFIG_HOST_BIOS_GEOMETRY=y
CONFIG_ENTRY_EXTRASTACK=y
CONFIG_MALLOC_UPPERMEMORY=y
CONFIG_ROM_SIZE=0

#
# Hardware support
#
CONFIG_ATA=y
# CONFIG_ATA_DMA is not set
# CONFIG_ATA_PIO32 is not set
CONFIG_AHCI=y
CONFIG_SDCARD=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_SCSI=y
CONFIG_PVSCSI=y
CONFIG_ESP_SCSI=y
CONFIG_LSI_SCSI=y
CONFIG_MEGASAS=y
CONFIG_MPT_SCSI=y
CONFIG_FLOPPY=y
CONFIG_FLASH_FLOPPY=y
CONFIG_NVME=y
CONFIG_PS2PORT=y
CONFIG_USB=y
CONFIG_USB_UHCI=y
CONFIG_USB_OHCI=y
CONFIG_USB_EHCI=y
CONFIG_USB_XHCI=y
CONFIG_USB_MSC=y
CONFIG_USB_UAS=y
CONFIG_USB_HUB=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_MOUSE=y
CONFIG_SERIAL=y
CONFIG_SERCON=y
CONFIG_LPT=y
CONFIG_RTC_TIMER=y
CONFIG_HARDWARE_IRQ=y
CONFIG_PMTIMER=y
CONFIG_TSC_TIMER=y

#
# BIOS interfaces
#
CONFIG_DRIVES=y
CONFIG_CDROM_BOOT=y
CONFIG_CDROM_EMU=y
CONFIG_PCIBIOS=y
CONFIG_APMBIOS=y
CONFIG_PNPBIOS=y
CONFIG_OPTIONROMS=y
CONFIG_PMM=y
CONFIG_BOOT=y
CONFIG_KEYBOARD=y
CONFIG_KBD_CALL_INT15_4F=y
CONFIG_MOUSE=y
CONFIG_S3_RESUME=y
CONFIG_VGAHOOKS=y
# CONFIG_DISABLE_A20 is not set
CONFIG_TCGBIOS=y

#
# VGA ROM
#
CONFIG_NO_VGABIOS=y
# CONFIG_VGA_GEODEGX2 is not set
# CONFIG_VGA_GEODELX is not set
# CONFIG_BUILD_VGABIOS is not set
CONFIG_VGA_EXTRA_STACK_SIZE=512

#
# Debugging
#
CONFIG_DEBUG_LEVEL=1
# CONFIG_DEBUG_SERIAL is not set
# CONFIG_DEBUG_SERIAL_MMIO is not set
CONFIG_DEBUG_IO=y

运行make,生成out/Csm16.bin文件:

image-20230222145946275

复制Csm16.bin文件到edk2目录下:

cp out/Csm16.bin ~/edk2/OvmfPkg/Csm/Csm16/

经测试,仅Arch linux 1.16.0-3-3版本构建的Csm16.bin才能正常引导win7

image-20230221152531592

否则全都显示无法读取boot disk:

image-20230222151731988

编译支持CSM的OVMF:

cd edk2
OvmfPkg/build.sh -a X64 -b RELEASE -t GCC5 -D NETWORK_IP6_ENABLE -D TPM_ENABLE -D TLS_ENABLE -D HTTP_BOOT_ENABLE -D CSM_ENABLE -D FD_SIZE_2MB
image-20230220175819842

OVMF Flash布局

OVMF支持构建1MB、2MB和4MB的固件文件,对应编译选项为:-D FD_SIZE_1MB-D FD_SIZE_2MB-D FD_SIZE_4MB

1MB和2MB的固件布局如下:

+--------------------------------------- 4GB (0x100000000)
| VTF0 (16-bit reset code) and OVMF SEC
| (SECFV, 208KB/0x34000)
+--------------------------------------- varies based on flash size
|
| Compressed main firmware image
| (FVMAIN_COMPACT)
|
+--------------------------------------- base + 0x20000
| Fault-tolerant write (FTW)
| Spare blocks (64KB/0x10000)
+--------------------------------------- base + 0x10000
| FTW Work block (4KB/0x1000)
+--------------------------------------- base + 0x0f000
| Event log area (4KB/0x1000)
+--------------------------------------- base + 0x0e000
| Non-volatile variable storage
| area (56KB/0xe000)
+--------------------------------------- base address

4MB的固件布局如下:

+--------------------------------------- base + 0x400000 (4GB/0x100000000)
| VTF0 (16-bit reset code) and OVMF SEC
| (SECFV, 208KB/0x34000)
+--------------------------------------- base + 0x3cc000
|
| Compressed main firmware image
| (FVMAIN_COMPACT, 3360KB/0x348000)
|
+--------------------------------------- base + 0x84000
| Fault-tolerant write (FTW)
| Spare blocks (264KB/0x42000)
+--------------------------------------- base + 0x42000
| FTW Work block (4KB/0x1000)
+--------------------------------------- base + 0x41000
| Event log area (4KB/0x1000)
+--------------------------------------- base + 0x40000
| Non-volatile variable storage
| area (256KB/0x40000)
+--------------------------------------- base address (0xffc00000)

编译成功,输出文件OVMF_CODE.fd,支持CSM模式及qemu引导:

image-20230222152022613
image-20230220175859777

用该固件成功引导win7 MBR,进入引导管理器:

image-20230222151831529

启动脚本:

#!/bin/sh
/usr/bin/qemu-system-x86_64 \
-machine type=q35,accel=kvm:tcg \
-cpu host \
-smp cpus=2,cores=2,threads=1,sockets=1 \
-boot menu=on \
-bios OVMF_CODE_seabios.fd \
-m 2G \
-k en-us \
-name "Microsoft Windows 7 MBR" \
-drive file="win7x64-mbr.img",if=virtio,index=0,media=disk,cache=writeback,format=qcow2 \
-usb \
-net none \
-monitor stdio \
-rtc base=localtime \
-serial file:serial-ok.log \
-debugcon file:debug-ok.log -global isa-debugcon.iobase=0x402

现成的

ArchLinux提供多个编译好的OVMF,可直接使用:

https://archlinux.org/packages/extra/any/edk2-ovmf/