需要用到的工具:
编译工具:arm-linux-gcc
链接工具:arm-linux-ld
格式转换工具:arm-linux-objcopy
反汇编器:arm-linux-objdump
文件信息查看:arm-linux-readelf
下载工具:dnw
调试工具:arm-linux-gdb
JLink驱动:JLinkGDBServer
1. 将arm-linux-gcc的bin目录添加至环境变量,使用命令如下
vi ~/.bashrc
在.bashrc文件末尾加上
export PATH=$PATH:/home/lu/arm_bin/4.3.2/bin,后面路径需意个人境况而定,等号两边不要有空格
添加后,输入在命令窗口输入arm-linux-gcc会出现如下错误:
[lu@localhost arm]$ arm-linux-gcc -v
/home/lu/arm_bin/4.3.2/bin/arm-linux-gcc: /home/lu/arm_bin/4.3.2/bin/arm-none-linux-gnueabi-gcc: /lib/ld-linux.so.2: bad ELF interpreter: 没有那个文件或目录
/home/lu/arm_bin/4.3.2/bin/arm-linux-gcc:行3: /home/lu/arm_bin/4.3.2/bin/arm-none-linux-gnueabi-gcc: 成功
这是因为在在64位系统中运行32位程序需要安装32位的库,使用如下命令安装
yum install glibc.i686
以hello.c为例,使用arm-linux-gcc,如下
[lu@localhost arm]$ arm-linux-gcc hello.c -o hello
[lu@localhost arm]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.14, not stripped
可以发现,此时编译出的文件适用平台为ARM若是使用gcc则编译出的可执行文件适用平台为X86_64,如下所示
[lu@localhost arm]$ gcc hello.c -o hello2
[lu@localhost arm]$ file hello2
hello2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ec21632861f93013791b58571a92f669486bc445, not stripped
其用法为
arm-linux-ld -T*.lds(链接脚本文件) -o *.elf *.o *.o(所需要链接的文件)
链接后的文件为.elf格式的,这并不能在ARM上直接运行,能在ARN上运行的是二进制文件,格式为.bin
此时,还需另一工具arm-linux-objcopy来完成转换,使ELF文件变为bin文件,其用法如下
arm-linux-objcopy -O binary *.elf *.bin
-O binary意味输出二进制文件
至此,能在ARM上运行的可执行的文件就制作好了
3.arm-linux-objdump,反汇编器,即根据编译好的 代码来商城汇编代码,其用法如下
arm-linux-objdump -D -S *.elf >dump,其默认是将生成的代码输入到屏幕,效果如下
#include<stdio.h>
int main()
{
8380: e92d4800 push {fp, lr}
8384: e28db004 add fp, sp, #4 ; 0x4
8388: e24dd008 sub sp, sp, #8 ; 0x8
printf("hello world");
838c: e59f000c ldr r0, [pc, #12] ; 83a0 <main+0x20>
8390: ebffffca bl 82c0 <_init+0x48>
}
8394: e24bd004 sub sp, fp, #4 ; 0x4
8398: e8bd4800 pop {fp, lr}
839c: e12fff1e bx lr
83a0: 0000842c .word 0x0000842c
地址 机器码汇编代码
编译时加上调试信息(-g) 才会在反汇编时会有C的语句出现,如上printf("hello world");的出现,C与汇编对应起来更容易查找错误所在
[lu@localhost example]$ arm-linux-readelf -a led.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
由此信息可看到,此ELF文件使用平台为ARM,采用小端格式存储数据arm-linux-readelf还可以用来查看所需的库文件,如下所示
[lu@localhost example]$ arm-linux-readelf -d hello
Dynamic section at offset 0x450 contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x8278
0x0000000d (FINI) 0x841c
5.安装gdb server
安装arm-linux-gdb后,还需在环境变量中增加其路径,使用如下命令
gedit ~/.bashrc
然后在其文件倒数第二行增加如下内容:
export PATH=$PATH:/opt/arm-linux-gdb/bin注:因为在arm-linux-gcc中同样含有arm-linux-gdb工具,但此版本(6.8.50)并不能在arm中使用,需要在网上下载更高版本的,而把arm-linux-gdb放在倒数第二行,是因为,我们需要优先使用专门下载的arm-linux-gdb工具,.bashrc最后两行代码如下:
export PATH=$PATH:/opt/arm-linux-gdb/bin
export PATH=$PATH:/home/lu/arm_bin/4.3.2/bin
在调用arm-linux-gdb时,同样会因为操作系统为64位,软件为32位,出现错误,如下
arm-linux-gdb: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
使用如下命令安装所需32位库即可yum install xulrunner.i686
6.启动JLinkGDBServer时同样会出现错误,如下
./JLinkGDBServer: error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or director
在此链接中找到对应库即可
http://rpmfind.net/linux/rpm2html/search.php?query=libusb-0.1.so.4
同样,启动JLinkGDBServer时还可能会出现如下错误:
[root@localhost JLink_Linux_V434a]# ./JLinkGDBServer
SEGGER J-Link GDB Server V4.34a
JLinkARM.dll V4.34a (DLL compiled Aug 31 2011 11:51:40)
ERROR: Failed to bind address (Err = 98)
ERROR: Failed to open listener port 2331
Exiting...
这个错误,经过本人重新插拔仿真器,重启系统,重新下载驱动,查找占用2331端口的程序并kill它,都没有解决,最终,经过他人指点,修改45-jlink.rules搞定了,将45-jlink.rules内容全部换为以下代码即可( 先备份45-jlink.rules)SUBSYSTEM=="usb", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="010[1234]", MODE="664", GROUP="plugdev"
45-jlink.rules所在路径为
/etc/udev/rules.d/45-jlink.rules
最后,将JLinkGDBServer复制到 /usr/bin路径下,这样在任何路径下都能调用了