qemu调试kernel启动(从第一行汇编开始)

一、背景

大部分qemu调试kernel 都是讲解从start_kernel开始设置断点,然后开启调试; 但是我们熟悉linux启动流程的伙伴肯定知道,在start_kernel之前还有一段汇编,包括初始化页表及mmu等操作, 这部分如何调试呢?

二、如何从第一行代码开始调试?

无论是gdb调试还是JTAG调试,其中最重要的一个就是加载symbols 到正确的物理/虚拟地址(是物理地址还是虚拟地址取决于此时mmu是否有打开); 我们需要知道kernel 的第一行地址是什么? 对应的symbols的区域在vmlinux的哪里?

qemu 启动kernel的物理地址:

qemu 启动增加-S 选项时(启动时停止等待gdb 连接,这时会显示一个地址,这个就是当前启动的物理地址)

vmlinux中的的起始地址(虚拟地址):

在源码的System.map或者通过gdb打开vmlinux查看,内核的入口是_text,虚拟地址0xffff800080000000

_text的定义在arch/arm64/kernel/vmlinux.lds.S (注意,这里的section name:.head.text 放的是_text 不要和.text段名搞混了)

ENTRY(_text)
...
SECTIONS
{
....head.text : {_text = .;HEAD_TEXT}.text : ALIGN(SEGMENT_ALIGN) {	/* Real text segment		*/_stext = .;		/* Text and read-only data	*/IRQENTRY_TEXTSOFTIRQENTRY_TEXTENTRY_TEXTTEXT_TEXTSCHED_TEXTLOCK_TEXTKPROBES_TEXTHYPERVISOR_TEXT*(.gnu.warning)}. = ALIGN(SEGMENT_ALIGN);_etext = .;			/* End of text section */
...

qemu启动的物理地址和vmlinux 中启动地址(_text 虚拟地址)的关系

先来看qemu的启动地址0x0000000040000000 附近内容

(gdb) x /16i 0x00000000400000000x40000000:	ldr	x0, 0x400000180x40000004:	mov	x1, xzr0x40000008:	mov	x2, xzr0x4000000c:	mov	x3, xzr0x40000010:	ldr	x4, 0x400000200x40000014:	br	x40x40000018:	stxrh	w0, w0, [x0]0x4000001c:	udf	#00x40000020:	.inst	0x40200000 ; undefined0x40000024:	udf	#00x40000028:	udf	#00x4000002c:	udf	#00x40000030:	udf	#00x40000034:	udf	#00x40000038:	udf	#00x4000003c:	udf	#0(gdb)  x /16x 0x0000000040000000
0x40000000:	0x580000c0	0xaa1f03e1	0xaa1f03e2	0xaa1f03e3
0x40000010:	0x58000084	0xd61f0080	0x48000000	0x00000000
0x40000020:	0x40200000	0x00000000	0x00000000	0x00000000
0x40000030:	0x00000000	0x00000000	0x00000000	0x00000000

注意:不同的qemu版本可能起始的物理地址不同,本人电脑使用ubuntu22.04自带版本,6.2.0

geek@geek-virtual-machine:~/workspace/linux/linux-6.6.1$ qemu-system-aarch64 --version
QEMU emulator version 6.2.0 (Debian 1:6.2+dfsg-2ubuntu6.15)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers

源码路径:https://gitlab.com/qemu-project/qemu.git ,切换到6.2.0版本

geek@geek-virtual-machine:~/workspace/linux/qemu_src/qemu$ git tag | grep 6.2
v1.6.2
v2.6.2
v6.2.0
v6.2.0-rc0
v6.2.0-rc1
v6.2.0-rc2
v6.2.0-rc3
v6.2.0-rc4
geek@geek-virtual-machine:~/workspace/linux/qemu_src/qemu$ git reset --hard v6.2.0

qemu启动kernel的部分在qemu源码路径:hw/arm/boot.c

(gdb) si
0x0000000040000010 in ?? ()
=> 0x0000000040000010:	84 00 00 58	ldr	x4, 0x40000020(gdb) x /x 0x40000020
0x40000020:	0x40200000ldr	x4, 0x4000002  //把0x40000020 地址存储的值读取到x4,实际就是上面bootloader_aarch64[]数组定义的//FIXUP_ENTRYPOINT_LO + FIXUP_ENTRYPOINT_HI
br	x4    //跳转到x4 并执行

通过qemu 代码的注释也可以看到,在这个版本的qemu中arm64的kernel 起始地址是放在0x40200000,并从这里开始执行第一条指令;

所以我们要在qemu中做的就是将物理地址0x40200000 与vmlinux中的第一条指令地址0xffff800080000000 (_text) 对齐即可;

gdb 已经连接qemu linux kernel
(gdb) x /16x 0x40200000
0x40200000:	0xfa405a4d	0x146a6427	0x00000000	0x00000000
0x40200010:	0x02860000	0x00000000	0x0000000a	0x00000000
0x40200020:	0x00000000	0x00000000	0x00000000	0x00000000
0x40200030:	0x00000000	0x00000000	0x644d5241	0x00000040gdb vmlinux直接查看_text处的汇编
(gdb) x /16x _text
0x80000000 <_text>:	0xfa405a4d	0x146a6427	0x00000000	0x00000000
0x80000010 <$d+8>:	0x02860000	0x00000000	0x0000000a	0x00000000
0x80000020 <$d+24>:	0x00000000	0x00000000	0x00000000	0x00000000
0x80000030 <$d+40>:	0x00000000	0x00000000	0x644d5241	0x00000040

通过readelf确认那些段需要映射

geek@geek-virtual-machine:~/workspace/linux/linux-6.6.1$ aarch64-none-linux-gnu-readelf -S vmlinux
There are 43 section headers, starting at offset 0x18ff9fb8:Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .head.text        PROGBITS         ffff800080000000  000100000000000000010000  0000000000000000  AX       0     0     65536[ 2] .text             PROGBITS         ffff800080010000  00020000000000000102b000  0000000000000000  AX       0     0     65536[ 3] .rodata           PROGBITS         ffff800081040000  0105000000000000009dc8c8  0000000000000000  WA       0     0     4096
......[15] .rodata.text      PROGBITS         ffff800081a94800  01aa48000000000000005800  0000000000000000  AX       0     0     2048[16] .init.text        PROGBITS         ffff800081aa0000  01ab0000000000000008c6f8  0000000000000000  AX       0     0     8
......[19] .init.data        PROGBITS         ffff800081b95000  01ba500000000000000c551a  0000000000000000  WA       0     0     256
......

地址映射关系:

section namevirtual addrphy addr
.head.text0xffff8000800000000x40200000
.text0xffff8000800100000x40210000
.rodata0xffff8000810400000x40240000
.rodata.text0xffff800081a948000x41C94800
.init.text0xffff800081aa00000x41CA0000
.init.data0xffff800081b950000x41D95000

启动gdb 时不要加载vmlinux, 通过add-symbol-file 指定section 要加载的物理地址

add-symbol-file vmlinux -s .head.text 0x40200000 -s .text 0x40210000 -s .rodata 0x40240000 -s .rodata.text 0x41C94800 -s .init.text 0x41CA0000 -s .init.data 0x41D95000

设置断点:b _text

然后就可以单步调试:

三、总结

其实不管使用什么调试器(gdb/T32/Crash/lldb),第一步要做的都是将elf和调试target的执行地址做一个对齐,当然这个对齐可能是物理地址对齐(无mmu,如bootloader,elf编译的地址就是代码运行的物理地址),也有可能是虚拟地址对齐(开启了mmu 比如kernel start_kernel 之后部分),也有可能是物理地址与虚拟地址对齐(比如本文中的_text到start_kernel), 掌握了这个规律也就掌握的调试的入口密码。

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

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

相关文章

漏洞原理linux操作系统的SqlMap工具的使用

漏洞原理linux操作系统的SqlMap工具的使用 Linux操作系统基础操作链接: 1024一篇通俗易懂的liunx命令操作总结(第十课)-CSDN博客 kali的IP地址:192.168.56.1 实操 # kali中使用sqlmap http://192.168.56.1/ sqlmap -u http://192.168.56.1/news/show.php?id46 sqlmap -u …

​ArcGIS Pro 如何批量删除字段

在某些时候&#xff0c;我们得到的图层属性表内可能会有很多不需要的字段&#xff0c;如果挨个去删除会十分的麻烦&#xff0c;对于这种情况&#xff0c;我们可以使用工具箱内的字段删除工具批量删除&#xff0c;这里为大家介绍一下使用方法&#xff0c;希望能对你有所帮助。 …

如何创建用户友好的软件产品说明书?(上:建议篇)

之前我有写过关于制作和编写用户友好的产品说明书需要注意哪些地方&#xff0c;以及有哪些方法可以比较快速制作编写产品说明书。但是有网友在后台私信我&#xff0c;说想要知道细化到软件的产品说明书需要注意什么&#xff1f;所以我打算将关于“软件产品说明书”的主题分成两…

IDEA常用插件(本人常用,不全)

文章目录 一、图标提示类插件1、Lombok插件&#xff08;用户配合lombok依赖的工具&#xff09;2、MybatisX插件3、GitToolBox4、VUE.js&#xff08;vue编程使用&#xff09;5、ESLint&#xff08;vue编程使用&#xff09; 二、代码自动生成插件1、EasyCode插件&#xff1a;自动…

Android中下载 HAXM 报错 Intel® HAXM installation failed,如何解决?

最近在搭建 Flutter 环境&#xff0c;但是在 Android Studio 中安装 Virtual Device 时&#xff0c;出现了一个 问题 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at: https://github.com/intel/haxm/wiki/Installation-Instructio…

爬虫学习笔记-xpath的基本使用

html示例 基本使用 #导入包 #pip install lxmlfrom lxml import etree# xpath解析 # 1.本地文件 etree.parse # 2.服务器响应的数据 etree.HTML()tree etree.parse(baidu.html) # 获取所有的ul下的li标签 l1 tree.xpath(//ul/li) print(l1) print(len(l1))# 获取所有带有id的…

某大厂关于Linux系统相关面试题

一、Linux系统和Shell 1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;(1) 删除所有空行&#xff1b;(2) 在非空行前面加一个"AAA"&#xff0c;在行尾加一个"BBB"&#xff0c;即将内容为11111的一行改为&#xff1…

安防监控项目

一、安防监控项目的概述 安防监控项目是指利用先进的技术手段对特定区域、场所或对象进行全天候、全方位的监控和管理&#xff0c;以确保安全和防范各类安全风险。随着科技的不断发展&#xff0c;安防监控项目已经从传统的简单监控摄像头向数字化、智能化方向发展。这些项目广…

代码随想录算法刷题训练营day19

代码随想录算法刷题训练营day19&#xff1a;LeetCode(404)左叶子之和、LeetCode(112)路径总和、LeetCode(113)路径总和 II、LeetCode(105)从前序与中序遍历序列构造二叉树、LeetCode(106)从中序与后序遍历序列构造二叉树 LeetCode(404)左叶子之和 题目 代码 /*** Definitio…

E. Vlad and a Pair of Numbers(位运算)

思路&#xff1a;如果x在这一位是1&#xff0c;说明a,b在这一位一个是1一个是0&#xff0c;我们默认a为1&#xff0c;b为0.. 对于n的一些位为0&#xff0c;那么a&#xff0c;b在这一位肯定相同。我们想&#xff0c;如果a和b的和右移一位与x相同&#xff0c;所以1的位置是相同的…

图算法 - 最短路径算法 (dijkstra) 迪克斯特拉算法

解决问题: 图中某个顶点到某一个顶点的最短路径 适用场景: 查找带权图的最短路径 代码设计: 首先定义一张图(邻接矩阵,二维数组方式实现) 生成一张图 迪克斯特拉算法实现 采用贪婪的方式,每次获取最短的一条路径,作为下次遍历的起点 使用visited 记录被访问过的节点避免…

网络安全04-sql注入靶场第一关

目录 一、环境准备 1.1我们进入第一关也如图&#xff1a; ​编辑 二、正式开始第一关讲述 2.1很明显它让我们在标签上输入一个ID&#xff0c;那我们就输入在链接后面加?id1 ​编辑 2.2链接后面加个单引号()查看返回的内容&#xff0c;127.0.0.1/sqli/less-1/?id1,id1 …

sqli-labs-master less-1 详解

目录 关于MySQL的一些常识 information_schema 常用的函数 sqli-labs-master less-1 分析PHP源码 测试 关于MySQL的一些常识 information_schema information_schema 是 MySQL 数据库中的一个元数据&#xff08;metadata&#xff09;数据库&#xff0c;它包含…

C++ 数论相关题目 求组合数Ⅱ

给定 n 组询问&#xff0c;每组询问给定两个整数 a&#xff0c;b &#xff0c;请你输出 Cbamod(1097) 的值。 输入格式 第一行包含整数 n 。 接下来 n 行&#xff0c;每行包含一组 a 和 b 。 输出格式 共 n 行&#xff0c;每行输出一个询问的解。 数据范围 1≤n≤10000 , 1…

方法、数组

方法 是语句的集合&#xff0c;在一起执行一个功能 它是解决一类问题的步骤的有序集合 包含于类或对象中 在程序中创建&#xff0c;在其他地方被引用 设计方法的原则&#xff1a;方法的本意是功能块&#xff0c;就是实现某一个功能的语句块的集合。设计时&#xff0c;最好保持…

【ArcGIS微课1000例】0096:dem三维块状表达(层次地形模型)

文章目录 一、DEM表达方式二、层次模型表达三、注意事项一、DEM表达方式 DEM数字高程模型的表达方式通常有以下4种: 1. 规则格网 2. 不规则三角网 3. 等高线 4. 层次地形模型 作为栅格地理数据,DEM 数据具有2.5维的特征,能够以三维表面的形式进行三维空间表达。但受其数…

IndexedDB查询

Indexeddb 创建、增删改查_indexdb 删除表-CSDN博客本地数据库IndexedDB - 学员管理系统之条件筛选&#xff08;四&#xff09;_indexdb条件查询-CSDN博客 <div align"center"><input type"text" id"input_search"> <button id&q…

在Visual Studio 2022中将源文件扩展名改为 .c 后,没有显示 #define _CRT_SECURE_NO_WARNINGS 1?

一、问题 在Visual Studio 2022中将源文件扩展名改为 .c 后&#xff0c;没有显示 #define _CRT_SECURE_NO_WARNINGS 1&#xff1f; 二、解答 对于使用了不安全的C运行时库函数&#xff08;如strcpy、scanf等&#xff09;而触发的安全警告&#xff0c;编译器不会默认包含_CRT_S…

C#颜色拾取器

1&#xff0c;目的&#xff1a; 获取屏幕上任意位置像素的色值。 2&#xff0c;知识点: 热键的注册与注销。 /// <summary>/// 热键注册/// </summary>/// <param name"hWnd">要定义热键的窗口的句柄 </param>/// <param name"id…

【大厂AI课学习笔记】1.3 人工智能产业发展(1)

我国人工智能政策&#xff0c;分为5个阶段。从探索期&#xff0c;到后面的4个阶段。 MORE:&#xff08;以下为文心一言4.0的参考内容&#xff0c;和腾讯课程资料的分阶段&#xff0c;略有不同&#xff09; 我国的人工智能政策发展可以大致分为以下几个阶段&#xff0c;每个阶段…