使用QEMU调试ARM64 Linux内核v6.0.9

news2025/7/11 18:39:33

环境准备

开发环境:Ubuntu 20.04.5 LTS,推荐修改阿里云的apt源,遇到编译依赖方便安装。
环境准备:在Windows上基于WSL2搭建Linux开发环境
本文用到的软件选用的是截至当前(2022-11-19)官网发布的最新的release版本,详细如下:

软件版本官网发布日期说明
Linux6.0.9https://kernel.org2022-11-16Linux内核
BusyBox1.35.0https://busybox.net2021-11-26集成工具集,方便制作根文件系统
QEMU7.2.0-rc1https://www.qemu.org2022-11-15仿真ARM64开发板

新建一个工作目录,编译准备所有所需软件,最终所需文件如下:

├── busybox-1.35.0
├── busybox-1.35.0.tar.bz2
├── linux-6.0.9
├── linux-6.0.9.tar.xz
├── make_initrd.sh
├── qemu-7.2.0-rc1
├── qemu-7.2.0-rc1.tar.xz
└── qemu.sh

说明1:make_initrd.sh 是为了自动化制作根文件系统
说明2:qemu.sh 是使用QEMU拉起Linux的shell脚本

本文后面将详细介绍如何编译和使用每一个软件,以及上面提到的两个脚本的内容和功能。

编译ARM64 Linux

下载Linux源码

官网下载当前最新的release版本:

wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.0.9.tar.xz
tar xvf linux-5.19.11.tar.xz linux-5.19.11

交叉编译ARM64 Linux

使用menuconfig勾选RAM disks支持,并调整大小为: 65536 kb:

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 O=build menuconfig -j32
    Device Drivers > Block devices
	  <*>   RAM block device support
        (16)    Default number of RAM disks (NEW)
        (65536) Default RAM disk size (kbytes)

说明:

  • O=build 表示编译的文件输出到build目录,不跟源码混在一起;
  • -j32 表示开启32线程编译,注意线程太多可能会偶现时序导致的编译错误;

交叉编译ARM64 Linux内核,编译完毕后,对应目录会有生成的内核镜像:

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 O=build -j32
file build/arch/arm64/boot/Image 

使用AMD 5800电脑,大概5min就可以编译完毕。

编译ARM64 BusyBox

下载BusyBox源码

官网下载最新的release版本:

wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
tar xvf busybox-1.35.0.tar.bz2 

交叉编译ARM64 BusyBox

使用menuconfig修改为静态链接:

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 menuconfig -j32 
    Settings
	  [*] Build static binary (no shared libs)

编译BusyBox可执行文件,并输出到_install目录:

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 install -j32
file _install/bin/busybox

基于BusyBox制作initrd

制作initrd步骤略多。这里make_initrd.sh就是用来自动制作initrd的脚本,内容:

#!/bin/bash

MOUNT_DIR=mnt
CURR_DIR=`pwd`

rm initrd.ext4
dd if=/dev/zero of=initrd.ext4 bs=1M count=32
mkfs.ext4 initrd.ext4

