心血来潮学习一下分散加载,把所有代码放到RAM执行。
得确保sysinit和_main在FLASH中,否则无法进行运行前代码的拷贝工作。(从FLASH将内容拷贝到RAM是在_main中完成的,由编译器自动生成的代码)
看一下.map文件,理解一下复制过程。
首先看一下FLASH里的内容:
可以看到我把.s和systeminit的内容放到了FLASH里,保证进入c的main之前完成前期准备工作。
在FLASH里有一个叫 Region$$Table 的section,这是一个表,用来描述怎样从FLASH中将RW(我设置的 RO XO 也在RAM运行)数据复制到RAM里。
进入 Region$$Table 指向的地址
可以看到前四个字节为需要复制的起始地址,也就是0x800027C
后边紧跟着需要复制到的目的地址 0x20000000,为RAM起始地址
紧随其后的是一个描述大小的number
0x4324看一下map里 0x20000000 + 0x4324的位置是什么
很明显这是一个 RO数据的结束位置,下面就开始复制RW数据了。
table的第四个数据也是一个地址,看一下map里 0x8000204是什么
很显然这是一个函数,从名字上来看就是编译器生成的用来复制FLASH数据的函数 ,这应该是第二次调用这个函数,用来将RW数据从FLASH复制到RAM。
table的第五个数据以后可以明显的看出规律了,四个数据一个循环。
从 0x080045A0 复制 0x90个数据到 0x20004324 ,一直复制到了0x200043B4,还是调用0x08000204处的 _xxx_copy 函数
很明显这又是一个分界,.DATA和.BSS的分界,也就是说刚才是把变量复制完了
table的第三行又开始了一次新的复制过程
从0x08004630复制 0x7D20个数据到 0x200043B4 调用另一个位于0x8000214的新函数,看下名字是_xxx_zeroinit 也就是把这部分的RAM清零。那么猜测0x08004630处应该是一个0x00000000,
看一下是不是
看来不是,这是bin文件的结尾了,后边没有代码了。 那应该就是简单的循环把目标区域清空了。
table的第三行又开始了一次新的复制过程,这次是把stack给清零了。
复制0x400个数据到0x2000FC00,调用_xxx_zeroinit