首页
视频
资源
登录
原
Qemu 简单应用
460
人阅读
2024/7/5 11:57
总访问:
2972229
评论:
0
收藏:
0
手机
分类:
嵌入式
![](https://img.tnblog.net/arcimg/hb/b3f08146d754401abe266c095a266fcb.png) >#Qemu 简单应用 [TOC] Qemu简单示范 ------------ tn2>创建一个工作目录`armv8easy`。 ```bash mkdir armv8easy cd armv8easy/ code . ``` tn2>给vscode安装相关ARM支持的汇编高亮插件。 ![](https://img.tnblog.net/arcimg/hb/4195ab11429f47fa926e41f4a15f472a.png) tn2>创建`start.S`汇编文件,以及Makefile文件,`launch.json`。 ![](https://img.tnblog.net/arcimg/hb/26d45b2b3770404186c782f348749a13.png) ```bash .globl start _start: mov x0,#1 ldr w1,=0x778899 add x0,x0,x1 mrs x3,CurrentEl reset_end: b reset_end ``` ```bash CC = aarch64-linux-gnu-gcc # 定义变量 CC,指定使用 aarch64-linux-gnu-gcc 作为 C 编译器 LD = aarch64-linux-gnu-ld # 定义变量 LD,指定使用 aarch64-linux-gnu-ld 作为链接器 CFLAGS = -g -O0 -nostdlib -nodefaultlibs # 定义变量 CFLAGS,包含编译选项:-g 调试信息,-O0 无优化,-nostdlib 禁用标准库,-nodefaultlibs 禁用默认库 start: start.o # 创建名为 start 的目标,依赖于 start.o 文件 $(LD) -o $@ $^ # 使用 LD 变量指定的链接器,将所有依赖文件($^,这里是 start.o)链接为可执行文件 $@ %.o: %.S # 创建一个模式规则,用于生成 .o 文件(依赖于同名的 .S 汇编文件) $(CC) $(CFLAGS) -c $< -o $@ # 使用 CC 变量指定的编译器和 CFLAGS 变量中的选项编译 .S 文件,并输出为 .o 文件 .PHONY: clean # 声明一个伪目标 .PHONY,用来标记 clean 不是一个实际的文件名 clean: # 创建名为 clean 的目标 -rm start.o # 使用 -rm 命令删除 start.o 文件,忽略文件不存在的错误 -rm start # 使用 -rm 命令删除 start 可执行文件,忽略文件不存在的错误 ``` ```bash { "version": "0.2.0", "configurations": [ { "name": "(gdb) 启动", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/start", "args": [], "stopAtEntry": true, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", // 如果远程登入到linux 服务器上面,路径不用写 /user/bin/gdb-multiarch "miDebuggerPath": "gdb-multiarch", "miDebuggerServerAddress": "localhost:1234", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] } ``` tn2>使用`make`进行构建。 ![](https://img.tnblog.net/arcimg/hb/9347ef97718d44389d7666b018957ab7.png) tn2>发现缺少`gcc-aarch64-linux-gnu`,需要安装一下。 ```bash sudo apt-get update sudo apt-get install gcc-aarch64-linux-gnu ``` tn2>再次`make`成功了 ![](https://img.tnblog.net/arcimg/hb/99a97c4d423049a1a9e65a7794504008.png) tn2>接下来我们打开一个窗口运行这个命令,使用Qemu创建一个模拟器。 | 选项 | 含义 | |-------------------|----------------------------------------------------------------------| | `qemu-system-aarch64` | QEMU 模拟器命令行工具,用于模拟 ARM 64 位架构的系统。 | | `-machine virt` | 指定使用 `virt` 机器模型,用于模拟 ARM 虚拟平台。 | | `-cpu cortex-a57` | 指定使用 Cortex-A57 处理器核心。 | | `-nographic` | 禁用图形显示,所有输出发送到控制台终端。 | | `-kernel start` | 加载名为 `start` 的内核文件。 | | `-S` | 启动时暂停,等待调试器连接。 | | `-s` | 开启 GDB 服务器,监听默认端口 1234,等待 GDB 连接。 | ```bash qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -kernel start -S -s ``` tn2>按F5启动调试报错,找了一下`/usr/bin/gdb-multiarch`没有找到,所以需要安装。 ![](https://img.tnblog.net/arcimg/hb/de1deb2f22024b8d85dc2cf726abec61.png) ```bash sudo apt install gdb-multiarch -y ``` ![](https://img.tnblog.net/arcimg/hb/caf9790a96654420aaa930f296f82975.png) tn2>再次运行。 ![](https://img.tnblog.net/arcimg/hb/0505a25cba3143639f38f78ba7ca1c20.png) ![](https://img.tnblog.net/arcimg/hb/83c1846ab8f4425cab277ab74c58b709.png) tn2>我们可以看到它是兼容x32位的,并且能将当前CPU异常级(Current Exception Level,CurrentEL)的值加载到寄存器 x3 中。 而`gdb`是达不到这一层的,会直接报错。 ```bash .globl start _start: ldr x0,=0x11223344556677 ldr w1,=0x11223344556677 add x0,x0,x1 mrs x3,CurrentEl reset_end: b reset_end ``` ![](https://img.tnblog.net/arcimg/hb/0ebb54920c7047559c079dbf65955562.png) tn>通过修改代码我们会发现`w1`只能存储后8位,而`x0`是可以存储16位的。 tn2>通过`bl`跳转到的sum方法中,lr(x30)将会保存下一条`mrs x3,CurrentEl`的地址,当在`ret`执行后会将lr的地址赋值给`pc`。 ```bash .globl start _start: ldr x0,=0x11223344556677 ldr w1,=0x11223344556677 add x0,x0,x1 bl sum mrs x3,CurrentEl reset_end: b reset_end sum: mov x0,#0x33 ret ``` ![](https://img.tnblog.net/arcimg/hb/9902f103c9d94aee894d583330668b9c.png) ![](https://img.tnblog.net/arcimg/hb/d036c1cc2e404afcb7b6fd10f2e63f64.png) ![](https://img.tnblog.net/arcimg/hb/ad55ade610764aa68b7ca53ed7195a84.png) tn2>`xzr`特殊寄存器,永远返回`0`。 ```bash sum: mov x0,#0x33 mov x0,xzr ret ``` ![](https://img.tnblog.net/arcimg/hb/7b1a1ea87d19479ba233d90667ccbbfe.png) ![](https://img.tnblog.net/arcimg/hb/c4449f9a298d430b8c36440b190e0639.png) tn2>获取DAIF寄存器包含4个标志位,分别用于控制不同类型的中断。 获取SPSel寄存器用于选择当前栈指针。 ![](https://img.tnblog.net/arcimg/hb/638a6f9e439f4d489711b4b7a7f5eb3b.png) tn2>DAIF值为`0x3c0`,D, A, I, F四个屏蔽位都为0,这意味着调试异常、同步错误中断、普通中断和快速中断都没有被屏蔽。当前SPSel为1,通常表示在内核模式下。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}
尘叶心繁
这一世以无限游戏为使命!
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
.net后台框架
177篇
linux
18篇
linux中cve
1篇
windows中cve
0篇
资源分享
10篇
Win32
3篇
前端
28篇
传说中的c
5篇
Xamarin
9篇
docker
15篇
容器编排
101篇
grpc
4篇
Go
15篇
yaml模板
1篇
理论
2篇
更多
Sqlserver
4篇
云产品
39篇
git
3篇
Unity
1篇
考证
2篇
RabbitMq
23篇
Harbor
1篇
Ansible
8篇
Jenkins
17篇
Vue
1篇
Ids4
18篇
istio
1篇
架构
2篇
网络
7篇
windbg
4篇
AI
19篇
threejs
2篇
人物
1篇
嵌入式
20篇
python
20篇
HuggingFace
8篇
pytorch
10篇
opencv
6篇
Halcon
5篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术