1. Linux内核启动流程
实际上操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表,页表的内容就是该进程的虚拟地址到物理地址的一个映射。
Linux内核的启动过程可以分为两部分:架构/开发板的相关引导过程,后续的通用启动过程
引导阶段通常使用汇编语言编写,它首先检查内核是否支持当前架构的处理器,然后检查是否支持当前开发板。通过检查后,就为调用下一阶段的start_kernel函数左准备,这主要分为两个步骤:
- 设置页表,使能MMU,
- 调用c函数start_kernel之前的常规工作,包括复制数据段,清除BSS段,调用start_kernel函数。
- 第二阶段的关键代码主要使用c语言编写,它进行内核初始化的全部工作,最后调用rest_init函数启动init过程,创建系统的第一个进程:init进程。在第二个阶段,仍有部分架构、开发板相关的代码,
2. Uboot启动流程
- 初始化硬件:设置CPU的工作模式为管理模式SVC,关闭看门狗,设置时钟,初始化SDRAM和Flash
- 如果uboot比较大,要把它重定位到SDRAM 重定位讲解
- 把内核从NandFlash中读到内核
- 设置传给内核的参数
- 跳转执行main函数
3.代码重定位
- 什么是代码重定位
重定位就是将代码的text,rodata段,data段从一个地址搬移到另一个地址,本来程序写好之后是在某个地址上开始运行的,经过代码重定位之后,可以在另一个地址运行,比如程序烧写在Nor Flash上,本来是在Nor Flash上的0地址开始运行的,通过代码重定位,把数据段或整个程序搬移到SDRAM的0x30000000地址运行,S3C2440的CPU可以直接给SDRAM发送命令、给Nor Flash发送命令、给4K的片上SDRAM发送命令,但是不能直接给Nand Flsh发送命令
- 为什么要进行代码重定位
- 程序烧在Nand Flash上的情况
(1)Nand Flash程序 的启动流程:将程序烧写在Nand FlASH时,CPU无法从Nand Flash中取出代码执行的,开机上电会自动把Nand Flash的前4K复制到CPU内部SRAM里面,然后CPU从内部SRAM的0地址执行代码,关看门狗,设置存储管理器,再将代码拷贝到SDRAM中,拷贝结束后在SDRAM中执行。
(2)问题:当我们的程序大于4K的时候,片内SRAM不够存放Nand Flash的程序了,片内SRAM只有4k
(3)解决程序大于4K方法:前4K的代码需要把整个程序读出来放到外部SDRAM
- 程序烧在Nor Flash上
(1) Nor Flash程序的启动流程:Nor Flash的基地址为0,片内SRAM地址为0x4000 0000;CPU读出Nor上第1个指令(前4字节),执行;CPU继续读出其它指令执行。
(2)存在问题:Nor Flash可以像内存直接读,但是不能直接写。当程序中含有需要写的全局变量或静态变量时,假如是在Nand Flash可以正常操作,如果是在Nor Flash,修改是无效。
(3)解决写无效的方法:我们把全局变量和静态变量这些数据段或者整个程序重定位放到外部SDRAM上,在SDRAM上修改全局变量和静态变量的值
如何进行代码重定位
一个程序里面一般有的段
(1)text:代码段,代码段其实就是函数编译后生成的东西。
(2)data:数据段
(3)rodata:只读数据段(const全局变量)
(4)bss段:又叫做ZI段,零初始化段,就是初始化为0的全局变量
- 为什么要清除bss段
这里的bss段指的是将bss段初始化为0,bss段不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0。如果把它们出现在程序下载文件中,会增加程序下载文件的大小,在实际运用中,通常只需要将bss段起始地址和结束地址保存起来,而不需要将程序下载文件中出现bss段(一堆0)将来真正运行程序的时候,再将bss段初始化为0即可,也就是清除bss段,如果不清除,那么全局变量的初始值就不是0了。
- 为什么要用绝对地址跳转到main函数执行
这里的绝对地址跳转用的指令为:ldr pc, = main,执行该命令后,程序跳转到SDRAM的main函数开始执行,如果使用相对指令(bl main),程序还是会在Nor Flash或内部SRAM中执行