最近的一段时间又温习了一下嵌入式开发的根本东西和程序的一些根本结构,逐步脱离了机械学习的进程,在学习的进程中了解到自己需求了解的东西还许多。记住我在大学期间学习DSP,其时的使命是完结2048点数据的FFT改换,记住其时程序(C言语)完结很快,可是在后期总是不能呈现正确的作用,最终发现原来是CMD(装备)文件存在问题,经过教师的解说以及自己的学习了解到了程序的根本结构,也便是所谓的代码段,数据段等,以及详细的存储器办理问题。这些都是链接器的根本功能。从此也就知道了程序的一些特色。
1、方针文件的构成
二进制文件是由一系列的段构成的,当然也会存在一些符号,存储器分配等等,从链接文本其实就能大约知道程序的组成,各个方针文件的同一段结合起来就完成了可执行程序的链接,当然详细的链接方法和准则都是东西设计好的。比方链接的次序按着输入的次序等。
记住在移植u-boot到TQ2440的进程中,从前就修改正链接文本,也便是u-boot.lds文件,其时由于自己增加了一个关于nand flash 操作的函数,为了确保增加的函数不会在链接的进程中将发动代码之前而导致芯片发动存在问题,我特意修改了程序的链接次序,确保链接文档正确链接。
1. [root@Gong-Computer u-boot-2010.06]# vi arch/arm/cpu/arm920t/u-boot.lds
2. . = ALIGN(4);
3. .text :
4. {
5. arch/arm/cpu/arm920t/start.o (.text)
6. board/samsung/smdk2440/lowlevel_init.o (.text)
7. board/samsung/smdk2440/nand_read.o (.text)
8. *(.text)
9. }
关于二进制文件中的根本内容首要是包含几个段的。当然还需求其他的一些条件,在链接的进程中,如同还需求一些C言语运转的环境,首要是用来控制程序的发动和封闭。这些都是crt*(C RunTime)方针文件完成的。这些方针文件在咱们程序设计中不经常看到,假如剖析过u-boot的编译进程就会发现,这些方针文件的确存在。
链接文本使得文件的链接愈加的便利和有用。因而了解方针的最根本阶段是十分的必要的。
在其间需求留意的几点:
1、静态变量不管是部分仍是大局的都是在数据段中,而不想部分变量在仓库中,当栈弹出今后,其间的内容也就开释了,静态变量不会改动,可是关于部分静态变量则只能被界说该变量的函数拜访,不能被其他的函数拜访。
2、大局变量、静态变量假如被初始化为0,或许没有被初始化,则该变量被分配到.bss(未初始化部分),只有当大局变量和静态变量初始化为非零数值时才会分配到.data段中。
3、大局变量和静态变量假如没有被初始化一般都会默以为0,这也是为什么将这两个数初始化为0,依然处在.bss段的原因。因而需求留意大局变量和静态变量在没有初始化时的值,可是关于部分变量则没有这个特色,假如没有初始化则会呈现一个随机值。
以上的定论能够经过代码进行手动测验。
2、Linux中程序结构
在Linux中每一个进程都存在一个4G的虚拟空间,其间前3G空间是用户空间,然后1G空间则是内核空间,这4G的空间在各个进程之间都是彼此独立的。可是这些内存空间的区域分配的确相同的,并且各个区域的开始地址也是固定好的,Linux程序的结构如下:
由于各个段的开始地址都是固定的,这样就便于虚拟地址到物理地址的映射,便利了程序的加载。特别是同享库的完成。
3、仓库和堆
其实我对这两个概念在刚开始的时分也存在很大的误解,不明白其间的联系,总是把仓库了解成堆和栈,实质上仓库便是指栈,搞清楚这个,两者的差异就简单了解啦。仓库其实也能够以为是一种数据结构,典型的先进后出特色。
一般来说仓库都是反向增加的,也便是所谓的从高地址到低地址的增加方法,可是也有其他的增加方法,比方ARM有4种不同的增加方式,所以仓库的增加方向只能根据CPU而言,不同的CPU其仓库或许存在必定的不同。仓库首要用来完成函数的调用。
堆一般来说都是在bass段的上面,首要用来完成动态内存的分配和开释,在C言语中首要是经过malloc/free函数完成,在C++中则首要选用new/delete完成。可是关于这一块的内存通常会不断的分配和开释以及满意根本的对齐方式,这样就导致了内存碎片的发生,减小了拜访的速率。一起由于在这段区域运转零空间请求,以及开释后指针依然有用等问题,所以在开释结束今后通常将指针指向NULL。