GNU-ARM程序开发(一)----GNU开发环境和工具

article/2025/11/9 8:32:39

什么是GNU
GNU计划,又称革奴计划。是由Richard Stallman在1983年9月27日公开发起的。目标是创建一套完全免费、自由的操作系统,基本原则是源代码共享及思想共享。
所有在GNU计划下开发的软件均为GNU软件。
为保证GNU软件可以自由地“使用、复制、修改和发布”,所有GNU软件都在一份在禁止其他人添加任何限制的情况下授权所有权利给任何人的协议条款,GNU通用公共许可证(GNU General Public License,GPL)。
GPL条款下发布的一些主要的GNU项目软件有:
GCC:GNU编译器集,包括GNU C编译器。
G++:C++编译器,是GCC的一部分。
GDB:源代码级的调试器。
GNU make:UNIX make命令的免费版本。
GNU Emacs:文本编辑器及环境。
bash:命令解释器(shell)。

 本地程序开发(PC--X86)
GNU工具:
/usr/bin/{gcc、g++、as、ld等}
库文件:
/usr/lib/lib*.so
头文件:
/usr/include
交叉开发(ARM)
GNU工具:
/usr/local/arm/arm920t/bin/
arm-angstrom-linux-gnueabi-gcc
arm-angstrom-linux-gnueabi-as
库文件:
/usr/local/arm/arm920t/arm-angstrom-linux-gnueabi/lib/
头文件:
/usr/local/arm/arm920t/arm-angstrom-linux-gnueabi/include

 

Linux环境下开发C/C++程序的工具主要是GNU工具,GNU工具集包括:
编译工具
:把一个源程序编译为一个可执行程序
调试工具:能对执行程序进行源码或汇编级调试
软件工程工具:用于协助多人开发或大型软件项目的管理,如 make、CVS、Subvision
其他工具:用于把多个目标文件链接成可执行文件的链接器,或者用作格式转换的工具。

cpp:
进行预处理,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析;
cc1:
进行编译,生成.s为后缀的汇编文件;
as:
进行汇编,汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件;
ld:
进行链接,所有的目标文件被安排在可执行程序中的恰当的位置。同时,该程序所调用到的库函数也从各自所在的档案库中链接到合适的地方。

GNU二进制工具

addr2line:把程序地址转换为文件名和行号
ar:建立、修改、提取归档文件
as:主要用来编译GNU C编译器gcc输出的汇编文件,产生的目标文件由链接器ld连接。
c++filt:连接器使用它来过滤C++ 和Java 符号,防止重载函数冲突。
ld:GNU链接器。
nm:列出目标文件中的符号。
objcopy:文件格式转换。
objdump:显示一个或者更多目标文件的信息,主要用来反编译。
ranlib:产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
readelf:显示elf格式可执行文件的信息。
size:列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
strings:打印某个文件的可打印字符串。默认情况下,只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件它打印整个文件的可打印字符,这个程序对于了解非文本文件的内容很有帮助。
strip:丢弃目标文件中的全部或者特定符号,减小文件体积。

写一测试程序:

 

#include<stdio.h>
int main()
{
return 0;
}
readelf
readelf可以显示elf格式可执行文件的信息。ELF格式是UNIX系统实验室作为应用程序二进制接口开发的。ELF格式是Unix/Linux平台上应用最广泛的二进制工业标准之一。
查看可执行文件“test”的头信息

