qemu进行ARM CPU仿真及程序gdb调试

本文主要介绍关于ARM汇编程序在ubuntu虚拟机中进行仿真及程序调试的相关介绍:

所需要的工具:

①装有ubuntu(linux)的虚拟机

②安装了qemu仿真器(一款主要仿真ARM CPU的软件)

③安装了交叉编译工具链(本人安装的是arm-none-linux-gnueabi-系列的4.6.4版本交叉编译工具链)

下面以mrs和msr ARM汇编指令的一个小程序来进行演示(暂时叫做CPU的状态切换吧)

第一步:安装qemu仿真器

设置网络,保证能够连通百度;
1、sudo apt-get update
2、sudo apt-get install qemu qemu-system qemu-utils
3、qemu-system-arm  --h
     该条语句为测试是否安装成功,可不进行执行

第二步:安装交叉编译工具链

1、解压gcc-4.6.4.tar.xz

tar   -xvf    gcc-4.6.4.tar.xz

2、扩展该交叉编译工具链的路径

①为什么要使用交叉编译工具链?

因为我们要编译在ARM芯片上跑的程序,而我们使用x86平台下系统自带的gcc编译的话,就是x86平台下的编译程序,不同平台最终编译出来的程序的机器码不一样,所以必须要使用交叉编译工具链。

②为什么要扩展交叉编译工具链的路径?

其实这个包解压后,在这个包的bin目录下有很多进行编译链接的工具,但是因为这些工具没有包含到系统自动检测的路径中,所以我们只能在当前的bin目录下使用这些工具,在别的目录下就必须使用路径+该工具的形式才能进行程序的编译,这样非常不方便,所以需要将这些工具的检索路径添加到系统的搜索路径中,也就是拓展PATH环境变量的值。

③具体步骤

a.进入到~目录下,打开.bashrc

b.在打开文件的末尾拓展环境变量值

注意自己交叉编译工具链的路径,这里因为我自己安装了两个版本的交叉编译工具链,所以对PATH环境变量进行了两次值的拓展;拓展之后要将该shell脚本执行一遍,之后环境变量才会导入PATH中,成功的标志是执行命令echo   $PATH之后会在PATH环境变量的自动检索路径中看到我们添加的路径。

第三步:交叉编译工具编译ARM汇编程序

测试的汇编代码如下:

.global   _start
_start:
	mrs  r0, cpsr
	bic  r0, #0x1f
	orr  r0, #0x12
	msr  cpsr, r0
	nop
	b  end

.end

Makefile编译脚本如下:

mrs.elf: mrs.o
	arm-linux-ld -Ttext 0x0  -o mrs.elf   $^
%.o : %.S
	arm-linux-gcc  -o $@ $<  -g  -c
clean:
		rm *.o *.elf    -f
该编译脚本其本质可拆分为下面两条指令:

arm-linux-gcc test.S -o mrs.o -c -g         //注意:-g参数是为了后面进行gdb调试使用

arm-linux-ld -Ttext 0x00000000  test.o -o    mrs.elf

第四步:qemu仿真调试

1、编译成功之后生成.elf的可执行文件,运行qemu仿真器

qemu-system-arm -machine vexpress-a9 -m 256M -serial stdio -kernel mrs.elf -S -s

注:因为我自己为了以后重复敲这行代码,将该命令写在一个脚本中的,所以会出现bash相关显示,直接敲命令的时候没有这些显示,只会弹出一个qemu的黑框。

2、执行交叉编译工具链中的gdb调试工具

①再开一个终端执行下面命令

arm-none-linux-gnueabi-gdb  mrs.elf

输入  target  remote  localhost:1234  命令来连接qemu

注:这个时候就相当于qemu是一个远程的ARM开发板,然后我们gdb通过网络连接着这个远程开发板进行程序调试实验。其中localhost为主机ip,因为我是在本机实验所以是localhost,端口号是1234

3、gdb调试相关指令

l   表示查看当前程序,将其打印到终端

b   表示设置断点(注:因为汇编程序运行非常快,所以需要有一个nop指令在.end前,否则会出现断点设置不成功)

c   表示程序继续执行,一直运行到断点处

s  表示进行单步运行

x /字节数        内存起始地址                 用于查看一片内存中的数据

p   $寄存器名     用于查看寄存器中的值

q   退出gdb调试

因为自己做的是一个ARM状态切换的验证程序,所以进行的是,读CPSR的值,然后改CPSR的值,最后回写CPSR的值,CPU自动切换状态,只要验证切换前后cpsr寄存器中CPRS的值的后五位不同其他位相同即成功。

可以看到切换前后cpsr后五位的值确实变化了,证明状态切换成功。

猜你喜欢

转载自blog.csdn.net/ass_dsb/article/details/78744614