ARM Development Studio 2021 FVP调试Linux内核代码


前言

ARM Development Studio 2021是一款集开发、调试、性能追踪等功能的高性能IDE,这款IDE可以配合DStream仿真器对arm嵌入式平台进行高效开发。其中,ARM FVP是arm提供的一个软件仿真平台,在还没有RTL EMU的情况下可以快速调试软件,加快软件的开发进度。在我们安装DS2021的时候已经自带了一部分FVP,如果你需要使用其他的FVP,可以去ARM官网购买下载。

此文主要使用FVP Base Platform Cortex-A76来调试Linux内核代码,关于FVP Base Platform的详细信息可以参考fast_models_rm_100964_1116_00_en.pdf这个文档的第八章节内容,里面详细说明了关于模拟基础平台的地址分配、中断、时钟等详细信息。你可以把FVP Base Platform Cortex-A76看作一个现成的开发板,上面那个文档作为它的开发手册即可。

注意:本文所使用的主机环境为windows10操作系统,虚拟机环境为Ubuntu16


一、安装DS2021

我们在官网下载armds2021进行安装,下载链接:armds2021下载
在这里插入图片描述
如上图所示,有两个版本(windows,linux)根据需求选择合适的版本,然后选择试用30天的证书即可。也可以下载破解版的,链接如下:ARMDS2021破解版

安装完成之后,在D:\ARMDS\bin(安装路径)下可以看到有这么多fvp可以使用:
在这里插入图片描述


二、构建Linux内核

此过程在虚拟机ubuntu下进行

2.1 下载Linux内核

从官网下载Linux内核源码:

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

使用命令tar xvf linux-5.2.11.tar.xz进行解压缩,然后进入linux-5.2.11

tar xvf linux-5.2.11.tar.xz
cd linux-5.2.11

2.2 构建Linux内核

进行默认配置和界面化配置,然后开始编译

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4 all

工具链如何配置可以参考我的另一篇博客

然后等待编译完成,生成以下文件:
在这里插入图片描述
构建完成以后,生成以下镜像
arch/arm64/boot/Image
arch/arm64/boot/dts/arm/foundation-v8-gicv3-psci.dtb
其中Image是内核镜像文件,foundation-v8-gicv3-psci.dtb是设备树文件,这两个文件是以下我们需要用到的。


三、构建boot-wrapper-aarch64

此过程在虚拟机ubuntu下进行

boot-wrapper-aarch64是FVP用于引导Linux内核启动的引导文件,作用类似uboot,是一个用于调试的简易boot程序。如果你仅调试内核,建议使用这个引导程序。

3.1 下载boot-wrapper-aarch64

从官网下载源码:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

3.2 构建boot-wrapper-aarch64

进行Bootwrapper的配置:

cd boot-wrapper-aarch64
autoreconf -i
./configure --enable-psci --enable-gicv3 --with-kernel-dir=/home/xt/20220816boot-wrapper-aarch64/linux-5.2.11/arch/arm64/boot --with-dtb=fvp-base-gicv3-psci.dtb --host=aarch64-linux-gnu --with-cmdline="rdinit=/linuxrc console=ttyAMA0"

注意:
–enable-psci : 使能psci
–enable-gicv3 : 使能gicv3
–with-kernel-dir: 用于指定内核目录,就是2.2中内核的路径
–with-dtb: 用于指定DTB文件,就是2.2中编译出来的foundation-v8-gicv3-psci.dtb
–host: 用于指定编译工具
–with-cmdline: 用于制定内核启动参数
–with-kernel-dir用于指定内核映像目录,–with-dtb用于指定DTB文件,从而将这些文件链接到中最终的image文件中;
更多配置选项可以通过./configure --help获取;
模拟器对应的硬件平台的DTB文件可以从Linaro发行版目录下载,例如所用的DTB文件来自archive/14.09/openembedded/aarch64/。
然后make,生成以下文件:

make

在这里插入图片描述

其中我们需要使用到的文件是linux-system.axf,里面包含了启动文件和linux系统镜像文件。

四、调试Linux内核

4.1 开启telnet

FVP 模型使用telnet作为串行终端,通过建模的 UART 从运行在 FVP 模型上的应用程序代码传输串行数据。Windows 7 及更高版本默认不启用 telnet 客户端。如果你的计算机上禁用了 telnet 客户端,可能会看到错误:“Windows 找不到 C:\Windows\System32\telnet.exe”或“在的系统上找不到 telnet 可执行文件”。
要启用 telnet 客户端:

  1. 右键单击开始菜单,然后选择设置
  2. 搜索Telnet,然后选择打开或关闭 Windows 功能
  3. 从出现的列表中,勾选Telnet Client复选框
  4. 单击确定关闭对话框。

