QEMU模拟ATF启动
通过qemu模拟ATF的启动,即启动流程为:
其中bl33为uboot。
Qemu
-
apt方式下载
# 不推荐以apt-get方式安装,版本较低 # 后续启动kernel可能失败 sudo apt-get install qemu # 查看ARM64平台版本 qemu-system-aarch64 --version
-
源码安装
去官网下载最新的版本,这里下载qemu-7.1.0,并解压
# 下载 wget https://download.qemu.org/qemu-7.1.0.tar.xz # 解压 xz -d qemu-7.1.0.tar.xz tar xvf qemu-7.1.0.tar
-
相关库安装
sudo apt-get install libcap-dev sudo apt-get install pkg-config sudo apt-get install zlib1g-dev libglib2.0-dev sudo apt-get install libpixman-1-dev sudo apt install python3-pip pip3 install --user meson
# ninja sudo apt-get install re2c git clone https://github.com/ninja-build/ninja.git cd ninja && ./configure.py --bootstrap sudo cp ./ninja /usr/bin/ ninja --version
-
问题解决
-
virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel
wget https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libcap-ng/0.7.7-3.1/libcap-ng_0.7.7.orig.tar.gz cd libcap-ng-0.7.7 ./autogen.sh ./configure make sudo make install
-
-
编译安装
./configure --target-list=x86_64-softmmu,x86_64-linux-user,arm-softmmu,arm-linux-user,aarch64-softmmu,aarch64-linux-user --enable-kvm make -j16 sudo make install # 查看版本 qemu-system-aarch64 --version
U-boot
-
下载uboot
git clone https://source.denx.de/u-boot/u-boot.git
-
编译uboot
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- make qemu_arm64_defconfig make -j16
-
uboot位置
./u-boot.bin
Kernel
-
下载kernel
进入官网,下载稳定版本的,这里下载linux-5.19.6.tar.xz,并解压
# 下载 https://www.kernel.org/ # 解压 xz -d linux-5.19.6.tar.xz tar xvf linux-5.19.6.tar
-
编译kernel
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- make defconfig make -j16
-
Image位置
./arch/arm64/boot/Image
Rootfs
-
下载buildroot
进入官网,下载稳定版本,这里下载buildroot-2022.05.2.tar.xz,并解压
# 下载 https://buildroot.org/download.html # 解压 xz -d xz -d buildroot-2022.05.2.tar.xz tar xvf buildroot-2022.05.2.tar
-
配置
make ARCH=arm64 menuconfig
如出现
Unable to find the ncurses libraries or the required header files
,需要安装以下库sudo apt-get install libncurses5-dev libncursesw5-dev
-
Target Options
Target Architecture:AArch64(little endian)
Target Architecture Variant:cortex-A53
其他默认不变。
-
Toolchain
这里让buildroot自己去下载适配的工具链
-
System configuration
这里默认不变
-
Filesystem images
ext2/3/4 root filesystem:y
- ex2/3/4 variant:ext4
-
-
编译
注意不能-j进行多核编译
sudo make
ATF
-
下载ATF
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
-
编译
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- make PLAT=qemu all DEBUG=1
TIPS:默认调试版本日志等级为40(INFO),发布版本中为20(NOTICE),可加
LOG_LEVEL=50
参数开启VERBOSE日志。 -
bin文件位置
build/qemu/debug
生成bl1.bin,bl2.bin,bl31.bin等文件
启动
新建qemu_test文件夹,并进入。
-
qemu启动u-boot
qemu-system-aarch64 \ -M virt \ -cpu cortex-a53 \ -smp 2 \ -m 2048M \ -kernel ../u-boot-master/u-boot \ -nographic
TIPS:
解决qemu启动输出参数较多,添加启动选项保存到配置文件中,如下
-writeconfig qemu-test.conf
下次启动时,直接加载该配置文件即可
qemu-system-aarch64 –readconfig qemu-test.conf
退出qemu,按住Ctrl+A,松开后再输入X即可。
-
qemu启动kernel
qemu-system-aarch64 \ -M virt \ -cpu cortex-a53 \ -smp 2 \ -m 2048M \ -kernel ../linux-5.19.6/arch/arm64/boot/Image \ -append "console=ttyAMA0 root=/dev/vda" \ -nographic
这里由于缺少根文件系统rootfs,会打印
end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
。 -
qemu启动rootfs(kernel)
qemu-system-aarch64 \ -M virt \ -cpu cortex-a53 \ -smp 2 \ -m 2048M \ -kernel ../linux-5.19.6/arch/arm64/boot/Image \ -drive file=../buildroot-2022.05.2/output/images/rootfs.ext4,if=none,id=blk1,format=raw \ -device virtio-blk-device,drive=blk1 \ -append "console=ttyAMA0 root=/dev/vda" \ -nographic
使用
root
的password登陆进去。 -
qemu通过u-boot启动kernel
uboot下载kernel镜像和设备数dtb有两种方式:
- 可以配置uboot的网络,使用tftp方式下载
- 使用半主机semihosting的方式加载
我们这里使用后者,但是需要编译uboot时,在configs/qemu_arm64_defconfig中添加以下配置
CONFIG_SEMIHOSTING=y
。重新编译后,运行:qemu-system-aarch64 \ -M virt \ -cpu cortex-a53 \ -smp 2 \ -m 2048M \ -kernel ../u-boot-master/u-boot \ -semihosting-config enable=on,target=native \ -nographic
然后通过semihosting方式添加kernel
smhload ../linux-5.19.6/arch/arm64/boot/Image
最后设置bootargs并启动内核
setenv bootargs " console=ttyAMA0 root=/dev/vda" booti 0x40000000 - 0x43000000
TODO:这里没有添加成功smhload命令
-
qemu通过ATF启动u-boot
拷贝
bl1.bin、bl2.bin、bl31.bin
到当前目录下,拷贝u-boot.bin到当前目录下并重命名为bl33.bincp ../arm-trusted-firmware-2.7.0/build/qemu/debug/*.bin ./ cp ../u-boot-master/u-boot.bin ./bl33.bin
qemu-system-aarch64 \ -nographic -machine virt,secure=on \ -cpu cortex-a53 \ -smp 2 -m 2048 \ -d unimp \ -bios bl1.bin \ -semihosting-config enable=on,target=native
注意:qemu默认使用FIP方式加载,原始镜像存在memmap中,如果memmap没有镜像,会打印
Firmware Image Package header check failed.
FIP校验头失败。然后就会使用半主机的方式读取镜像Using Semi-hosting IO
,直接半主机方式读取原始镜像到内存地址中(实际上是通过读文件的方式),即不会在校验FIP方式的头这些,因此如果需要FIP方式加载,需要将镜像事先加载到memmap中。可以使用gdb的restore命令用来将文件中的数据加载到内容中,使用方法如下,详见第5点
restore file binary start_addr end_addr
-
qemu通过gdb调试目标镜像
在启动qemu时添加-s –S选项。
-S:表示QEMU虚拟机会冻结CPU,直到远程的GDB输入相应控制命令
-s:表示在1234端口接受GDB的调试连接,其与-gdb tcp::1234参数相同qemu-system-aarch64 \ -nographic -machine virt,secure=on \ -cpu cortex-a53 \ -smp 2 -m 2048 \ -d unimp \ -bios bl1.bin \ -semihosting-config enable=on,target=native -s -S
启动GDB,apt-get安装的交叉工具链没有gdb(可以安装gdb-multiarch的gdb),我们这里使用自己下载的工具链。在另一窗口下通过gdb从atf的bl1开始启动:
~/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb ../arm-trusted-firmware-2.7.0/build/qemu/debug/bl1/bl1.elf
gdb通过tcp方式attach到qemu的目标板上
target remote localhost:1234
就开始调试了,执行N,C,B等gdb命令。
TIPS1:默认ATF编译时开优化,需要打开调试
CFLAGS='-O0 -gdwarf-2' make PLAT=qemu all DEBUG=1
TIPS2:默认我们开始使用的是bl1的符号表,因此如果要调试bl2,bl31,kernel等,需要在gdb中添加对应的符号表,如下:
add-symbol-file ../arm-trusted-firmware-2.7.0/build/qemu/debug/bl2/bl2.elf
-
qemu使用FIP方式加载ATF
编译生成FIP包,需要指定BL33镜像的位置,默认会生成fip.bin
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- make PLAT=qemu BL33=../u-boot-master/u-boot.bin all fip DEBUG=1 LOG_LEVEL=50
下面的命令在
build/qemu/debug
目录下执行。启动qemu
qemu-system-aarch64 \ -nographic -machine virt,secure=on \ -cpu cortex-a53 \ -smp 2 -m 2048 \ -d unimp \ -bios bl1.bin \ -semihosting-config enable=on,target=native -s -S
启动gdb调试
~/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb bl1/bl1.elf
-
连接目标板
target remote localhost:1234
-
加载fip.bin到内存
restore fip.bin binary 0x00040000
这里的开始地址和最大大小就是qemu平台配置的
#define PLAT_QEMU_FIP_BASE 0x00040000 #define PLAT_QEMU_FIP_MAX_SIZE 0x00400000
-
全速运行文章来源:https://www.toymoban.com/news/detail-447287.html
c
如果开启VERBOSE打印,可以看到每个镜像加载时会打印如下内容文章来源地址https://www.toymoban.com/news/detail-447287.html
VERBOSE: FIP header looks OK. VERBOSE: Using FIP
-
参考
- 利用Qemu-4.0虚拟ARM64实验平台
- 从零开始搭建qemu调试环境
到了这里,关于QEMU模拟ATF启动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!