uboot、kernel启动过程分析

00、uboot的宏观启动

        第1种:bootROM读取SPL到片内RAM,SPL初始化DDR,SPL把uboot程序copy到DDR,uboot启动进行必要外设初始化、自我拷贝、重定位等。

uboot、kernel启动过程分析_第1张图片

        第2种:bootROM直接读取uboot的头部信息(IVT、DCD)将DDR初始化完成,bootROM拷贝uboot程序到DDR,uboot开始执行。

uboot、kernel启动过程分析_第2张图片

        uboot的启动设备有很多,由bootPin开关(类似于STM32的boot0和boot1引脚)决定bootROM从哪种设备启动(上电开始从哪种存储设备读取信息去执行)。

一、uboot的启动

以imx6ull为例: 

  1. 设置CPSR寄存器,进入SVC模式,关闭中断irq、fiq;
  2. 设置SCTLR、VBAR寄存器,进行中断向量表重定位,向VBAR写入中断向量表的基地址0x87800000;
  3. 关闭MMU,关闭D-cache,cpu类型检查,进入__main开始板级初始化;
  4. 初始化内部定时器(类似于Cortex-M系列内核的滴答定时器);
  5. uboot拷贝自己到DDR高地址0x9FF47000处(产生地址偏移:0x9FF47000 - 0x87800000=0x18747000),让出空间给准备要加载的内核;
  6. uboot进行重定位,采用位置无关码(pc的相对偏移)访问Label,并且修改Label的内容:原Label内容+偏移0x18747000,这样就可以通过与pc的相对偏移访问到Label,取出Label的内容,也即取出真正要访问的函数或全局变量的地址(Label的内容=真正要访问的函数或全局变量的地址,可以通过反汇编去验证)。
  7. 再次重定位中断向量表重定位,向VBAR写入NEW中断向量表的基地址0x9FF47000;
  8. 初始化其他外设;
  9. uboot进入命令行模式等待或者直接尝试启动内核(bootz指令启动内核:主要传递内核镜像和设备树地址,如:bootz 80800000 - 83000000,内核地址0x80800000 ,设备树地址0x83000000);

uboot、kernel启动过程分析_第3张图片

二、kernel的启动

        内核启动前的要求:MMU off、D-cache off、I-cache = don’t care、如果支持设备树内核需要知道设备树的首地址;

        uboot要传递给内核的核心参数:bootargs(控制台参数、根文件系统位置等)、bootcmd(读取外部存储器的内核、设备树文件加载到DDR指定位置并启动);

        从arch/arm/kernel/vmlinux.lds下ENTRY(stext)内核入口,stext在arch/arm/kernel/head.S下:

uboot、kernel启动过程分析_第4张图片

1)处理器继续处于SVC,关闭所有中断,“内核详细的启动工作...”

2)内核启动函数:start_kernel -> “一系列详细过程...”-> reset_init :

     内部使用rcu锁调度器(区别读写锁,rcu读不会被写阻塞)

        a. pid=1:init进程

                  init进程进行其他初始化工作:

                          -注册控制台设备“ /dev/console”,作为标准输入,同时复制此文件描述符,

                           同时作为标准输出、标准错误;

                          -根据bootargs参数console(console=ttymxc0,115200)设置/dev/console对

                           应的实际设备;

                          -根据bootargs参数root(root=/dev/mmcblk1p2)挂载根文件系统,也可以通

                            过nfsroot挂载网络文件系统;

                          -根据bootargs参数init(init=/linuxrc),在根文件系统下查找init用户态进

                            程/linuxrc,找不到,内核就会启动失败!

        b. pid=2:负责内核进程调度和管理的进程;

        c. pid=0:主进程演变为idle进程,相当于空闲任务;

---------------------------------------------------------------------------------------------

你可能感兴趣的:(嵌入式,linux,操作系统)