4.2 配置FVP

打开DS2021,选择菜单栏的run/Debug Configurations,如下所示:
在这里插入图片描述
首先配置Connection选项卡,选择FVP类型,一定要选择带有Installed with Arm DS这一选项的FVP(这是安装包自带的,直接可以使用),然后根据自己的需求选择相应的FVP。此处我选择的是Base_A76x1->Bare Metal Debug->Cortex-A76,其中还有一个Linux Kernel Debug的选项卡也可以用,这个可以调试Linux线程。配置模型参数,在Model parameters中输入:

-C bp.secure_memory=false -C cache_state_modelled=0 -C pctl.startup=0.0.*.* -C bp.refcounter.non_arch_start_at_default=1

模型参数可以在DS命令行的help中找到:
bp.secure_memory=false 代表模型使用非安全空间
cache_state_modelled=0 代表模型的cache状态是否打开
bp.refcounter.non_arch_start_at_default=1 这个参数特别重要,控制处理器核内generic timer是否使能,默认是不使能的,如果generic timer未打开,Linux系统就无法正常工作。(现象是进程切换不成功,应该是generic无法工作导致中断无法产生)关于generic timer的说明:
在这里插入图片描述
接下来配置 File 选项卡:
在这里插入图片描述
在Target Configuration中选择3.2章节构建的linux-system.axf文件,勾选Load symbols选项。
最后配置 Debugger 选项卡
在这里插入图片描述
选择Debug from entry point选项,在Source search directory中选择boot-wrapper-arrch64和linux内核源码的所在路径。

到此FVP配置关闭,点击Debug,开始调试。

4.3 调试Linux内核

经过4.2章节的配置之后,点击debug,会出现以下界面:
在这里插入图片描述
程序的起始点是在boot的程序入口处,源码在boot-wrapper-aarch64\arch\aarch64\boot.S中,里面的程序主要对串口、中断等做了一些初始化操作,感兴趣的同学可以仔细阅读一下源码,在这就不分析源码了。
接下来我们在linux内核的入口处打一个断点,在Commands输入:

break el2:0x80080000

然后按F8全速执行,串口会打印以下信息,我们可以看到linux内核镜像的起始位置是在0x80080000处。
在这里插入图片描述
执行到断点处我们发现代码窗口没有显示相应的代码,因为还没有加载符号表vmlinux,vmlinux是在编译linux内核时根目录下的生成的文件。我们可以使用命令aarch64-linux-gnu-readelf -S vmlinux来查看:
在这里插入图片描述

可以看出".head.text"段的链接地址为0xffff000010080000,而此时处理器MMU还没有打开,处理器是运行在物理地址上,对应的物理地址是0x80080000。我们需要计算一个偏移量让add-symbol-file命令把vmlinux各个段的符号表加载到物理地址中:
0x80080000 - 0xffff000010080000 = -0xfffeffff90000000

故在Commands输入

add-symbol-file "可用路径\vmlinux" -0xfffeffff90000000

加载完符号表之后,程序定位到linux入口处(arch/arm64/kernel/head.S)
在这里插入图片描述
此阶段的源码也不一一分析,重点是开启MMU之后,需要重新加载符号表,这一次加载符号表就是不带偏移的加载。
我们可以先单步运行到__primary_switch处,__enable_mmu开启MMU,然后执行完BR X8语句。
在这里插入图片描述
加载符号表:

add-symbol-file "可用路径\vmlinux"

加载完显示如下:
在这里插入图片描述
然后运行到arch/arm64/kernel/head.S line:456 的start kernel 语句:
在这里插入图片描述
到此汇编阶段执行完毕,接下开始执行main.c的startkernel初始化函数,源码不在此处分析。
在这里插入图片描述
然后我们可以按F8全速运行,在串口终端可以看到,Linux系统已经正常运行起来了。
在这里插入图片描述

总结

此文只是阐述了FVP功能的冰山一角,更多的内容可以参考官网相关FVP使用文档,其中部分内容参考:
ARM DS-5单步调试ARM64 linux 内核
ARM FVP(固定虚拟平台)Linux内核调试简明手册
有其他问题可以私信联系我,或者发我邮箱982833950@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值