tnblog
首页
视频
资源
登录

Qemu 简单应用

1370人阅读 2024/7/5 11:57 总访问:3467455 评论:0 收藏:0 手机
分类: 嵌入式

Qemu 简单应用

Qemu简单示范


创建一个工作目录armv8easy

  1. mkdir armv8easy
  2. cd armv8easy/
  3. code .


给vscode安装相关ARM支持的汇编高亮插件。


创建start.S汇编文件,以及Makefile文件,launch.json

  1. .globl start
  2. _start:
  3. mov x0,#1
  4. ldr w1,=0x778899
  5. add x0,x0,x1
  6. mrs x3,CurrentEl
  7. reset_end:
  8. b reset_end
  1. CC = aarch64-linux-gnu-gcc # 定义变量 CC,指定使用 aarch64-linux-gnu-gcc 作为 C 编译器
  2. LD = aarch64-linux-gnu-ld # 定义变量 LD,指定使用 aarch64-linux-gnu-ld 作为链接器
  3. CFLAGS = -g -O0 -nostdlib -nodefaultlibs # 定义变量 CFLAGS,包含编译选项:-g 调试信息,-O0 无优化,-nostdlib 禁用标准库,-nodefaultlibs 禁用默认库
  4. start: start.o # 创建名为 start 的目标,依赖于 start.o 文件
  5. $(LD) -o $@ $^ # 使用 LD 变量指定的链接器,将所有依赖文件($^,这里是 start.o)链接为可执行文件 $@
  6. %.o: %.S # 创建一个模式规则,用于生成 .o 文件(依赖于同名的 .S 汇编文件)
  7. $(CC) $(CFLAGS) -c $< -o $@ # 使用 CC 变量指定的编译器和 CFLAGS 变量中的选项编译 .S 文件,并输出为 .o 文件
  8. .PHONY: clean # 声明一个伪目标 .PHONY,用来标记 clean 不是一个实际的文件名
  9. clean: # 创建名为 clean 的目标
  10. -rm start.o # 使用 -rm 命令删除 start.o 文件,忽略文件不存在的错误
  11. -rm start # 使用 -rm 命令删除 start 可执行文件,忽略文件不存在的错误
  1. {
  2. "version": "0.2.0",
  3. "configurations": [
  4. {
  5. "name": "(gdb) 启动",
  6. "type": "cppdbg",
  7. "request": "launch",
  8. "program": "${workspaceFolder}/start",
  9. "args": [],
  10. "stopAtEntry": true,
  11. "cwd": "${fileDirname}",
  12. "environment": [],
  13. "externalConsole": false,
  14. "MIMode": "gdb",
  15. // 如果远程登入到linux 服务器上面,路径不用写 /user/bin/gdb-multiarch
  16. "miDebuggerPath": "gdb-multiarch",
  17. "miDebuggerServerAddress": "localhost:1234",
  18. "setupCommands": [
  19. {
  20. "description": "为 gdb 启用整齐打印",
  21. "text": "-enable-pretty-printing",
  22. "ignoreFailures": true
  23. }
  24. ]
  25. }
  26. ]
  27. }


使用make进行构建。


发现缺少gcc-aarch64-linux-gnu,需要安装一下。

  1. sudo apt-get update
  2. sudo apt-get install gcc-aarch64-linux-gnu


再次make成功了


接下来我们打开一个窗口运行这个命令,使用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 连接。
  1. qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -kernel start -S -s


按F5启动调试报错,找了一下/usr/bin/gdb-multiarch没有找到,所以需要安装。

  1. sudo apt install gdb-multiarch -y


再次运行。


我们可以看到它是兼容x32位的,并且能将当前CPU异常级(Current Exception Level,CurrentEL)的值加载到寄存器 x3 中。
gdb是达不到这一层的,会直接报错。

  1. .globl start
  2. _start:
  3. ldr x0,=0x11223344556677
  4. ldr w1,=0x11223344556677
  5. add x0,x0,x1
  6. mrs x3,CurrentEl
  7. reset_end:
  8. b reset_end

通过修改代码我们会发现w1只能存储后8位,而x0是可以存储16位的。


通过bl跳转到的sum方法中,lr(x30)将会保存下一条mrs x3,CurrentEl的地址,当在ret执行后会将lr的地址赋值给pc

  1. .globl start
  2. _start:
  3. ldr x0,=0x11223344556677
  4. ldr w1,=0x11223344556677
  5. add x0,x0,x1
  6. bl sum
  7. mrs x3,CurrentEl
  8. reset_end:
  9. b reset_end
  10. sum:
  11. mov x0,#0x33
  12. ret


xzr特殊寄存器,永远返回0

  1. sum:
  2. mov x0,#0x33
  3. mov x0,xzr
  4. ret


获取DAIF寄存器包含4个标志位,分别用于控制不同类型的中断。
获取SPSel寄存器用于选择当前栈指针。


DAIF值为0x3c0,D, A, I, F四个屏蔽位都为0,这意味着调试异常、同步错误中断、普通中断和快速中断都没有被屏蔽。当前SPSel为1,通常表示在内核模式下。


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

Qemu 硬件模拟调试工具安装

Qemu 硬件模拟调试工具安装[TOC] Qemu与GDB区别QEMU 是一个强大的硬件仿真器,它不仅能仿真CPU,还能仿真各种硬件设备,例...

Xamarin.Forms UI 与 XAML的简单应用(一)

Xamarin.Forms UI 与 XAML的简单应用(一)[TOC] XAML简介XAML代表可扩展应用程序标记语言,你可以以声明式定义到你的用户界...

LangChain 简单应用(学习笔记)

LangChain 简单应用(学习笔记)[TOC] Langchain 简介大型语言模型(LLM)正在成为一种具有变革性的技术,使开发人员能够构...
这一世以无限游戏为使命!
排名
2
文章
634
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术