[root@localhost testGNU]# readelf -h test
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:                           Intel 80386
Version:                           0x1
Entry point address:               0x8048280
Start of program headers:          52 (bytes into file)
Start of section headers:          1836 (bytes into file)
Flags:                             0x0
Size of this header:               52 (bytes)
Size of program headers:           32 (bytes)
Number of program headers:         7
Size of section headers:           40 (bytes)
Number of section headers:         28
Section header string table index: 25
size
小以及总体的大小。
size有两种输出格式,一种为“sysv”,另一种为“berkeley”,默认为berkeley的格式。第一种格式可以用“-A”或者“--format=sysv”指定,第二种格式用“-B”或“--format=berkeley”指定:
$ size test –A
$ size test -B
[root@localhost testGNU]# size test
text    data     bss     dec     hex filename
803     248       8    1059     423 test
[root@localhost testGNU]# size test -A
test  :
section          size        addr
.interp            19   134512916
.note.ABI-tag      32   134512936
.gnu.hash          32   134512968
.dynsym            64   134513000
.dynstr            69   134513064
.gnu.version        8   134513134
.gnu.version_r     32   134513144
.rel.dyn            8   134513176
.rel.plt           16   134513184
.init              23   134513200
.plt               48   134513224
.text             408   134513280
.fini              28   134513688
.rodata            12   134513716
.eh_frame           4   134513728
.ctors              8   134517828
.dtors              8   134517836
.jcr                4   134517844
.dynamic          200   134517848
.got                4   134518048
.got.plt           20   134518052
.data               4   134518072
.bss                8   134518076
.comment          276           0
Total            1335


nm
nm可以列出目标文件中的符号。用法虽然简单,但是功能很强大。
nm可以列出的符号:

R 只读符号
N 调试符号
D 已经初始化的变量的符号
T Text段的符号。子程序都是这种符号
U 未定义的符号。例如文件中引用了不存在的函数
S 未初始化的符号,比如定义了一个全局变量int a;则a的符号就是这种类型
libsupc++ 提供支持C++语言的库函数
R 只读符号

nmdemo.c实例

#include<stdio.h>
static int i_a;
int i_b;
const c_c=3;
char *buf="Demo for study nm tools!";
extern int i_e;
void function_1()
{
printf("Any string you want!\n");
}
int num_add(int a1,int a2)
{
return a1+a2;
}

nm使用
$ gcc –g –O –c nmdemo.c
$ nm –A nmdemo.o

[root@localhost testGNU]# gcc -g -O -c nmdemo.c 
[root@localhost testGNU]# ls
nmdemo.c  nmdemo.c~  nmdemo.o  test  test.c  test.i  test.o  test.s
[root@localhost testGNU]# nm -A nmdemo.o
nmdemo.o:00000000 D buf
nmdemo.o:00000000 R c_c
nmdemo.o:0000000b T function_1
nmdemo.o:00000004 C i_b
nmdemo.o:00000000 T num_add
nmdemo.o:         U puts


nm使用
$ nm –Aa nmdemo.o

[root@localhost testGNU]# nm -Aa nmdemo.o
nmdemo.o:00000000 b .bss
nmdemo.o:00000000 n .comment
nmdemo.o:00000000 d .data
nmdemo.o:00000000 N .debug_abbrev
nmdemo.o:00000000 N .debug_aranges
nmdemo.o:00000000 N .debug_frame
nmdemo.o:00000000 N .debug_info
nmdemo.o:00000000 N .debug_line
nmdemo.o:00000000 N .debug_loc
nmdemo.o:00000000 N .debug_pubnames
nmdemo.o:00000000 N .debug_str
nmdemo.o:00000000 n .note.GNU-stack
nmdemo.o:00000000 r .rodata
nmdemo.o:00000000 r .rodata.str1.1
nmdemo.o:00000000 t .text
nmdemo.o:00000000 D buf
nmdemo.o:00000000 R c_c
nmdemo.o:0000000b T function_1
nmdemo.o:00000004 C i_b
nmdemo.o:00000000 a nmdemo.c
nmdemo.o:00000000 T num_add
nmdemo.o:         U puts


nm使用
“a”选项会把调试符号也列出来。默认状态下调试符号不会被列出。
“l”选项会把源代码中对应的行号也列出
$ nm –Aal nmdemo.o

