qemu单步调试arm64 linux kernel

一、背景和目的

qemu搭建arm64 linux kernel环境-CSDN博客

之前介绍了qemu启动kernel的配置步骤和方法,现在开始我们的调试,这篇文章主要讲解如何单步调试内核,所有的实验还是基于ARM64;

二、环境准备

需要准备host=x86 target = arm64的gdb, 有三种方式:一种是sudo apt install gdb-multiarch;

另外一种是用ARM官网下载交叉编译工具链,其中自带gdb(目前我使用的方式Arm GNU Toolchain Downloads – Arm Developer); 还有一种是下载gdb源码并编译;

不同的方式有些差异,用apt安装的如果ubuntu比较老,可能存在部分特性不支持(比如ARMv8.5的PAC,BTI等,之前用ubuntu18.04就遇到了);

注意:使用ARM 官网gdb的伙伴启动时可能会遇到缺少库和python3.8的报错(依赖libncurses5 ,libncursesw5及python3.8),可以参考下面解决(偷懒可以直接安装gdb-multiarch)

三、kernel debug

单步调试kernel 只需要三步:

第一步:qemu启动内核并暂停等待(暂停是可选的,如果不调启动,可以去掉),同时需要建立网络端口等待gdb attach;

第二步:启动gdb(target=arm64)加载对应kernel Image的vmlinux, attach到指定端口即可;

第三步:如果是启动是挂起,直接设置断点即可调试,如果未选择启动暂停,ctrl + c会触发挂起,然后就可以和前面一样,正常设置断点。

