zoukankan      html  css  js  c++  java
  • 系统启动知识 说道说道(一) 冰山之下

    说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中搬运的。至于是不是这样,后面专栏中会进一步探讨。

  • 相关阅读:
    android activity状态保存
    android的5个进程等级
    android什么时候会产生ANR
    android压力测试monkey简单使用
    CodeIgniter学习笔记五:分页,文件上传,session,验证码
    CodeIgniter学习笔记四:CI中的URL相关函数,路由,伪静态,去掉index.php
    Scrapy使用示例
    CodeIgniter学习笔记三:扩展CI的控制器、模型
    Queries for Number of Palindromes(区间dp)
    Dungeon Master(三维bfs)
  • 原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15401771.html
Copyright © 2011-2022 走看看