13.4.3 固化程序的加载运行
在某些时候,在存放程序的位置是不能运行程序的,例如程序存储在不能以XIP方式运行的Nand-Flash或者硬盘中,在这种情况下,必须将程序完全加载到RAM中才可以运行。固化程序加载运行的内存布局如图13-8所示:
|
(点击查看大图)图13-8 固化程序加载运行的内存布局 |
依照这种方式运行程序,需要将Flash中所有的内容全部复制到SDRAM或者SRAM中。在一般情况下,SDRAM或者SRAM的速度要快于Flash。这样做的另外一个好处是可以加快程序的运行速度。也就是说,即使Flash可以运行程序,将程序加载到RAM中运行也还有一定的优势。
这样做也产生了另外一个问题:代码段的载入地址和运行地址是不相同的,载入地址是在ROM(Flash)中,但是运行的地址是在RAM(SDRAM或者SRAM)中。对于这个问题,不同的系统在加载程序的时候有不同的解决方式。
C语言固化程序的加载运行过程如表13-6所示。
表13-6 C语言固化程序的加载运行时各段的情况
阶 段< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
涉及的部分 |
主要工作 |
代码的映像 |
代码段(Code)
只读数据段(RO Data)
读写数据段(RW Data) |
将程序放置在Flash中 |
初始化阶段 |
代码段(Code)
只读数据段(RO Data)
读写数据段(RW Data)
未初始化数据段(BSS) |
加载代码段和只读数据段到RAM中
复制读写数据段到RAM中
开辟未初始化段并且清零 |
运行阶段 |
代码段(Code)
只读数据段(RO Data)
读写数据段(RW Data)
未初始化数据段(BSS)
堆(heap)
栈(stack) |
运行RAM代码段中的程序,
动态地在RAM中开辟堆和栈 |
知识点:固化程序在加载运行时,需要复制代码段、只读数据段和读写数据段到RAM中,并另辟未初始化数据段,然后在RAM中运行程序(执行代码段)。
以这种加载方式的运行程序,另外一个重要的问题是:如何把代码移到RAM中。在有操作系统的情况下,代码的复制工作是由操作系统完成的,在没有操作系统的情况下,处理方式相对复杂,程序需要自我复制。显然,这种方式实现的前提是代码最初放置在可以以XIP方式执行的内存中。
程序本身复制的过程也是需要通过程序代码完成的,这时需要程序中的代码根据将包含自己的程序从ROM或者Flash中复制到RAM中。这是一个比较复杂的过程,程序的最前面部分是具有复制功能的代码。系统上电后,从ROM或者Flash起始地址运行,具有复制功能的代码将全部代码段和其他需要复制的部分复制到RAM中,然后跳转到RAM中重新运行程序。
固化程序加载复制和跳转过程如图13-9所示。
|
(点击查看大图)图13-9 固化程序加载复制和跳转过程 |
在代码的前面一小部分是初始化的内容,这部分内容中有一部分是复制程序,这段复制程序将代码段复制至RAM中,当这段初始化程序运行完成后,将跳转到RAM中的某个地址运行。