qemu启动调试脚本(注意这里有个小坑,直接调试的伙伴直接跳转到最后拷贝即可

qemu-system-aarch64 \
    -machine virt,virtualization=true,gic-version=3 \
    -nographic \
    -m size=1024M \
    -cpu cortex-a72 \
    -smp 2 \ 
    -kernel Image \
    -drive format=raw,file=rootfs.img \
    -append "root=/dev/vda rw" \
    -s \
    -S

可以看到对比之前的启动参数也就是增加了-s 和-S,具体含义如下:
# -s 是-gdb tcp::1234 的简写,如果需要换端口可以用-gdb tcp::1234替换-s参数
# -S 是freeze cpu at startup的指令,也就是kernel 启动时就挂起,等待调试连接,如果不需要调试内核启动,这个参数也
     可以去掉

gdb启动
找到vmlinux所在目录(最好在linux编译的根目录,不要拷贝出来,这样调试源码可以直接显示,不然还要在gdb中设置src path),
geek@geek-virtual-machine:~/workspace/linux/linux-6.6.1$ aarch64-none-linux-gnu-gdb vmlinux

(gdb) target remote :1234
Remote debugging using :1234
0x0000000040000000 in ?? ()
(gdb) b start_kerne

然后continue即可停在指定断点,后面就可以step 单步调试了,实际调试时会发现设置的断点start_kernel停不住,ctrl+c 触发挂起时会出现bt无法显示相关符号等问题

(gdb) bt
#0  0xffffd43266a17f6c in ?? ()
#1  0xffffd43265ad7ad0 in ?? ()
#2  0x0000000000000002 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
 

这里的原因也是经常会遇到和遗忘的,查看kernel log可以看到KASLR字样

[    0.000000] KASLR enabled
[    0.000000] CPU features: kernel page table isolation forced ON by KASLR

KASLR是内核启动添加随机地址保护,启动后实际运行地址和vmlinux 有一个随机偏移值,在gdb中设置断点是基于vmlinux的(这个是不带偏移值的),实际qemu中运行的内核是在这个地址 + 随机偏移值,所以断点无法触发,出现上面的问题;

上面的问题有两种解决方法:

1、是重新编译内核,在arch/arm64/configs/defconfig 中将CONFIG_RANDOMIZE_BASE=y修改成CONFIG_RANDOMIZE_BASE=n

2、是在qemu启动的cmdline中增加nokaslr 参数,通过参数方式关闭

      -append "root=/dev/vda rw nokaslr" \

修改正常后,断点能正确停止,bt调用栈显示正常

(gdb) bt
#0  cpu_do_idle () at arch/arm64/kernel/idle.c:32
#1  0xffff800081017f80 in arch_cpu_idle () at arch/arm64/kernel/idle.c:44
#2  0xffff800081018bcc in default_idle_call () at kernel/sched/idle.c:97
#3  0xffff8000800d7ad0 in cpuidle_idle_call () at kernel/sched/idle.c:170
#4  do_idle () at kernel/sched/idle.c:282
#5  0xffff8000800d7d48 in cpu_startup_entry (state=CPUHP_ONLINE) at kernel/sched/idle.c:380
#6  0xffff800081018eac in rest_init () at init/main.c:726
#7  0xffff800081aa08bc in arch_call_rest_init () at init/main.c:823
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

四、总结

qemu内核调试时需要注意关闭kaslr,更新正确的脚本,也不依赖kenerl config是否开启kaslr

qemu启动脚本(最终版本):

qemu-system-aarch64 \
    -machine virt,virtualization=true,gic-version=3 \
    -nographic \
    -m size=1024M \
    -cpu cortex-a72 \
    -smp 2 \ 
    -kernel Image \
    -drive format=raw,file=rootfs.img \
    -append "root=/dev/vda rw nokaslr" \
    -s \
    -S

关于kaslr原理相关的知识,有兴趣的伙伴参考 文章 kaslr原理分析

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VirtualBox:安装提示缺少python core和win32 api

最近升级了Ubuntu22.04,查了一下,VirtualBox的增强功能,居然用时5分钟。 5min 18ms vboxadd.service 据说升级VirtualBox的增强功能能解决这个问题,于是先升级VirtualBox,但是安装VirtualBox却报缺少python core及win3…

Android App开发-简单控件(4)——按钮触控和图像显示

3.4 按钮触控 本节介绍了按钮控件的常见用法,包括:如何设置大小写属性与点击属性,如何响应按钮的点击事件和长按事件,如何禁用按钮又该如何启用按钮,等等。 3.4.1 按钮控件Button 除了文本视图之外,按钮…

【GAMES101】Lecture 11 贝塞尔曲线

曲线这部分基本上就单讲了贝塞尔曲线 目录 贝塞尔曲线(Bezier curves) De Casteljau’s algorithm B-splines 贝塞尔曲线(Bezier curves) 很早之前说过的这种矢量图是不会随着放大而失真的,像这种字体&#xff0c…

Mysql第一天

数据库概述 1. 为什么要使用数据库 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。(可掉电:内存 使用高电压和低电压来区别0和1进行数据的一个存储但是一旦断电了电压都没了 0和1也就没有了)大多数情况下,特别是企 业级应用&#…

CSS 星空按钮

<template><button class="btn" type="button"><strong>星空按钮</strong><div id="container-stars"><div id="stars"></div></div><div id="glow"><div class=…

HCIA-HarmonyOS设备开发认证-3.内核基础

目录 前言目标一、进程与线程待续。。。 前言 对于任何一个操作系统而言&#xff0c;内核的运行机制与原理是最为关键的部分。本章内容从多角度了解HarmonyOS的内核运行机制&#xff0c;涵盖进程与线程的概念&#xff0c;内存管理机制&#xff0c;网络特性&#xff0c;文件系统…

vue3 + ts vue_3.4 setup单文件组件中的属性

props 各种类型 <script lang"ts" setup>import { ref, PropType } from vue;interface listType {addres: string;code: number;}interface ftObj {obj1: string[];obj2: {[key: string]: any;};}const props defineProps({name: {type: String as PropType&…

C 练习实例50-使用Dev-C++创建项目(圆形体体积计算器)

项目展示 项目案例&#xff1a;圆形体体积计算器 vol.h文件 #include <stdio.h> #include <math.h> #define PI 3.141592654 void cal(int sel); //函数声明 double vol_ball(void); double vol_cylind(void); double vol_cone(void); main.c文件 #include &quo…

代理IP使用指南:风险与注意事项

在当今的数字化时代&#xff0c;使用在线代理IP已经成为一种常见的网络行为。然而&#xff0c;在使用这些代理IP时&#xff0c;我们需要注意一些风险和问题&#xff0c;以确保我们的网络安全和隐本私文。将探讨使用代理IP时需要注意的几个关键问题。 1、代理IP的安全性 使用代理…

【JavaLearn】#(29)Maven引入、Maven项目类型、Maven安装与配置、Maven项目的创建和使用、pom配置文件介绍

1. Maven引入 1.1 传统方式中项目jar包资源的问题 项目中的jar包资源&#xff08;如JDBC驱动包&#xff09;需要我们自己从网上下载&#xff0c;然后手动导入到项目中使用 –> 一旦jar包资源过多&#xff0c;容易造成遗漏&#xff0c;且不好管理 如果有两个项目&#xff0…

LabVIEW动态数据交换实现数据通信

LabVIEW动态数据交换实现数据通信 介绍了LabVIEW软件在驱动一般多功能接口卡中的应用。LabVIEW作为一种图形化编程平台&#xff0c;被广泛应用于自动测量系统、工业过程自动化等领域。利用LabVIEW驱动实验室中常用的多功能接口卡&#xff0c;以实现数据采集和分析。 系统主要…

C#算法(11)—求三个点构成圆的圆心坐标和半径

前言 我们在上位机开发领域也经常会碰到根据三个点求出圆的圆心、半径等信息的场景,本文就是详细的介绍如何根据三个点使用C#代码求出三点构成的圆的圆心坐标、圆半径、三点构成的圆弧的角度。 1、3点求圆分析 A、B、C三个点都是圆上的坐标点,过向量AB做中垂线,过向量AC做…

HCIP寒假第十次作业

第一步&#xff0c;给pc配置IP192.268.1.2-192.168.1.4 第二步&#xff0c;在三个交换机上划分vlan [sw1]vlan 3 [sw1]interface e0/0/2 [sw1-Ethernet0/0/2]port link-type access [sw1-Ethernet0/0/2]port default vlan 3 [sw2]vlan 2 lsw2]interface e0/0/2 [sw2…

【c++】构造函数和析构函数

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器…

2024年第一篇博客

这是2024年的第一篇博客&#xff0c;2023年笔者经历了一连串的生活、工作、学习上的转折和调整&#xff0c;跌跌撞撞时光飞逝&#xff0c;转眼间就踏着元旦的钟声步入了2024年&#xff0c;前思后想、辗转反侧、犹豫再三不知道从哪里开始博客新的篇章&#xff0c;这个问题坦诚说…

【Spark系列3】RDD源码解析实战

本文主要讲 1、什么是RDD 2、RDD是如何从数据中构建 一、什么是RDD&#xff1f; RDD&#xff1a;弹性分布式数据集&#xff0c;Resillient Distributed Dataset的缩写。 个人理解&#xff1a;RDD是一个容错的、并行的数据结构&#xff0c;可以让用户显式的将数据存储到磁盘…

嵌入式Linux系统引导过程中的设备驱动加载

大家好&#xff0c;今天给大家介绍**嵌入式Linux系统引导过程中的设备驱动加载&#xff0c;**文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 **在嵌入式Linux系统的引导过程中&#xff0c…

杨占华主任:冠心病,中医好还是西医好

冠心病是一种慢性疾病&#xff0c;治疗时间相对较长&#xff0c;恢复缓慢。一般来说&#xff0c;冠心病患者也面临着巨大的心理压力。选择中药治疗好还是西药治疗好&#xff1f; 冠心病的西医治疗主要包括药物治疗、冠状动脉支架植入和冠状动脉搭桥术。 中医治疗冠心病的主要方…

Open CASCADE学习|读取STEP文件并显示

STEP文件是基于ISO 10303标准创建的三维模型数据交换文件&#xff0c;也称为产品模型数据交换标准&#xff08;Standard Exchange of Product data model&#xff09;。这种文件格式旨在提供一个不依赖具体系统的中性机制&#xff0c;实现产品数据的交换和共享。 STEP文件是一…

OJ_键盘输入问题

题干 c语言实现 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<vector> #include<map> using namespace std;int main() {//记录每个字母需要花费多少时间map<char, int> inputTime {{a,1},{b,2},{c,3},{d,1},{e,2},{f,3},{g,1},{h,2…