在進行ARM匯編語言學習的階段,如果沒有開發板和類似于JLink的JTAG硬件調試器時,那么通常會選擇在PC機上模擬運行ARM程序。方法大致有兩類,第一類方法就是安裝像MDK或IAR的集成開發環境,在該集成開發環境中進行代碼編寫,編譯,模擬運行并調試。該類方法的主要特點是簡單、易用,但是這些集成開發環境通常都是用各自定義的匯編偽代碼,需要進行熟悉;另一方面就是通常這類集成開發環境所支持的ARM核的版本不是很高,通常只能模擬運行ARM9及以下的ARM核,當然ARM公司的DS-5是一個不錯的選擇,但上述商業軟件都是要付費的。第二類方法就是使用開源的模擬器加調試工具,大特點就是免費,并且能支持較高版本的ARM核,這也是本文要介紹的方法。整個環境的搭建分為以下幾個步驟。
一、在Linux(如Ubuntu)中安裝交叉編譯工具鏈,這個步驟很簡單,在這里不再贅述。需要注意的是交叉編譯工具鏈中需要包含交叉的gdb調試工具,如果沒有可以移植一個。
二、安裝qemu模擬器,在Ubuntu-12.04的32位版本中可以使用下面的指令進行安裝。
$ sudo apt-get install qemu qemu-system qemu-utils
三、編寫測試代碼。一個簡單的測試代碼包含下面四個文件。
start.S # ARM匯編源文件
1 .text
2 .global _start
3 _start:
4 ldr r0, stacktop
5 mov sp, r0
6
7 stop:
8 nop
9 b stop
10
11 stacktop: .word stack + 4 * 4096
12
13 .data
14 stack: .space 4 * 4096
Makefile
1 all:
2 arm-linux-gcc -g -c -o start.o start.S
3 arm-linux-ld -Tmap.lds -o test.elf start.o
4
5 run: all
6 qemu-system-arm -machine vexpress-a9 -m 256M -serial stdio -kernel test.elf -S -s &
7 sleep 3
8 arm-linux-gdb test.elf
9 clean:
10 rm -rf *.o test.elf
在上面Makefile中啟動qemu模擬器的參數解釋如下:
$ qemu-system-arm -machine vexpress-a9 -m 256M -serial stdio -kernel test.elf -S –s
-machine vexpress-a9:指定開發板,該開發板是QEMU中支持的一款ARM公司的基于Cortex-A9的開發板
-m 256M:指定物理內存的大小
-serial stdio:指定串口為標準輸入輸出
-kernel test.elf:指定要運行的elf格式的可執行文件
-S:虛擬機啟動后立即暫停,等侍gdb連接
-s:在1234接受gdb調試連接
map.lds # 鏈接腳本
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2 OUTPUT_ARCH(arm)
3 ENTRY(_start)
4 SECTIONS
5 {
6 . = 0x0;
7 . = ALIGN(4);
8 .text :
9 {
10 start.o(.text)
11 *(.text)
12 }
13
14 . = ALIGN(4);
15 .rodata :
16 { *(.rodata) }
17
18 . = ALIGN(4);
19 .data :
20 { *(.data) }
21
22 . = ALIGN(4);
23 .bss :
24 { *(.bss) }
25 }
.gdbinit # gdb運行的初始化文件
1 target remote localhost:1234
四、編譯并運行測試代碼,執行下面的命令首先編譯,然后運行,在gdb的命令行模式下即可進行程序的調試。
$ make
arm-linux-gcc -g -c -o start.o start.S
arm-linux-ld -Tmap.lds -o test.elf start.o
$ make run
arm-linux-gcc -g -c -o start.o start.S
arm-linux-ld -Tmap.lds -o test.elf start.o
qemu-system-arm -machine vexpress-a9 -m 256M -serial stdio -kernel test.elf -S -s &
sleep 3
arm-linux-gdb test.elf
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-build_pc-linux-gnu --target=arm-cortex_a8-linux-gnueabi"...
[New Thread 1]
_start () at start.S:4
4 ldr r0, stacktop
Current language: auto; currently asm
(gdb)
五、常用的gdb調試命令。
l:列出源代碼
b 5:在5行設置斷點
i b:查看斷點信息
i r:查看寄存器值
set $r1 = 5:設置寄存器的值
p i:打印變量i的值
p/x i:以十六進制打印變量i的值
set var i = 3:設置變量i的值
x/16xb 0x0:以16進制形式查看0地址開始的16個字節的內存內容
bt:查看棧回溯信息
q:退出gdb
六、如果不太習慣命令行模式,則只需要使用一個gdb的圖形前端,比如ddd。可以使用下面的命令來安裝ddd。
$ sudo apt-get install ddd
七、安裝完成后,修改Makefile,將:
arm-none-linux-gnueabi-gdb test.elf
改為:
ddd --debugger arm-none-linux-gnueabi-gdb test.elf
即可。運行后效果如下:
QEMU還可以模擬運行U-Boot及Linux操作系統,使用類似的方法也可以進行調試。這大大降低了ARM學習的成本。另外,gdb的前端還有insight、eclipse等,這些都能提供更友好的圖形界面,從而使調試變得更加的簡便。