本文主要是介绍UEFI之虚拟环境(OVMF),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概要
模拟器平台介绍 :
一个仿真平台并不是一个实际的硬件平台 , 但它旨在证明 EDKII 核心模块的稳定性和独立于硬件可以开发模块。仿真平台和实际平台之间的差异是其加载器和仿真的硬件设备。
OvmfPkg 是基于qemu的虚拟环境,Linux 和 Windows都可以使用
源码
git clone https://github.com/tianocore/edk2.git
cd edk2
git submodule update --init
cd ..
qemu
需要安装qemu
apt install qemu
ubuntu 20.04
apt install qemu-system-x86
这里主要讲一些启动系统时可以使用的参数:
- -m x:用来指定虚拟系统的内存大小,x是一个数字,单位是MB;
- -bios x:用来指定使用的BIOS,默认使用的是seabios,也支持OVMF;
- -serial stdio:用来指定串口的输出,这里就是输出的标准输出;
- -hda:指定之前创建的虚拟盘;
- -cdrom:指定了安装的系统镜像;
制作挂载盘镜像
QEMU可以支持很多种文件格式,以qcow2和raw两种格式的镜像为例。需要特别注意的是,UEFI能识别到的文件系统类型比较有限,建议格式化镜像时都使用VFAT
格式。注意这里的VFAT和前面说的qcow2和raw并不冲突,一个是镜像中的文件系统,一个是镜像的封装格式。
- qcow2格式的镜像文件(这个映射出来是BLK0:)
sudo modprobe nbd max_part=16
qemu-img create -f qcow2 hda.img 10M #创建qcow2虚拟盘
sudo qemu-nbd -c /dev/nbd0 ~/hda.img #映射nbd设备
mkfs -t vfat /dev/nbd0 #格式化该设备为vfat格式
sudo mount /dev/nbd0 /mnt/image #挂载nbd设备
......(work in mnt dir)
sudo umount /mnt/image #卸载nbd设备
sudo qemu-nbd -d /dev/nbd0 #解除nbd映射
- 采用dd命令生成的镜像文件(raw镜像,这个映射出来是FS0:)
dd if=/dev/zero of=~/hda.img bs=1 count=10M
mkfs -t vfat ~/hda.img
losetup /dev/loop0 ~/hda.img #映射loop设备
sudo mount /dev/loop0 /mnt/image #挂载loop设备
......(work in mnt dir)
umount /mnt/image #卸载loop设备
losetup -d /dev/loop0 #解除loop映射
- qemu 中使用虚拟硬盘
qemu-system-x86_64 -bios "path/to/OVMF.fd" -hda hda.img
- 指定文件或文件夹映射
在Bios调试中映射镜像拷贝还需要挂载,比较麻烦,这里直接指定本地文件夹或文件进行映射
qemu-system-x86_64 -bios "/path/OVMF.fd" -net none -hda fat:rw:/path/DEBUG_GCC5
fat:rw:
这个文件夹映射的关键
path
为绝对地址
编译环境
1.更新软件源,sudo apt-get update
2.安装gcc4.8
sudo apt-get install gcc-5 g++-5
如果已经安装gcc,可以使用下面命令切换
添加sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 40sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50
切换sudo update-alternatives --config gcc
3.安装nasm
sudo apt-get install nasm
4.安装build
sudo apt-get install build-essential uuid-dev
sudo apt-get install iasl
5.安装python
sudo apt-get install pythonsudo apt-get install python-pipsudo apt-get install python3-distutils
6.在edk根目录执行
source edksetup.sh
7.在 BaseTools目录下编译工具
make
建立完成后,试试看能否编译。
source edksetup.sh
build -p MdeModulePkg/MdeModulePkg.dsc -t GCC5
8.编译
OvmfPkg
OvmfPkg/build.sh
或者编译32bit
build -p OvmfPkg/OvmfPkgIa32.dsc -t GCC5 -D SOURCE_DEBUG_ENABLE
SOURCE_DEBUG_ENABLE
是编译开关参数,dsc中有定义
9.运行
OvmfPkg:
执行命令:
qemu-system-x86_64 -bios OVMF.fd
没有UEFI的打印,为了能够有打印,首先需要添加编译选项并重新生成二进制
build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -D DEBUG_ON_SERIAL_PORT
用qemu运行时,需要加入新的参数:
qemu-system-x86_64 -bios OVMF.fd -serial stdio
qemu 下OVMF 网络
- 下载efi驱动
在Intel网站上下载E3522X2.EFI,这是网卡E1000的驱动,上一节中已经给出了下载地址。进入UEFI的编译目录,新建目录Intel3.5/EFIX64,将E3522X2.EFI拷贝到这个目录下。
获取路径:http://194.116.247.242/TRUSTER/TRUSTER_SN4236/Intel/LAN/v21.1/APPS/EFI/EFIx64/E3522X2.EFI
mkdir -p edk2/Intel3.5/EFIX64
cp E3522X2.EFI edk/edk2/Intel3.5/EFIX64/
- 编译:
build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -b DEBUG -D E1000_ENABLE -D DEBUG_ON_SERIAL_PORT
E1000_ENABLE
使能网卡,将efi驱动编译进去
如果不指定任何网络设置,Qemu将使用带有内置DHCP服务器的用户模式(user)网络。当虚拟机运行时,可设定为DHCP模式,它能够通过QEMU伪装的IP来访问物理主机的网络。
不过,这种情况下,能通信的仅限于TCP和UDP协议,因此ICMP协议(包括ping)将不起作用。因此,我们准备采用tap模式,使用桥接的方法,让虚拟机和外部通信起来。
- user 网络
user mode network :
这种方式实现虚拟机上网很简单,类似vmware里的nat,qemu启动时加入-user-net参数,虚拟机里使用dhcp方式,即可与互联网通信,但是这种方式虚拟机与主机的通信不方便。
用户模式网络允许访客通过TCP,UDP等连接回外部世界。不允许ICMP Ping。 此外,除非使用端口转发,否则不允许主机到访客的连接。
网络参数
-netdev user,id=mynet0,hostfwd=tcp::8080-:80
说明:创建ID为mynet0的用户模式网络后端。 将主机端口8080上的传入tcp连接重定向到访客端口80;
语法:hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport
-device e1000,netdev=mynet0
创建一个NIC(型号为e1000)并连接到由上一个参数创建的mynet0后端
整体的启动命令:
qemu-system-x86_64 -bios "/home/zhubo/00_loongson/02-code/edk/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd" -serial stdio -hda fat:rw:Build/AppPkg -netdev user,id=mynet0,hostfwd=tcp::8080-:80 -device e1000,netdev=mynet0
具体可以查看这里:https://wiki.archlinux.org/index.php/QEMU_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
- tap 桥接
需要做个桥,再做个虚拟网卡,比较繁琐;
tap/tun network :
这种方式要比user mode复杂一些,但是设置好后 虚拟机<–>互联网 虚拟机<–>主机 通信都很容易
这种方式设置上类似vmware的host-only,qemu使用tun/tap设备在主机上增加一块虚拟网络设备(tun0),然后就可以象真实网卡一样配置它.
编译AppPkg
EDK2 中新版本的AppPkg 和 StdLib 是分出去的
在这里放着 https://github.com/tianocore/edk2-libc.git
克隆到本地后将AppPkg、StdLib、StdLibPrivateInternalFiles 复制到edk2 的编译路径
-
编译
build -a X64 -p AppPkg/AppPkg.dsc -t GCC5
-
编译问题
Concatenation.c:34:21: error: implicit declaration of function ‘StrCat’
查看发现确实没有定义,发现如下patch删除了,
commit 9c1f455f5f0ee63ce080940bf974aac4fefe526b
Author: Shenglei Zhang <shenglei.zhang@intel.com>
Date: Wed Aug 5 14:08:03 2020 +0800MdePkg: Remove code wrapped by DISABLE_NEW_DEPRECATED_INTERFACESREF: https://bugzilla.tianocore.org/show_bug.cgi?id=2777Code wrapped by DISABLE_NEW_DEPRECATED_INTERFACES is deprecated.So remove it.Cc: Michael D Kinney <michael.d.kinney@intel.com>Cc: Liming Gao <liming.gao@intel.com>Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
最好的做法是将删除的文件恢复回来,找到上面patch的前一个patch,如下, 然后编译就没问题了
git reset cc942105ede58a300ba46f3df0edfa86b3abd4dd MdePkg/Include/Library/BaseLib.h
git reset cc942105ede58a300ba46f3df0edfa86b3abd4dd MdePkg/Library/BaseLib/String.c
问题
1、安装不了python3-distutils,提示无法定位
sudo vim /etc/apt/sources.list
添加源:
deb http://cn.archive.ubuntu.com/ubuntu bionic main multiverse restricted universe
deb http://cn.archive.ubuntu.com/ubuntu bionic-updates main multiverse restricted universe
deb http://cn.archive.ubuntu.com/ubuntu bionic-security main multiverse restricted universe
deb http://cn.archive.ubuntu.com/ubuntu bionic-proposed main multiverse restricted universe
再执行如下指令:
sudo apt-get updatesudo apt-get install python3-distutils
2、Trim.py: error: no such option: --asm-file
安装完如下3条命令问题就没有了,也不知道具体哪条解决的;
pip install brotli
sudo apt install build-essential uuid-dev
sudo apt install acpica-tools
3、 在编译AppPkg和Demo时,出现如下问题:
/usr/bin/ld: 并不支持从格式 pe-i386 (/edk2/Build/AppPkg/DEBUG_GCC5/IA32/StdLib/LibC/LibC/OUTPUT/LibC.lib(ftol2.obj)) 到格式 elf32-i386 (edk2/Build/AppPkg/DEBUG_GCC5/IA32/AppPkg/Applications/Sockets/SetHostName/SetHostName/DEBUG/SetHostName.dll) 的重寻址链结
是由于在ubuntu64上编译32位应用导致的,添加-a X64
后正常了;
build -p AppPkg/AppPkg.dsc -t GCC5 -a X64
4、警告变error
可以在 Flags 加 -Wno-error
试试
5、编译报缺少东西,如brotli/c/enc/encoder_dict.o: 没有那个文件或目录
git submodule update --init
这篇关于UEFI之虚拟环境(OVMF)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!