[root@localhost testGNU]# nm -Aal nmdemo.o
nmdemo.o:00000000 b .bss        /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 n .comment    /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 d .data
nmdemo.o:00000000 N .debug_abbrev       /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_aranges      /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_frame        /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_info /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_line /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_loc  /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_pubnames     /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 N .debug_str  /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 n .note.GNU-stack     /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 r .rodata
nmdemo.o:00000000 r .rodata.str1.1
nmdemo.o:00000000 t .text       /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:00000000 D buf /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:5
nmdemo.o:00000000 R c_c /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:4
nmdemo.o:0000000b T function_1  /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:8
nmdemo.o:00000004 C i_b
nmdemo.o:00000000 a nmdemo.c
nmdemo.o:00000000 T num_add     /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:12
nmdemo.o:         U puts        /mnt/hgfs/share/C++_C/testGNU/nmdemo.c:9


strip
strip用来丢弃目标文件中的全部或者特定符号,减小文件体积。对于嵌入式系统,这个命令必不可少。

[root@localhost testGNU]# vim nmdemo.c
[root@localhost testGNU]# ls -lh test
-rwxrwxrwx 1 root root 4.6K 12-08 13:11 test


strip -s  去除所有符号

[root@localhost testGNU]# strip -s test
[root@localhost testGNU]# ls -lh test
-rwxrwxrwx 1 root root 2.8K 12-08 13:11 test

 

strip使用
经过strip处理后的文件已经不包含符号了,可以使用nm加以验证。

[root@localhost testGNU]# nm nmdemo.o
00000000 D buf
00000000 R c_c
0000000b T function_1
00000004 C i_b
00000000 T num_add
U puts
[root@localhost testGNU]# strip nmdemo.o
[root@localhost testGNU]# nm nmdemo.o
nm: nmdemo.o: no symbols


strings
strings用来打印某个文件的可打印字符串。

[root@localhost testGNU]# strings nmdemo.o
Any string you want!
Demo for study nm tools!

如果想显示文件名称,使用“f”选项。

[root@localhost testGNU]# strings -f nmdemo.o
nmdemo.o: Any string you want!
nmdemo.o: Demo for study nm tools!


objdump
objdump可以显示一个或者更多目标文件的信息,主要用来反编译。
-d  反汇编
-i BFD文件支持信息

[root@localhost testGNU]# objdump -d nmdemo.o
nmdemo.o:     file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0:   55                      push   %ebp
1:   89 e5                   mov    %esp,%ebp
3:   8b 45 0c                mov    0xc(%ebp),%eax
6:   03 45 08                add    0x8(%ebp),%eax
9:   5d                      pop    %ebp
a:   c3                      ret    
b:   55                      push   %ebp
c:   89 e5                   mov    %esp,%ebp
e:   83 ec 08                sub    $0x8,%esp
11:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
18:   e8 fc ff ff ff          call   0x19
1d:   c9                      leave  
1e:   c3                      ret 

“-R”选项显示动态重定向的入口。


objcopy
objcopy可以进行目标文件格式转换。
转成bin文件

[root@localhost testGNU]# objcopy -O binary test test.bin
[root@localhost testGNU]# ls
nmdemo.c  nmdemo.c~  nmdemo.o  test  test.bin  test.c  test.i  test.o  test.s

 

addr2line
addr2line能够把程序地址转换为文件名和行号,前提是这个可执行文件包括调试符号。
如果可执行文件中没有包括调试符号,shell将返回??:0。
最常用的选项是“-e”用来指定文件名和地址。

08048384 T main
U printf@@GLIBC_2.0
[root@localhost testGNU]# addr2line 08048384 -e  test
/mnt/hgfs/share/C++_C/testGNU/test.c:3

http://chatgpt.dhexx.cn/article/4jV8rvOh.shtml

相关文章

【ARM编程】ARM介绍

01.ARM目录 ARM目录 01.ARM目录02.前言03.计算机体系结构分类04.ARM公司05.ARM应用领域06.ARM基本架构07.ARM各体系架构版本7.1 ARM版本Ⅰ&#xff1a;V1版架构7.2 ARM版本 Ⅱ&#xff1a;V2版架构7.3 ARM版本 Ⅲ&#xff1a;V3版架构7.4 ARM版本 Ⅳ&#xff1a; V4版架构7.5 A…

