IAR生成文件链接过程解析

IAR生成文件设置

最近在搞contiki在IAR上的移植工作,好不容易移植完成了,但是生成的bin文件超出了MCU的Flash大小,MCUFlash为512K,生成的bin文件747K,开始一直认为是系统文件太多导致,后来觉得疑点颇多,所以就研究了一下IAR工程的编译和链接过程,具体过程如下:

1. 使用IAR compiler + assembler,对工程的每个".c/.cpp/.asm",分别生成一个.o文件,为可重定位ELF,叫做symobol。(内含的目标代码实际为机器码)

2. 使用IAR linker对上步产生的
"relocatable objectfiles(eg:可重定位ELF) .o"+“.icf”链接

3. 最终产生可执行ELF或者bin等。(IAR的调试系统C-SPY会根据ELF文件产生进行JLIINK在线调试,因为该文件中包含了每个obj在内存中的绝对地址。而且对于函数而言,虽然其内部的局部变量在运行时的地址不是固定的,但由于程序经过固定程式的编译已经是确定性事件,所以C-SPY根据该文件的信息是可以预测的)

--说明:根据上面的过程,利用.o可以生成“可以安装、动态管理的软件“

有两种设想(对于一个已经链接好了的最小单位镜像而言):

(1).
编译之后至链接之前:在镜像文件的头部设置标号,后面的bin引用地址的时候根据这个标号(基地址)偏移。这样,在linker链接的时候,就可以很方便的分配绝对地址了。

(2).在程序加载时,在镜像的头部设置一个变量,该变量可以动态改变[A1]。同样,其后的地址也以此偏移,这样就可以动态改变一个模块程序的存储器地址,实现动态加载、程序安装、管理了。

ELF文件格式参见《链接器与加载器》“Unix ELF格式”章节,或者wiki.

MAP文件

第一部分:

***PLACEMENT SUMMARY
位置总括

"A1": place at 0x08000000 { ro section .intvec};----启动文件

"P1": place in [from 0x08000000 to 0x0807ffff] { ro};-------代码与常量(.text、.rodata)

"P3": place in [from 0x20000010 to 0x2000ffff] {

rw, block CSTACK, block HEAP };-----RAM区。规划.data
、.bss、栈、堆

Section Kind Address Size Object

“A1”:

.intvec ro code

“P1”

.text ro code

.rodata const

"P3", part 1 of 3:

HEAP uninit

CSTACK uninit

.iar.dynexit uninit

"P3", part 2 of 3:

.data inited

"P3", part 3 of 3:

.bss zero

第二部分:

***INIT TABLE----------------------------------启动过程中,变量的初始化

Address Size

------- ----

Zero (__iar_zero_init3)------------------------------------.bss段

1destination range, total size 0x71c6:

0x2000362c 0x71c6

Copy/packbits (__iar_packbits_init3)--------------------------------.data段

1source range, total size 0x387 (84% of destination):

0x0801bcad 0x387

1destination range, total size 0x42e:

0x200031fc 0x42e

第三部分:

*** MODULE SUMMARY
模块概览

Module rocode ro data rw data

各个目标文件

(每个.c生成一个)只读代码常量变量

各个文件:

command line: [2]

动态库

dl7M_tl_if.a: [3]

rt7M_tl.a: [4]

shb_l.a: [5]

第四部分:

*** ENTRY LIST: 入口目录

Entry Address Size Type Object

实体名地址大小种类(Code
or Data) Gb or Lc
目标文件

(函数/变量)

一、从目标文件到下载

二、目标文件的segment分配

三、程序的启动

1 When an application is started, thesystem startup code first performs hardware

initialization, such as initialization ofthe stack pointer to point at the end of the

predefined stack area:

2 Then, memories that should bezero-initialized are cleared, in other words, filled with

zeros:

3 For initialized data, data declared, forexample, like int i = 6; the initializers are

copied from ROM to RAM:

Figure 6: Initializing variables

4 Finally, the main function is called:

四、

类似于linux程序的编译过程以及SVN windows软件,IAR软件由工作区(windows外壳)和分散的模块组成(比如编译器
IarBuild、链接器ILink)组成。实质上,不用IAR提供的集成开发环境,使用那些命令行工具开发也是可行的。

IAR编译后,产生这几个目录.

(1)、Exe--------------execute
可执行文件包

/.bin:纯镜像文件

/.sim:flash loader
在烧flash时会用到*.sim文件

/.out:C-SPY JLINK在线调试用到的ELF/DWARF文件

以下摘自help:

Build considerations

When you build an application that will be downloaded to flash, specialconsideration is needed. Two output files must be generated. The first is theusual ELF/DWARF file (out) that provides the debugger with debug and symbolinformation. The second file is a
simple-code file (filename extension sim)that will be opened and read by the flash loader when it downloads theapplication to flash memory.

The simple-code file must have the same path and name as the ELF/DWARF fileexcept for the filename extension. This file is automatically generated by thelinker.

(2).List

每个.c产生一个.lst及.s

/.lst list文件

/.s 汇编文件

(3)Obj

/.o 编译后生成的ELF可重定位目标文件

