为什么需要数据段、代码段和BBS段?这么多的段是干什么用的。

程序的指令等是只读的,可以把它们归为一类,以便运行时可以把它们放到ROM等设备上去,当然也可以是内存上,只不过是这段内存时只读的。
程序的全局变量等是可读可写的,可以把他们归为一类,放在内存里面去。
那么我们来假设一个事,若是我们编写了一个程序中,包含大量的初始值为0的全局变量,那么编译出来的.bin文件是不是会很大,很显然根据日常经验来看,编译的文件中并没有存放这些数据,那么这是怎么回事呢。
将它们这些数据归为一类,只记录它们的内存起始地址和结束地址,在程序运行前将这块内存清零。清零BSS段(BSS段通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域)。
栈的作用?
从汇编跃进到C前,调用C函数需要有栈(栈是一种操纵内存的数据结构类型,至于你说为什么不是其他的数据结构,那你得去想想操作系统方面的知识了),至于栈的好处,我参开这篇文章上:
http://www.cnblogs.com/xmphoenix/archive/2012/04/28/2475399.html
一.栈的整体作用
(1)保存现场/上下文

(2)传递参数:汇编代码调用c函数时,需传递参数

(3)保存临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

这些需要保存在内存的值呢,大家就约定用CPU的sp指针指明位置,这块内存也就是栈。

SDRAM那么大,程序被复制到了哪里?

对于2440来说,Nand启动时,CPU会自动将Nand上前4K的程序复制到片内SRAM上运行,而这段代码中就有一个功能就是将Nand上的程序复制到SDRAM上去运行的,而复制到哪里呢,以前的Uboot是采用的把链接地址写死,然后复制代码到SDRAM上的地址也是定死了,但是,现在的Uboot采用的是重定位的方法,那么也就是说,现在的程序猿把代码复制到哪里都可以,主要也是为了适配如今大量不同的板子。

之所以要复制到链接地址上去使用,是因为程序上的全局变量、函数等都是以链接地址来访问的,在程序运行之前,这些地址都应该有确定的值。

总结下bootloader的第一阶段大概框架:

a. 必要的硬件初始化:关看门狗,时钟,SDRAM

b. 重定位,将程序从Flash上读到内存相应的链接地址上

c. 清除BSS段

d. 调用C函数

前4K所使用的是位置无关码所编写的程序,也就是说为什么没有在链接地址上,还能正确运行着程序,没有上面说的限制

何为位置无关, ① 不去访问全局变量/静态变量; ② 跳转指令均是采用相对跳转,例如b, bl。