
Qemu 简单应用
Qemu简单示范
创建一个工作目录armv8easy
。
mkdir armv8easy
cd armv8easy/
code .
给vscode安装相关ARM支持的汇编高亮插件。
创建start.S
汇编文件,以及Makefile文件,launch.json
。
.globl start
_start:
mov x0,#1
ldr w1,=0x778899
add x0,x0,x1
mrs x3,CurrentEl
reset_end:
b reset_end
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 可执行文件,忽略文件不存在的错误
{
"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
}
]
}
]
}
使用make
进行构建。
发现缺少gcc-aarch64-linux-gnu
,需要安装一下。
sudo apt-get update
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 连接。 |
qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -kernel start -S -s
按F5启动调试报错,找了一下/usr/bin/gdb-multiarch
没有找到,所以需要安装。
sudo apt install gdb-multiarch -y
再次运行。
我们可以看到它是兼容x32位的,并且能将当前CPU异常级(Current Exception Level,CurrentEL)的值加载到寄存器 x3 中。
而gdb
是达不到这一层的,会直接报错。
.globl start
_start:
ldr x0,=0x11223344556677
ldr w1,=0x11223344556677
add x0,x0,x1
mrs x3,CurrentEl
reset_end:
b reset_end
通过修改代码我们会发现w1
只能存储后8位,而x0
是可以存储16位的。
通过bl
跳转到的sum方法中,lr(x30)将会保存下一条mrs x3,CurrentEl
的地址,当在ret
执行后会将lr的地址赋值给pc
。
.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
xzr
特殊寄存器,永远返回0
。
sum:
mov x0,#0x33
mov x0,xzr
ret
获取DAIF寄存器包含4个标志位,分别用于控制不同类型的中断。
获取SPSel寄存器用于选择当前栈指针。
DAIF值为0x3c0
,D, A, I, F四个屏蔽位都为0,这意味着调试异常、同步错误中断、普通中断和快速中断都没有被屏蔽。当前SPSel为1,通常表示在内核模式下。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
评价
排名
2
文章
634
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 :
好是好,这个对效率影响大不大哇,效率高不高
一个bug让程序员走上法庭 索赔金额达400亿日元
剑轩 : 有点可怕
ASP.NET Core 服务注册生命周期
剑轩 :
http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256


欢迎加群交流技术