ARM开发环境

目录 前言一、Ubuntu及linux系统基础知识1.shell命令的运用2.Tool的安装&#xff1a;3.deb是软件包&#xff0c;dpkg是手动安装工具&#xff0c;apt是自动安装工具&#xff0c;4.Linux文件系统5.gcc编译器 二、开发环境搭建1.vim编辑器2.与windows文件互传3.VSCode使用4.NFS网络…

ARM开发环境下载地址大全

MDK5.3.8a(Keil5)最新下载地址 超链接如下&#xff0c;点击直达&#xff1a; Keil MDK (Keil Licensing) (MDK000) (arm.com) 实际网址如下所示&#xff1a; https://developer.arm.com/downloads/view/MDK000 Arm Compiler for Embedded下载地址 超链接如下&#xff0c;点击直…

什么是ARM?

原文 一、ARM是什么&#xff1f; ARM既可以认为是一个公司的名字 &#xff0c;也可以认为是对一类处理器的统称 &#xff0c;还可以认为是一种技术的名字 。 ARM公司是专门从事基于RISC技术芯片设计开发 的公司&#xff0c;作为知识产权供应商&#xff0c;本身不直接从事芯片…

X86ARM架构

这里写目录标题 cpu架构arm架构ARM架构图 x86架构arm架构和x86架构的区别CISC Vs RISCWindows如何查看系统是ARM64还是X64架构 32位与64位的区别巨头公司国产cpu公司 cpu架构 CPU 的全称是"中央处理单元"&#xff0c;它是计算机的核心&#xff0c;计算都由它来完成。…

ARM开发——常见仿真器

搞嵌入式开发和ARM开发搞了半辈子了&#xff0c;调试程序是不可避免的。接触了那么多的调试规范、调试工具、调试手段&#xff0c;彼此之间的关系却也不是特别清楚&#xff0c;今天就来捋一捋&#xff1a; JTAG协议 JTAG&#xff08;Joint Test Action Group&#xff0c;联合…

ARM开发---基础认识

本文适合初次接触ARM的的初学者&#xff0c;主要以基础知识点和科普为主. 文章目录 前言一、ARM是什么&#xff1f;二、ARM的特点三、ARM的使用场景1.计算机组成2.架构3.指令集4.指令解析5.工作模式 四、寄存器总结 前言 提起ARM&#xff0c;没有接触过的朋友可能第一反应是英…

【嵌入式】Linux开发工具arm-linux-gcc安装及使用

arm-linux-gcc 知识架构及层次 — 程序编译及调试嵌入式交叉编译器安装配置主机目标板开发模式ARM微处理器/Linux系统下编译器编译器下载及安装 arm-linux-gcc工具使用-E-S-c -o-include file-I dir-I-iprefix prefix 和 -iwithprefix dir-l库名 -L目录gcc 优化 课后作业 Linux…

ARM 编译器 Arm Compiler for Embedded 6 相关工具链简介

目录 1, Introduction to Arm Compiler 6 1.1 armclang 1.2 armasm 1.3 armlink 1.4 armar 1.5 fromelf 1.6 Arm C libraries 1.7 Arm C libraries 1,8 Application development &#xff0c;ARM程序开发流程 2&#xff0c;ARM 编译器 5和ARM 编译器 6的兼容性 3&…

ARM处理器开发详解

目录 第一章 嵌入式系统基础知识&#xff08;不考&#xff09;嵌入式系统特点交叉调试调试器 第二章 嵌入式 ARM 技术概论ARM的基本数据类型&#xff08;不考&#xff09;选择ARM芯片的一般原则Cortex-A9内核的八种工作模式流水线&#xff08;不考&#xff09;寄存器组织程序状…

ARM嵌入式常用开发工具介绍及插画开发流程(更新)

这里接着前边的开发环境的配置说&#xff0c;其实用于开发的话&#xff0c;基本的开发环境已经架构好了&#xff0c;不过由于嵌入式开发环境的特殊性(交叉编译)&#xff0c;我们还会用到一些其他的外围工具&#xff0c;这里做简要的说明。并重新介绍一下整个开发环境中&#xf…

