3嵌入式操作系统3.ppt
《3嵌入式操作系统3.ppt》由会员分享,可在线阅读,更多相关《3嵌入式操作系统3.ppt(123页珍藏版)》请在三一文库上搜索。
1、嵌入式操作系统 GNU开发工具链介绍,李春杰,主要内容,. 1 前言 交叉开发 . 2 GNU Tools 简介 GCC GNU binutils Gdb调试器 GNU make软件工程工具 GNU ld链接器 . 3 GNU tools 交叉开发环境的安装 . 4 小结和作业,1 前言 交叉开发 . 2 GNU Tools 简介 GCC GNU binutils Gdb调试器 GNU make软件工程工具 GNU ld链接器 . 3 GNU tools 交叉开发环境的安装 . 4 小结和作业,本地开发 vs 交叉平台开发,本地开发: 一般软件的开发属于本地开发,也就是说开发软件的系统与运行软
2、件的系统是相同的。 交叉平台开发: 本课程所涉及到的嵌入式系统开发属于交叉平台开发,也就是说开发软件的系统与运行软件的系统不同。,交叉开发平台,主机: 开发软件的平台,称为主机,往往是通用电脑; 目标机: 运行软件的平台,称为目标机,在这里是嵌入式系统。,嵌入式交叉开发工具,掌握嵌入式开发工具的使用是进行嵌入式开发的前提条件之一 与主流开发工具类似,嵌入式交叉开发工具也包括 编译器,即能够把一个源程序编译生成一个可执行程序的软件 调试工具,即能够对执行程序进行源码或汇编级调试的软件 软件工程工具,用于协助多人开发或大型软件项目的管理的软件,GNU tools,GNU tools和其他一些优秀的
3、开源软件可以完全覆盖上述类型的软件开发工具。为了更好的开发嵌入式系统,需要熟悉如下一些软件 GCCGNU 编译器集 Binutils辅助 GCC 的主要软件 Gdb调试器 make软件工程工具 di, patch补丁工具 CVS版本控制系统,一、GCC,很多人认为GCC只是一个C编译器, 其实GCC = GNU Compiler Collection 目前,GCC可以支持多种高级语言,如 C、C+ ADA Object C JAVA Fortran PASCAL,GCC下的工具,cpp 预处理器 GNU C编译器在编译前自动使用cpp对用户程序进行预处理 gcc 符合ISO等标准的C编译器 g
4、+ 基本符合ISO标准的C+编译器 gcj GCC的java前端 gnat GCC的GNU ADA 95前端,GNU Toolsgcc,gcc是一个强大的工具集合,它包含了预处理器、编译器、汇编器、链接器等组件。它会在需要的时候调用其他组件。 输入文件的类型和传递给gcc的参数决定了gcc调用具体的哪些组件。 对于开发者,它提供的足够多的参数,可以让开发者全面控制代码的生成,这对嵌入式系统级的软件开发非常重要 作业1:总结Gcc指令的主要参数有哪些?主要用法?,gcc使用举例(1) 源程序,gcc使用举例(2) 编译和运行,gcc的工作过程(1),如果使用-v选项,则可以看到许多被隐藏的信息,
5、gcc的编译过程,一般情况下,c程序的编译过程为 1、预处理 2、编译成汇编代码 3、汇编成目标代码 4、链接,1、预处理,预处理:使用-E参数 输出文件的后缀为“.cpp” gcc E o gcctest.cpp gcctest.c 使用wc命令比较预处理后的文件与源文件,可以看到两个文件的差异,行数 单词数 字节数,预处理是指在系统对源程序进行编译之前,对程序中某些特殊的命令行的处理,预处理程序将根据源代码中的预处理命令修改程序。使用预处理功能可以改善程序的设计环境,提高程序的通用性、可读性、可修改性、可调试性、可移植性和方便性,易于模块化。 预处理命令有三类:宏定义、文件包含和条件编译。
6、 下面是常见的预处理命令: #include,文件包含,用于把指定的文件内容包含到所在文件的当前位置处。 #define 和 #undef,分别用于定义和取消定义条件编译符号。 #if、#elif、#else 和 #endif,用于按条件跳过源代码中的节。,预处理文件和源文件的区别: 从预处理的角度讲: 对于一个包含了多个头文件的源文件,只要用头文件的内容替换掉源文件中的对应的include语句,就可以得到预处理后的源文件。这个最终生成的源文件的编译结果就是最终的编译结果。,2、编译成汇编代码,预处理文件汇编代码 1)使用-x参数说明根据指定的步骤进行工作, 2)cpp-output指明从预处
7、理得到的文件开始编译 3)使用-S说明生成汇编代码后停止工作 gcc x cpp-output S o gcctest.s gcctest.cpp 也可以直接编译到汇编代码 gcc S gcctest.c,预处理文件汇编代码,直接编译到汇编代码,s,s,s,3、编译成目标代码,汇编代码目标代码 gcc x assembler c gcctest.s -x指定步骤 assembler汇编标志 直接编译成目标代码 gcc c gcctest.c 使用汇编器生成目标代码 as o gcctest.o gcctest.s,汇编代码目标代码,直接编译成目标代码,使用汇编器,4、编译成执行代码,目标代码执
8、行代码 gcc o gcctest gcctest.o 直接生成执行代码 gcc o gcctest gcctest.c,目标代码执行代码,直接生成执行代码,gcc的高级选项,-Wall:打开所有的警告信息,根据警告信息检查源程序,Main函数的返回值为int,在函数的末尾应当返回一个值,修改源程序,优化编译,优化编译选项有: -O0 缺省情况,不优化 -O1 -O2 -O3 等等,gcc的优化编译举例(1) 考虑如下的源代码,不同的优化 编译选项,gcc的优化编译举例(2) 使用time命令统计程序的运行,二、GNU binutils,binutils是一组二进制工具程序集,是辅助GCC的主
9、要软件,它主要包括 addr2line 把程序地址转换为文件名和行号。在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。 ar 建立、修改、提取归档文件。归档文件是包含多个被包含文件内容的一个大文件,其结构保证了引用文件索引,可以恢复原始文件内容。,as 是GNU汇编器,主要用来编译GNU C编译器gcc输出的汇编文件,他将汇编代码转换成二进制代码,并存放到一个object文件中,该目标文件将由连接器ld连接 C+filt解码C+符号名,连接器使用它来过滤 C+ 和 Java 符号,防止重载函数冲突。 gprof 显示程序调用段的
10、各种数据。 ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并链接符号引用,最终形成一个可执行文件。通常,建立一个新编译程序的最后一步就是调用ld。,nm 列出目标文件中的符号。 objcopy把一种目标文件中的内容复制到另一种类型的目标文件中,Objcopy可以使用不同于源目标文件的格式来写目的目标文件(也即是说可以将一 种格式的目标文件转换成另一种格式的目标文件)。 objdump 显示一个或者更多目标文件的信息。使用选项来控制其显示的信息。它所显示的信息通常只有编写编译工具的人才感兴趣。 ranlib 产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成
11、员所定义的可重分配目标文件。 readelf 显示elf格式可执行文件的信息。,size 列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。 strip 丢弃目标文件中的全部或者特定符号,binutils开发工具使用举例,ar nm Objcopy readelf,1、ar,ar用于建立、修改、提取归档文件(archive),一个归档文件,是包含多个被包含文件的单个文件(也可以认为归档文件是一个库文件)。 被包含的原始文件的内容、权限、时间戳、所有者等属性都保存在归档文件中,并且在提取之后可以还原文件的相关属性。,使用ar建立库文件
12、(1),源程序add.c和minus.c,Step1:生成 add.o 和 minus.o 两个目标文件 step2:生成库文件,并复制到 /usr/lib/ 目录,Ar的rv参数的说明: r:将多个文件组成一个文件v:输出信息,在代码中使用Add和Minus函数,在链接时,使用“-l”选项来指明库文件,2、nm,nm的主要功能是列出目标文件中的符号,这样程序员就可以定位和分析执行程序和目标文件中的符号信息和它的属性,nm 显示的符号类型 A:符号的值是绝对值,并且不会被将来的链接所改变 B:符号位于未初始化数据部分(BSS 段) C:符号是公共的。公共符号是未初始化的数据。在链接时, 多个公
13、共符号可能以相同的名字出现。如果符号在其他地方被定义,则该文件中的这个符号会被当作引用来处理 D:符号位于已初始化的数据部分 T:符号位于代码部分 U:符号未被定义 ?:符号类型未知,或者目标文件格式特殊,nm使用举例,nm使用举例,命令nm test.o的输出说明了test.o定义了main函数,但没有定义Add、Minus和Printf函数符号。 命令nm add.o的输出说明了add.o定义了Add函数符号。 命令nm minus.o的输出说明了minus.o定义了Minus函数符号。 test.o中没有定义但使用了printf函数符号,printf函数实际上定义在libc.a库中。,3
14、 objcopy,可以将一种格式的目标文件内容进行转换,并输出为另一种格式的目标文件。 它使用GNU BFD(binary format description)库读/写目标文件,通过这个BFD库,objcopy能以一种不同于源目标文件的格式生成新的目标文件 $objcopy h命令可以看到objcopy的一般帮助信息 在makefile里面用-O binary 选项来生成原始的二进制文件,即通常说的image文件,Objcopy使用举例,使用file命令查看文件类型,生成srec格式的目标文件,4、readelf,readelf: 显示一个或多个ELF格式的目标文件信息,Readelf使用举
15、例,5、GNU Toolsld,ld,The GNU Linker Linux上常用的链接器 ld软件的作用是把各种目标文件(.o文件)和库文件链接在一起,并定位数据和函数地址,最终生成可执行程序 ld-o hello /lib/crt0.o hello.o lc 该指令把 /lib/crt0.o hello.o 和库文件libc.a链接起来生成新的执行程序hello,gcc可以间接的调用ld,使用gcc的-Wl参数可以传递参数给ld gcc-W1,-startgroup foo.o bar.o-W1,-endgroup 等同于执行如下ld命令: Ld - startgroup foo.o b
16、ar.o -endgroup 使用命令:ld -help可以列出ld常用的一些选项,ld使用举例(1),源程序,编译hello.c到hello.o 命令:gcc -c hello.c,链接 命令:ld dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o hello.o lc o hello 运行 ./hello,目标文件,ld通过BFD库可以读取和操作coff、elf、a.out等各种执行文件格式的目标文件 BFD(Binary File Descriptor) 目标文件(objec
17、t file) 由多个节(section)组成,常见的节有: text节保存了可执行代码, data节保存了有初值的全局标量, bss节保存了无初值的全局变量。,链接描述文件( Linker script ),可以使用链接描述文件控制ld的链接过程。 链接描述文件,command file 又称为链接脚本,Linker script 用来控制ld的链接过程 描述各输入文件的各节如何映射到输出文件的各节 控制输出文件中各个节或者符号的内存布局 使用的语言为: The ld command language,链接命令语言,ld命令的-T commandfile选项指定了链接描述文件名 如果不指定链
18、接描述文件,ld就会使用一个默认的描述文件来产生执行文件 链接描述文件主要由一系列的命令组成,每个命令可以是一个带参数的关键字或赋值语句。,链接描述文件的命令,链接描述文件的命令主要包括如下几类: 设置入口点命令 处理文件的命令 处理文件格式的命令 其他,常用的命令,设置入口点 格式:ENTRY(symbol) 设置symbol的值为执行程序的入口点。 ld有多种方法设置执行程序的入口点,确定程序入口点的顺序如下: ld命令的-e选项指定的值 Entry(symbol)指定的值 .text节的起始地址 入口点为0,常用的命令,INCULDE filename 包含其他filename的链接描述
19、文件 INPUT(file,file,) 指定多个输入文件名 OUTPUT_FORMAT(bfdname) 指定输出文件的格式 OUTPUT_ARCH ( bfdname ) 指定目标机器体系结构,例如: OUTPUT_ARCH(arm),常用的命令,MEMORY: 这个命令在用于嵌入式系统的链接描述文件中经常出现,它描述了各个内存块的起始地址和大小。格式如下: MEMORY name (attr):ORIGIN = origin,LENGTH = len Name可以理解为描述的内存块名字,len表示这个内存的大小,attr表示内存块的属性,它的值可以是: R:只读 W:可读/写 X:可执行
20、 A:可分配 等,例如:,Memory举例,SECTIONS命令,SECTIONS 告诉ld如何把输入文件的各个节映射到输出文件的各个节中。 在一个链接描述文件中只能有一个SECTIONS命令 在SECTIONS命令中可以使用的命令有三种: 定义入口点 赋值 定义输出节,一个简单例子,下面是一个简单的例子: 例中,输出文件包含text,data,bss三个节,而输入文件也只包含这3个节: SECTIONS .=0x01000000; /表示可执行文件的起始加载地址0x01000000 .text:*(.text);/表示把所有输入文件的.text收集起来形成新的输出文件.text .=0x08
21、000000;/表示.data的起始地址0x08000000 .data:*(.data); .bss:*(.bss); / .bss的起始地址为0x08000000加上所有输入文件 / .data的大小,最后看个简单的输入section相关例子: SECTIONS outputa 0x10000 : all.o foo.o (.input1) outputb : foo.o (.input2) foo1.o (.input1) outputc : *(.input1) *(.input2) 本例中,将all.o文件的所有section和foo.o文件的所有(一个文件内可以有多个同名secti
22、on).input1 section依次放入输出outputa section内,该section的VMA是0x10000;将foo.o文件的所有.input2 section和foo1.o文件的所有.input1 section依次放入输出outputb section内,该section的VMA是当前定位器符号的修调值(对齐后);将其他文件(非all.o、foo.o、foo1.o)文件的. input1 section和.input2 section放入输出outputc section内.,运用实例,lds 运用实例展示 共5个文件nand.lds Makefile head.s ini
23、t.c main.c 链接描述文件nand.lds 1) /nand.lds SECTIONS firtst 0x00000000 : head.o init.o second 0x30000000 : AT(4096) main.o ,运用实例,/Makefile nand : head.s main.c init.c arm-linux-gcc -c -o head.o head.s arm-linux-gcc -c -o init.o init.c arm-linux-gcc -c -o main.o main.c arm-linux-ld -Tnand.lds head.o init.
24、o main.o -o nand_tmp.o arm-linux-objcopy -O binary -S nand_tmp.o nand arm-linux-objdump -D -b binary -m arm nand ttt.s clean: rm -f head.o init.o main.o tmp.o nand_tmp.o nand ) 执行make语句即可生成所需要的可执行文件 objdump D进行反汇编,一个例子u-boot.lds for 2410,= /u-boot.lds for 2410 OUTPUT_FORMAT(“elf32-littlearm”, “elf32
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 操作系统
链接地址:https://www.31doc.com/p-3409500.html