基于QEMU aarch64学习UEFI(edk2)-1环境搭建
基于QEMU-aarch64学习UEFI(EDK2)-1环境搭建
一、环境搭建
1、虚拟机Ubuntu系统安装
虚拟机安装Ubuntu系统,如20.04,安装完系统后sudo apt-get install qemu*
,用于安装qemu-system-aarch64
应用程序。
2、docker镜像导入
系统安装完成后,如果没有docker请手动安装,安装完成后,输入以下命令,查看docker的容器和镜像,暂时是没有任何东西的。
下面导入我们之前编译的一个docker镜像,镜像包含了EDK2编译所需的软件。
导入我们的镜像,docker load -i rayuuu-edk2.tar
导入完成,docker images
命令可以看到我们刚刚导入的镜像。
docker镜像导入到这里,说明我们的软件环境已经搭建完成。
3、下载EDK2源码
软件环境搭建完成,下面开始下载源码,如果github下载速度慢,建议同步仓库到gitee上面再进行下载。。
git clone https://github.com/tianocore/edk2.git
下载完成后,我们继续克隆其他的仓库,如:edk2-platforms,edk2-libc,uefi-tools
等仓库,命令如下:
git clone https://github.com/tianocore/edk2.git git clone https://github.com/tianocore/edk2-platforms.git git clone https://github.com/tianocore/edk2-libc.git git clone https://github.com/tianocore/edk2-non-osi.git git clone https://git.linaro.org/uefi/uefi-tools.git
克隆完成后,我们进入edk2,同步submodule。
cd edk2 git submodule update --init
然后checkout一个稳定的分支,如edk2-stable202208
。
git checkout -b edk2-rayu-202208 edk2-stable202208
4、容器创建和代码编译
4.1 容器创建
源码下载完成后,使用我们第二步导入的docker镜像,创建一个容器,开始尝试编译代码。
#docker run -h uefi --name uefistudy -p 2022:22 --privileged=true -v /work/study/uefistudy/edk2-202208:/data -it rayuuu/edk2:v1 bash ##命令解析如下: docker run -h uefi \ #设置主机名称为uefi --name uefistudy \ #设置容器名称为uefistudy -p 2022:22 \ #端口映射,容器22端口映射到主机2022端口 docker不建议使用ssh,所以不用映射端口 --privileged=true \ #使container内的root拥有真正的root权限 -v /work/study/uefistudy/edk2-202208:/data \ #数据映射,将主机work目录映射到容器data目录,可根据实际情况修改。 -it rayuuu/edk2:v1 bash
输入以上命令后,发现成功进入容器。
进入容器/data
目录,查看我们映射的文件,已经存在。
4.2 代码编译
容器创建完成,下面开始编译QEMU,我们通过uefi-tools,首先配置uefi-tools工具。
编辑uefi-tools/edk2-build.sh
,添加对应的路径。
然后使用该命令编译。
# armvirtqemu64是platforms名字 ./uefi-tools/edk2-build.sh armvirtqemu64 -b DEBUG
提示没有权限。
输入命令sudo chmod a+rw /data
,然后重新编译。
./uefi-tools/edk2-build.sh -b DEBUG armvirtqemu64
编译还是报错,退出,删掉容器,重新创建一个容器,以root用户登录。
docker run -h uefi --name uefistudy -p 2022:22 --privileged=true -uroot -v /work/study/uefistudy/edk2-202208:/home/edk2/src -it rayuuu/edk2:v1 bash
映射到/home/edk2/src
路径,以root用户登录,重新编译,可以通过。
git status
如果出现大量的修改,而且提示:
$ git diff code.c
old mode 100644
new mode 100755
那么使用命令:git config core.filemode false
修改,此命令只针对当前仓库有效。
5、运行QEMU_EFI.fd
编译通过后,我们在Ubuntu系统下使用QEMU加载uefi固件。
在docker容器内,固件路径是/home/edk2/src/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd
,那么在Ubuntu系统下的路径为/work/study/uefistudy/edk2-202208/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd
#qemu命令 qemu-system-aarch64 -machine virt,kernel_irqchip=on,gic-version=3 -cpu cortex-a57 -m 1G \ -device virtio-gpu-pci \ -drive file=fat:rw:./filedir/,media=disk,if=virtio,format=raw -nodefaults -device qemu-xhci -device usb-kbd \ -bios `pwd`/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd \ -serial stdio
上面命令使用qemu-system-aarch64程序,加载固件,将filedir文件夹映射到qemu中,实现文件共享。
我们使用上面命令运行我们刚刚编译的QEMU_EFI.fd,效果如下。
其中fs0:
就是我们的filedir文件夹。
我们输入fs0:
可以进入filedir查看文件。
其与我们在Ubuntu实际看到的文件一致。
6、VSCODE配置
我们这里以VSCODE为例,编辑代码,当然你也可以用vscode或者sublime代替。
这里推荐一个扩展,名字叫做edk2-vscode
,对比sourceinsight
可以实现FDF、DSC、DEC
等文件跳转。
如果像*.dsc.inc,*.fdf.inc
等文件无法识别的话,可以自己在"设置"->"文件"->"文件关联"中设置如下图:
将要识别的文件后缀名对应edk2_dsc,edk2_fdf
。
这样查看代码就会自动变色了。
7、日常工作
参考:韦东山——《嵌入式Linux应用开发完全手册V3.0_韦东山全系列视频文档-IMX6ULL开发板.docx》
假设你已经创建了容器,那么在日常工作中,你每天打开电脑后,你需要做的就是这个命令:
docker start ubuntu # 启动ubuntu容器 docker exec -it ubuntu bash # 进入容器,开始工作,可以在多个命令行中执行这命令 #在Ubuntu下,要先执行start 命令,它会启动SSH、NFS等服务 #在Ubuntu下,执行exit退出容器 docker stop ubuntu # 停止容器,下班回家
我们查看我们创建的容器,docker ps -a
命令。
我们这里可以重新命名,把CONTAINER ID
自定义命名。
docker rename 8b7cf92dbd2d edk2
所以后续,我们每天开机就是docker start edk2
来启动容器,然后进入容器编译。
8、不同项目的处理方法
针对不同的项目,也可以创建不同的容器,映射对应的代码文件夹即可,比如我们有一个project2的项目名称,那么我们新建一个project2的文件夹,把代码解压至project2中。
然后同步远程仓库,
git checkout master git pull origin master
这时我们想同步最新的edk2-stable202211
版本,发现没有同步到本地。
我们使用命令git fetch --tags -f
,把远程tag同步过来。
接着创建远程tag edk2-stable202211
为本地分支edk2-rayu-202211
。
命令如下:git checkout -b edk2-rayu-202211 edk2-stable202211
git log
命令查看已经通过到最新的tag。
这样我们project2项目同步了最新的edk2-stable202211版本,我们下面创建project2的容器。
命令同之前创建容器一样,只是代码路径和端口不同:
docker run -h project2 --name project2 -p 2023:22 --privileged=true -uroot -v /work/study/project2/edk2-202211:/home/edk2/src -it rayuuu/edk2:v1 bash
进入容器,同样的编译方式,可以看到编译无问题。
9、submodules的处理
因为edk2里面包含了一些子模块,需要同步才能编译,上面演示是我已经把子模块下载完成了,同步到新的tag,我们需要再更新一次子模块。
由于网络原因,我把github的仓库导入到了gitee上面进行下载到本地,速度会快很多,下面是我的.gitmodules
文件参考:
[submodule "CryptoPkg/Library/OpensslLib/openssl"] path = CryptoPkg/Library/OpensslLib/openssl url = https://gitee.com/rayu/openssl [submodule "SoftFloat"] path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 url = https://gitee.com/rayu/berkeley-softfloat-3.git [submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"] path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka url = https://gitee.com/liuson945/edk2-cmocka.git [submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"] path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma url = https://gitee.com/rayu/oniguruma [submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"] path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli url = https://gitee.com/rayu/brotli [submodule "BaseTools/Source/C/BrotliCompress/brotli"] path = BaseTools/Source/C/BrotliCompress/brotli url = https://gitee.com/rayu/brotli ignore = untracked^M [submodule "RedfishPkg/Library/JsonLib/jansson"] path = RedfishPkg/Library/JsonLib/jansson url = https://gitee.com/jiego/jansson
而我对比最新的tag,即202211版本又新增了一个子模块,名称为googletest
。
在gitee上面搜索,发现有别人也同步了这个名为googletest
的仓库,那么我参考修改一下,下面是最终的.gitmodules
文件。
[submodule "CryptoPkg/Library/OpensslLib/openssl"] path = CryptoPkg/Library/OpensslLib/openssl url = https://gitee.com/rayu/openssl [submodule "SoftFloat"] path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 url = https://gitee.com/rayu/berkeley-softfloat-3.git [submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"] path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka url = https://gitee.com/liuson945/edk2-cmocka.git [submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"] path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma url = https://gitee.com/rayu/oniguruma [submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"] path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli url = https://gitee.com/rayu/brotli [submodule "BaseTools/Source/C/BrotliCompress/brotli"] path = BaseTools/Source/C/BrotliCompress/brotli url = https://gitee.com/rayu/brotli ignore = untracked [submodule "RedfishPkg/Library/JsonLib/jansson"] path = RedfishPkg/Library/JsonLib/jansson url = https://gitee.com/jiego/jansson [submodule "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest"] path = UnitTestFrameworkPkg/Library/GoogleTestLib/googletest url = https://gitee.com/zqx5449/googletest.git
然后更新子模块,命令git submodule update --init
10、Ubuntu安装软件环境
如果不想使用docker导入镜像的方式编译软件,那么可以在Ubuntu系统里面安装官方参考,使用apt-get命令安装。
比如:
sudo apt-get install -y bison build-essential uuid-dev iasl git gcc-5 nasm python3-distutils gcc-aarch64-linux-gnu
至此,我们在docker下编译EDK2环境已经搭建完成,后续进行程序开发学习。
本文作者:Rayuu
本文链接:https://www.cnblogs.com/rayuu/p/17684176.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构