系统启动(一) 冰山之下

说bootloader之前,最好能温故而知新一下,想一想,我们之前玩的51单片机,stm32单片机,它们是怎么启动的。

无非是上电后,CPU开始取指令,总线按照寻址的命令,取出flash中的一条指令,然后译指,ALU执行运算,最后把结果写到CPU寄存器或者

ram中去。

 

但是考虑下面这样一段代码,我们可以挖出更多的问题:

 1 #include <stdio.h>
 2 
 3 int a[10] = {1,2,3,4,5,6,7,8,9,10};
 4 int main()
 5 {
 6      int i  = 0 ;
 7      for(i = 0; i < 10; i++) {
 8          a[i] = 0;
 9     }
10     return 0;
11 }

上述c文件,编译后,会生成.o目标文件,目标文件中会有很多段,比如text段,data段,bss段等,和平台的运行库链接后会生成hex可执行文件

我们烧录到板子的flash中的正是这些可执行文件。那么问题来了,全局变量a在data段(STM32中叫做RW段),但是在系统运行前,它是在rom里的,当代码运行到对a[i] 执行赋值操作时,a就在ram里面了,这中间发生了什么?谁把a[10] 从flash中搬到内存中了吗?

 

是的,CPU上电后,的确是从ROM中读取代码运行的,但是在运行我们的代码之前,CPU会运行一段特殊的代码,会把flash中RW段的数据从ROM中复制到RAM中,并在RAM中分配一段空间存放ZI段的内容,然后把ZI段的内容全部初始化为0,加载完毕后,正式开始执行主体程序。

 

这里面这段特殊的代码,不知你是否还有印象,就是那个startup_xxx.s文件。关于startup.s, 值得好好深入研究一番,但是不在本文的重点内容中。只是,这件事里面需要引起我们的思考,也就是我们的代码在编译链接的时候,其实所有的符号的地址已经确定了,比如我在程序里访问a[0]

绝对是,直接操作某个确切的地址的,那么也就是说,搬运的时候,应该是会根据具体的地址往sram中搬运的。至于是不是这样,后面专栏中会进一步探讨。

 

posted on 2022-01-05 00:10  疾速瓜牛  阅读(286)  评论(0编辑  收藏  举报

导航