ARM介绍

什么是ARM&#xff1f; ARM即可以是一家芯片设计厂商的名字&#xff0c;也可以代表一类微处理器的通称&#xff0c;还可以表示为一种技术的名称&#xff08;这个问题面试的时候可能问道&#xff09; 1、ARM是一个公司&#xff1a;Advanced RISC Machine Acorn RISC Machi…

《 Arm Compiler 5.06 》__ARM编译器官网下载、安装和使用说明(小白也能懂)

目录 一、前言 二、官方网站下载 三、编译器安装在 Keil 软件上 四、Keil选择编译器V5 “ V5.06 update 7(build 960) ” 五、测试 六、我的资源 (*&#xffe3;︶&#xffe3;)创作不易&#xff01;期待你们的 点赞、收藏和评论喔。 一、前言 Keil MDK-Arm5.37不再默认…

arm-linux开发板相关软件的使用

文章目录 1. 串口调试1.1 简介1.2 secureCRT使用步骤 2. 文件传输2.1 文件传输: tftp2.2 文件传输: NFS (相当于将主机作为一个u盘插入开发板) 3. 交叉编译3.1 下载3.2 配置 1. 串口调试 1.1 简介 一般而言&#xff0c;嵌入式开发板使用串口来监控后台。可以使用串口线连接开…

嵌入式:ARM相关开发工具概述

文章目录 JTAG仿真器J-LINK仿真调试器J-Link ARM主要特点 U-LINK仿真调试器ULINK2特点ULINK和JLINK的比较 ADS1.2集成开发环境使用ADS创建工程 JTAG仿真器 JTAG(Joint Test Action Group&#xff1b;联合测试行动小组)是一种国际标准测试协议&#xff08;IEEE 1149.1兼容&…

嵌入式:ARM常用开发编译软件介绍

文章目录 编译器介绍1、ADS1.22、ARM RealView Developer Suite (RVDS)3、IAR EWARM4、KEIL ARM-MDKARM5、WIN ARM-GCC ARM 编译器介绍 1、ADS1.2 ADS&#xff08;ARM Developer Suite&#xff09;&#xff0c;是在1993年由Metrowerks公司开发是ARM处理器下最主要的开发工具。…

北京邮电大学计算机考研资料汇总

北京邮电大学研招网 北京邮电大学计算机学院 北京邮电大学软件学院 北京邮电大学网络空间安全学院 北京邮电大学&#xff08;Beijing University of Posts and Telecommunications&#xff09;&#xff0c;简称北邮&#xff0c;是中华人民共和国教育部直属、工业和信息…

23届计算机保研经验帖(北邮)

21届计算机保研经验帖 本文非常适合保研非实力派选手&#xff0c;越早阅读离心仪学校就越近一步。有很多同学担心自己拿到推免资格却无学可上&#xff0c;这大可放心&#xff0c;我们学校很多同学都轻松得到西南985高校的offer&#xff0c;但如果想保到北上广的计算机强校的话…

2019年北理工计算机北航计算机中山大学计算机北邮网研院保研夏令营

目录 1.个人情况 2.夏令营入营情况 3.报名准备建议 3.1 准备一个txt 文本&#xff0c;上面有个人信息&#xff0c;方便填写每个大学的报名申请&#xff0c;包括以下信息&#xff1a; 3.2 电脑上新建一个文件夹和一个网页收藏夹 3.3 一些可能需要使用的工具和软件&#xf…

北邮考研复试机试准备过程(已上岸)

纯自用请勿转载&#xff0c;用来给自己最后复习和捋思路用的&#xff0c;主要参考牛客网王道机试指南&#xff0c;C、C混用。考研人太久不写代码了…什么都不记得了&#xff0c;从头开始过一遍吧。 黑色代码段是要记住的重点函数/方法。每天下午做几个小时&#xff0c;一共不到…