mkdir -p $MOUNT_DIR
mount initrd.ext4 $MOUNT_DIR
cp -arf busybox-1.35.0/_install/* $MOUNT_DIR

cd $MOUNT_DIR
mkdir -p etc dev mnt proc sys tmp mnt etc/init.d/

echo "proc /proc proc defaults 0 0" > etc/fstab
echo "tmpfs /tmp tmpfs defaults 0 0" >> etc/fstab
echo "sysfs /sys sysfs defaults 0 0" >> etc/fstab

echo "#!/bin/sh" > etc/init.d/rcS
echo "mount -a" >> etc/init.d/rcS
echo "mount -o remount,rw /" >> etc/init.d/rcS
echo "echo -e \"Welcome to ARM64 Linux\"" >> etc/init.d/rcS
chmod 755 etc/init.d/rcS

echo "::sysinit:/etc/init.d/rcS" > etc/inittab
echo "::respawn:-/bin/sh" >> etc/inittab
echo "::askfirst:-/bin/sh" >> etc/inittab
chmod 755 etc/inittab

cd dev
mknod console c 5 1
mknod null c 1 3
mknod tty1 c 4 1

cd $CURR_DIR
umount $MOUNT_DIR
echo "make initrd ok!"

介绍一下这个脚本的实现和功能:

  1. 使用 ddinitrd.ext4 制作一个空的32M的ext4格式的文件系统;
  2. mount这个文件系统,然后拷贝busybox编译的文件进去;
  3. 创建Linux的关键的标准层级目录 Filesystem Hierarchy Standard (FHS) ;
  4. 创建 /etc/fstab,这是mount自动挂载配置文件,可参考:mount命令及/etc/fstab文件详解
  5. 创建 /etc/init.d/rcS,这是文件系统的初始化脚本,可参考:嵌入式linux /etc/init.d/rcS文件解读
  6. 创建 /etc/inittab,init进程会解析inittab文件,可参考:/etc/inittab文件的作用

这片文章也挺不错:制作嵌入式根文件系统(常见问题详解)

使用QEMU拉起ARM64 Linux

下载QEMU源码

官网下载最新的release版本:

wget https://download.qemu.org/qemu-7.2.0-rc1.tar.xz
tar xvf busybox-1.35.0.tar.bz2

编译可拉起aarch64内核的QEMU

进入qemu源码目录后,编译步骤如下:

cd qemu-7.2.0-rc1
mkdir build
cd build
../configure --target-list=aarch64-softmmu
make -j32
file aarch64-softmmu/qemu-system-aarch64

使用QEMU virt拉起ARM64 Linux

运行 qemu.sh 即可拉起 ARM64 Linux,使用的ARM机器就是是QEMU仿真的virt machine。
注意:QEMU的virt machine默认CPU是cortex-a15,这是一个32位CPU。选择ARMv8的64位CPU可用cortex-a57。
查看QEMU支持的machine和cpu方法如下:

cd qemu-7.2.0-rc1/build/aarch64-softmmu
./qemu-system-aarch64 -M help      # 查看支持的machine
./qemu-system-aarch64 -cpu help    # 查看支持的CPU

启动脚本 qemu.sh 内容如下:

#!/bin/bash

qemu/build/aarch64-softmmu/qemu-system-aarch64 \
    -nographic \
    -M virt \
    -cpu cortex-a57 \
    -smp 2 \
    -m 4G \
    -kernel linux-6.0.9/build/arch/arm64/boot/Image \
    -append "nokaslr root=/dev/ram init=/linuxrc console=ttyAMA0 console=ttyS0" \
    -initrd initrd.ext4

说明:上面append选项用来给内核传递命令行参数,nokaslr 表示关闭地址随机化,方便gdb调试内核。

GDB调试ARM64 Linux

QEMU是一个仿真器,有内置的GDB server,给内核提供了强大的调试功能。基本用法如下:

修改 qemu.sh 脚本,加入 -s -S 参数,修改后如下:

#!/bin/bash

qemu/build/aarch64-softmmu/qemu-system-aarch64 \
    -nographic \
    -M virt \
    -cpu cortex-a57 \
    -smp 2 \
    -m 4G \
    -kernel linux-6.0.9/build/arch/arm64/boot/Image \
    -append "nokaslr root=/dev/ram init=/linuxrc console=ttyAMA0 console=ttyS0" \
    -initrd initrd.ext4 \
    -s -S

这是执行 qemu.sh 脚本会停住,新开一个终端,使用如下命令调试

cd linux-6.0.9/build
gdb-multiarch vmlinux
# 进入gdb交互界面后,执行
    target remote :1234
    b start_kernel
    c
# 即可在内核入口函数断注

内核大部分时间都在cpu idle,一般在gdb交互界面随机按 ctrl+c就是停在这个状态,调试大概如下截图:
gdb
后面就可以非常方便的调试内核了:

  1. 在QEMU的交互console可以看一些硬件寄存器等信息;
  2. 在GDB的交互console可以像调试普通应用程序一样调试内核;

需要注意的是:内核只能用O2编译,很多变量都被优化了,不很方便。

可用下面方法来局部O0编译:

  • #pragma GCC optimize ("O0") 写在文件开头,O0编译本文件
  • __attribute__((optimize("O0"))) 写在函数开头,O0编译本函数

具体可以参考:使用 O0 编译 调试 Linux内核的某些部分 和 O0的内核

这样如果遇到需要单步执行,或者看一些变量信息,会更加的方便。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/18046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaEE之HTTPS

文章目录HTTPS加密引入证书总结HTTPS 加密 HTTPS 就是在 HTTP 的基础上进行了 加密 , 进一步的来保证用户的信息安全~ 举个例子: 83 版 <<火烧圆明园>> , 有人要谋反干掉慈禧太后. 恭亲王奕䜣给慈禧递的折子. 折子内容只是扯一扯家常,但套上一张挖了洞的纸就能看…

ESP32的BLE使用学习

UUID生成网站&#xff1a; Online UUID Generator Tool 0.前言 什么是低功耗蓝牙&#xff1f; BLE之所以被称为低功耗蓝牙&#xff0c;就是需要通讯的时候才握手&#xff0c;数据传输完成后&#xff0c;就断开连接。在通讯过程中&#xff0c;主动方是客户端&#xff0c;由客…

中微SC8F5771模拟IIC通信——指令运行速度的探索(附编译软件与烧录软件)

文章目录一、中微单片机烧录与使用编译软件烧录软件下载地址烧录软件二、模拟IIC三、逻辑分析仪下的时序一、中微单片机烧录与使用 编译软件 中微所使用编译软件为SCMCU_IDE&#xff0c;不过个人不推荐使用这个软件写代码&#xff08;十分不好用&#xff0c;不能跳转&#xf…

Linux搜索查找命令【详细整理】

目录Linux下文件搜索、查找、查看命令findfind 【搜索范围】【选项】​ find /home -name ‘hello.txt’​ find /home -user root​ find / -size 100Mlocate特别说明&#xff1a;locate 文件名whichwhich lsgrep​ 基本语法&#xff1a;grep [选项] 查找内容 源文件grep -niL…

第六章 图论 8 AcWing 1624. 地铁地图

第六章 图论 8 AcWing 1624. 地铁地图 原题链接 AcWing 1624. 地铁地图 算法标签 图论 单源最短路 dijkstra spfa 思路 若采用邻接矩阵存储 超出本题空间限制&#xff0c;因此无法采用邻接矩阵存储&#xff0c;可采用邻接表存储 若采用常规建图方式&#xff08;即相邻两…

微信小程序|基于小程序实现人脸融合

文章目录一、文章前言二、具体流程及准备三、开发步骤四、完整代码一、文章前言 此文主要通过小程序实现人脸图像融合&#xff0c;将检测到的两张人脸进行融合&#xff0c;输出一张融合后的人脸。 二、具体流程及准备 2.1、注册百度开放平台及微信公众平台账号。 2.2、下载及安…

概论_第2章随机变量及其概率分布__离散型随机变量之二项分布

二项分布是离散型随机变量的内容 一. 定义&#xff1a; 若随机变量X的可能取值为0, 1, ... ,n, 而X的分布值为 , k0,1,…n 其中&#xff0c;0<p<1, q 1-p, 称X服从参数为n, p的二项分布&#xff0c; 简记为 X ~ B(n, p) 1. 当n1时&#xff0c; X服从0-1分布, …

想进入游戏建模行业,这4点必须了解

“游戏行业不关心你的专业&#xff0c;只关心你的作品”&#xff0c;想要进入游戏行业就记住这句话&#x1f44d; 这一年可是越来越多人想要进入游戏行业啦&#xff5e;造成了汤多肉少的情况&#xff0c;咱们怎样才能在一群竞争者中脱颖而出呢❓有4⃣大点你要注意的&#xff1…

决策树算法在计算机视觉中的应用附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

利用SpringBoot和vue+elementui做一个简单的书本信息管理系统

目录 1.准备工作 1.1.数据库准备 1.2.前端准备工作 1.3.后端准备工作 2.后台代码的编写 2.1.修改配置文件 2.2. 编写service层 2.3.编写Controller层 3.前台代码的编写 3.1.在src里面的api里面的action.js 3.2.搜索栏&#xff0c;表单 3.3.表格 3.4.弹出新增的模态…

[附源码]SSM计算机毕业设计整形美容咨询网站JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【考研复试】计算机专业考研复试英语常见问题二(研究方向/前沿技术/本科毕设篇)

相关链接&#xff1a; 【考研复试】计算机专业考研复试英语常见问题一&#xff08;家庭/家乡/学校篇&#xff09;【考研复试】计算机专业考研复试英语常见问题二&#xff08;研究方向/前沿技术/本科毕设篇&#xff09;【考研复试】计算机专业考研复试英语常见问题三&#xff0…

助老服务机器人结构设计

目 录 摘要 I Abstract II 第1章 绪论 1 1.1 课题背景 1 1.2 国外助老服务机器人的研究 1 1.2.1 爱尔兰PAM-AID 助老服务机器人 1 1.2.2 美国SmartCane 助老服务机器人 2 1.2.3 韩国WAR 助老服务机器人 3 1.2.4 日本助老服务机器人 4 1.2.5 可穿戴的外骨骼式助老服务机器人 4 …

(九)Spring之Bean的循环依赖问题

文章目录环境什么是Bean的循环依赖singleton下的set注入产生的循环依赖prototype下的set注入产生的循环依赖构造注入产生的循环依赖singleton下的构造注入prototype下的构造注入Spring解决循环依赖的机理&#xff08;底层实现&#xff09;上一篇&#xff1a;&#xff08;八&…

注释写的好,文档不潦草.

大家好&#xff0c;long time no see&#xff01;这次聊一聊「注释」。写「注释」的好处众所周知&#xff0c;但有时在实现一些「公共代码」后&#xff0c;需要编写「文档」&#xff0c;其中「注释」和「文档」的内容是大致相同的&#xff0c;比如param和returns等(相信有不少同…

Java_抽象类和接口(一)

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE领域博主 专栏&#xff1a;JavaSE 作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 一、抽象类 1.1 抽象类概念 1.2 抽象类语句 1.3 抽象类特性 1.4 抽象类和普通类的区别 1.5 抽…

赞不绝口!仅靠阿里P9分享的 Redis 工作手册,拿到60W年薪Offer

昨晚有六七位小伙伴告诉我说&#xff1a;“大佬&#xff0c;有没有Redis的面试教程啊&#xff0c;最近面试被问到好多” 这就帮小伙伴们专门整理了一份资料&#xff08;不仅仅是面试题&#xff09;&#xff0c;从Redis核心原理到Redis设计与源码帮助大家梳理体系&#xff0c;快…

教你自己写Arcpy批处理程序

自己写Arcpy批处理栅格和矢量 先上代码&#xff0c;讲解各行代码的意思&#xff0c;从而达到自己写代码的目的 #....Edit by Longhao Wang.... import arcpy from arcpy import env from arcpy.sa import * import os import os.path import sys arcpy.env.workspace"D:…

Vue项目开发经验

文章目录前言网页组件echarts使用打包后显示包体积安装tensorflow和anaconda可能出现的错误![在这里插入图片描述](https://img-blog.csdnimg.cn/c1facd95a7f645c5af3e8dc1237913a3.png)总结前言 本博客仅做学习笔记&#xff0c;如有侵权&#xff0c;联系后即刻更改 科普&…

《调试九法》阅读笔记

1. 理解系统 阅读手册、仔细阅读每个细节、掌握基础知识、了解工作流程、了解工具。 2. 制造失败 制造失败、从头开始、引发失败、但不要模拟失败、查找不受你控制的条件、记录每件事情&#xff0c;并找到间歇性bug特征、不要过于相信统计数据、要认识到“那”是可能会发生的…