Qemu支持ATF + u-boot + linux kernel

一、qemu环境搭建及ATF/u-boot/linux kernel的编译等,参考

1. 从零开始搭建qemu调试环境 - 知乎

2. 使用qemu进行arm64架构linux开发学习 - 知乎

3. 通过Buildroot自制根文件系统_buildroot systemd_17岁boy想当攻城狮的博客-CSDN博客

4. 【linux】init进程的详解_linux init进程_云川之下的博客-CSDN博客

说明:

参考1是一个包含了BL1/BL2/BL31/BL33/Linux的一个完整启动过程

参考2制作了uboot->linux的启动过程,描述了启动时出来的根文件系统加载出错及解决方法

参考3讲述了根文件系统的概念及其制作

参考4主要说明了init进程与init程序的不同,init进程是内核启动,从内核态转到用户态时会执行根文件系统中的init程序,可以是linuxrc(软链接到busyboxy), systemv, systemd等

二、ATF编译:

wmx@wmx-VirtualBox:~/work/arm-trusted-firmware$ cat build-atf.sh
export ARCH=arm64
export CROSS_COMPILE=/home/wmx/Downloads/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
make PLAT=qemu BL33=/home/wmx/work/u-boot/u-boot.bin all fip DEBUG=1

三、u-boot编译:

wmx@wmx-VirtualBox:~/work/u-boot$ cat build-uboot.sh
export ARCH=arm64
export CROSS_COMPILE=/home/wmx/Downloads/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
make qemu_arm64_defconfig
make

四、qemu+atf+uboot+linux启动:

wmx@wmx-VirtualBox:~/work$ cat qemu-atf-kernel.sh
qemu-system-aarch64 \
    -nographic \
    -M virt,secure=on,gic_version=3 \
    -cpu cortex-a53 \
    -smp 2 \
    -m 2048 \
    -d guest_errors,unimp \
    -bios /home/wmx/work/arm-trusted-firmware/build/qemu/debug/bl1.bin \
    -drive file=/home/wmx/work/buildroot/output/images/rootfs.ext4,if=none,id=blk1,format=raw \
    -device virtio-blk-device,drive=blk1 \
    -kernel /home/wmx/work/linux-4.19.294/arch/arm64/boot/Image \
    -semihosting-config enable=on,target=native

五、代码执行流程:

1)BL1加载BL2并跳转到BL2入口

2)BL2加载BL31

3)BL2加载BL33,即加载u-boot.bin

前面的加载过程会用到plat/qemu/common/qemu_io_storage.c中定义的文件名,需要修改为本机的实际存储位置

4)BL2返回到BL1,并从BL1进入BL31

此时BL31由于尚未设置其自身的smc异常处理程序而无法直接处理该异常,因此,为了完成跳转流程,BL1需要先代理该异常的处理。因此BL1在退出之前先设置smc异常处理函数,

BL2触发smc启动BL31时,bl2/bl2_main.c 函数bl2_main中通过smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0); 进入BL1. 

BL1捕获该异常,进入bl1/aarch64/bl1_exceptions.S 的 SynchronousExceptionA64-> smc_handler64 ,并根据BL2传入的参数设置BL31的入口地址和系统初始状态,并通过ERET跳转到BL31的入口地址处执行

5)BL31会初始化GICv3及runtime service(SMC调用的服务),并进入BL33(u-boot)执行

六、BL31:

runtime_svc.c->runtime_svc_init函数:

主要是初始化SMC调用时的处理函数,rt_svc_descs通过 DECLARE_RT_SVC声明,并链接到RT_SVC_DESCS_START和RT_SVC_DESCS_END范围内. 当前qemu平台上会有两个rt_svc_descs, 分别是arm_arch_svc和std_svc。 分别在services/arm_arch_svc/arm_arch_svc_setup.c 和services/std_svc/std_svc_setup.c中声明

七、linux启动:
加载根文件系统出错:

[    1.509470] VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
[    1.510035] Please append a correct "root=" boot option; here are the available partitions:
[    1.510827] fe00           61440 vda
[    1.510862]  driver: virtio_blk
[    1.511514] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

根文件系统是内核启动时所mount的第一个文件系统,是加载其他文件系统的“根”。一套linux体系,只有内核本身是不能工作的,必须要rootfs配合才能工作,根文件系统中通常包含etc目录下的配置文件、/bin /sbin等目录下的shell命令,还有/lib目录下的库文件等。 

根文件系统是Linux内核启动之后读取的一个文件系统,并从这个文件系统中加载第一个init应用程序并启动,就是Linux上俗称的root进程、根进程。制作根文件系统纯粹就是在通过文件形式来构造一个Linux系统,为内核提供用户态的体系

在启动脚本中添加:-append "console=ttyAMA0 root=/dev/vda" \

busybox init进程分析:init_main()也即busybox中的init进程入口。init上承kernel,下起用户空间进程,配置了整个用户空间工作环境。首先初始化串口、环境变量等;解析/etc/inittab文件;初始化信号处理函数;然后依次执行SYSINIT、WAIT、ONCE选项;最后在while(1)中监控RESPAWN|ASKFIRST选项。

启动后一直进不了shell界面,发现inittab中的有getty的配置如下:

而上面qemu里配置的console是ttyAMA0, 更改buildroot配置 make menuconfig->System configuration->Run a getty(login prompt) after boot -> TTY port, 修改为ttyAMA0

重新启动系统可以到登录界面:

重新配置buildroot,增加root登录及密码:

以root及配置的密码登录即可

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值