同时我做了相关的代码测试,首先新建一个工程,编译一个最简单的IO控制程序,生成的bin文件大小为512K,之后又做了一个相对contiki更复杂的工程文件,编译生成的bin文件大小仍为512K,打开二者生成的bin文件可以发现,文件固定大小为512K,但是有用的代码却不是这么多,剩余的部分被以所00填充,此时基本可以确定是工程本身设置的问题,所以从options开始对比排查,最终,确认了问题所在的原因,在link->Output栏,有一项output文件名称设置,先来看看IAR
help对其的描述:

Output

The Output options determine the generated linker output.

Output filename

Sets the name of the ILINK output file. By default, the linker will use the project name with the filename extension out. To override the default name, specify an alternative name of the output file.

Note:

If you change the filename extension for linker ouput and want to use the output converter ielftool to convert the output, make sure ielftool will recognize the new filename extension. To achieve this, choose Tools>Filename Extension, select your toolchain,
and click Edit. In the Filename Extension Overrides dialog box, select Output Converter and click Edit. In the Edit Filename Extensions dialog box, select Override and type the new filename extension and click OK. ielftool will now recognize the new filename
extension.

Include debug information in output

Makes the linker generate an ELF output file including DWARF for debug information.

基本意思是说这个输出设置决定了生成的链接文件,默认的格式是.out格式的,如果你要改成其他格式,你必须得保证该格式的文件能够被ielftool文件识别,也就是上述所说的ELF文件,对比之下发现工程文件将此处设置成了.bin格式,按照help说明更改回默认的.out文件之后,生成的bin文件大小终于变为512K,THX,小问题,但是解决之路也不容易,总结一下大家共同学习,有说的不对的欢迎拍砖O(∩_∩)O哈哈~

时间: 2024-10-17 21:00:47

IAR生成文件链接过程解析的相关文章

转:从编译链接过程解析static函数的用法

关于static函数的用法

Lab_1:练习一——理解通过make生成执行文件的过程

参考网站: https://www.cnblogs.com/chaunceyctx/p/7188779.html https://cloud.tencent.com/developer/article/1415004 https://www.runoob.com/linux/linux-comm-dd.html 练习1:理解通过make生成执行文件的过程.(要求在报告中写出对下述问题的回答) 列出本实验各练习中对应的OS原理的知识点,并说明本实验中的实现部分如何对应和体现了原理中的基本概念和关键

生成动态文件链接 | Django

# 生成动态文件链接 # 1.models.py image = models.ImageField(upload_to="文件/%Y/%m", verbose_name="缩略图") # 2.urls.py from django.views.static import serve ... # 配置上传文件的访问处理函数 url(r'^media/(?P<path>.*)', serve, {"document_root":MEDI

Hadoop源码分析(1):HDFS读写过程解析

一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public FSDataInputStream open(Path f, int bufferSize) throws IOException { return new DFSClient.DFSDataInputStream( dfs.open(getPathName(f), bufferSize, verif

C++编译与链接(1)-编译与链接过程

大家知道计算机使用的一系列的1和0 那个一个C++语言程序又是如何从一个个.h和.cpp文件变成包含1和0的可执行文件呢? 可以认为有以下的几个阶段 源程序->预处理->编译和优化->生成目标文件->链接->可执行文件 1.预处理 C++的预处理是指在C++程序源代码被编译之前,由预处理器对C++程序源代码进行的处理.这个过程并不对程序的源代码进行解析. 这里的预处理器(preprocessor)是指真正的编译开始之前由编译器调用的一个独立程序. 预处理器主要负责以下的几处

程序的编译链接过程

还是从HelloWorld开始说吧... #include <stdio.h> int main(int argc, char* argv[]) { printf("Hello World!\n"); return 0; } 从源文件Hello.cpp编译链接成Hello.exe,需要经历如下步骤: 可使用以下命令,直接从源文件生成可执行文件 linux: gcc -lstdc++ Hello.cpp -o Hello.out // 要带上lstdc参数,否则会报undef

Hadoop学习总结之二:HDFS读写过程解析

一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public FSDataInputStream open(Path f, int bufferSize) throws IOException { return new DFSClient.DFSDataInputStream( dfs.open(getPathName(f), bufferSize, verif

链接过程

note:这里还要补充的可能很多,包含可重定位目标文件的内容等. 符号和符号表 在ld等链接器的上下文中,有三种不同的符号.每一个可重定位目标模块m都有一个符号表,它包含m所定义的和引用的符号的信息. 由m所定义的并且能够被其他模块所引用的全局符号.就是非静态的c函数和被定义为不带c static属性的全局变量. 在其他模块定义并被模块m引用的全局符号.对应于定义在其他模块中的c函数和变量,external. 只在模块m定义和引用的本地符号.有的就是对应于带static属性的c函数和全局变量.这

[CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口

1 平台 1.1 硬件 Table 1. 硬件(lscpu) Architecture: i686(Intel 80386) Byte Order: Little Endian 1.2 操作系统 Table 2. 操作系统类型 操作系统(cat /proc/version) 位数(uname -a) Linux version 3.2.0-4-686-pae i686(32bit) 1.3 编译器 Table 3. 编译器信息 编译器(gcc -v) gcc (Debian 4.7.2-5) 4