全志平台linux启动流程分析

一、BROM阶段

机器上电之后会执行固化在BROM里面的一段引导程序,这个程序会依次遍历所有支持的启动介质,直到找到第一个支持的。目前支持的启动介质是sd/mmc卡、nand和spinor。当程序初始化启动介质成功后,就从固定位置读入Bootloader的Boot0到SRAM,然后跳到SRAM执行。

下面展示了BROM的执行流程

二、Bootloader阶段

Bootloader是全志平台上从小系统一直沿用下来的内核加载器,在这里的主要职责是加载U-Boot到DRAM。

Bootloader分为两个部分,分别是Boot0和Boot1。

       Boot0:初始化DRAM,加载Boot1到DRAM;

       Boot1:调频,加载U-Boot到DRAM;

为什么Bootloader要划分成Boot0和Boot1两个部分?因为在Bootloader阶段,使用的SRAM大小是32KB,除去C运行环境需要的栈空间,可用的空间在24KB左右,这点不足以载入整个Bootloader。因此,需要将Bootloader划分成两个部分,尽可能将繁重的任务放在Boot1执行,这个情况类似于Linux系统中断执行环境的上半部和下半部。

1. boot0执行过程

2. boot1的执行过程

Boot1会进行一次系统调频,将CPU的频率调到用户在sys_config1.fex target段配置的boot_clock。

       如何在Boot1让机器进入升级模式?

(1)按住power键,再按任意键3下;

(2)接上串口启动,进入Boot1后在键盘输入2;

       如何替换Bootloader分区的内容?

接上串口启动,进入Boot1后在键盘输入1,USB会挂载Bootloader分区到PC上,卷标是“Volume”,替换掉相关的文件之后重启机器即可生效。Boot1会检测低电关机,以及插入火牛开机的情况进入关机程序。后者需要在sys_config1.fex里配置。

三、u-boot阶段

概括地说,U-Boot引导内核分为两个阶段,第一阶段负责重定位U-Boot到最高地址,第二阶段才是真正的引导内核。

1. 第一阶段

在第一阶段会关闭I/D cache和MMU,因此,整个U-Boot是直接运行在物理地址上。

2. 第二阶段

U-Boot第二阶段有一个完整、宽松的C环境,不再受制于栈空间,各个平台可以在这个阶段完成一些复杂的操作,以求达到定制的目的。

a. board init

执行平台相关的初始化,这些比较复杂,不适宜在第一阶段完成。这部分的功能在board/allwinner目录下实现。

b. device init

主要是根据用户的编译配置选择初始化对应的存储设备。这个地方可以改进,比如根据用户的配置文件

sys_config1.fex选择初始化对应的存储设备。这样可以做到一份u-boot.bin适应不同的存储设备。

c. env relocate

初始化环境变量。

d. board later init

初始化fastboot和android recovery,可能修改bootcmd,影响引导流程。

e. main loop

U-Boot的主程序,负责引导内核以及处理用户的命令请求。这部分的功能在common目录下实现。

四、内核启动

在我们平台上使用的是非压缩的内核(bImage),因此内核的启动省去了自解压的过程。内核的链接依赖链接脚本vmlinux.lds,我们平台使用了ARM的内核,对应的链接脚本是arch/arm/kernel/vmlinux.lds。

1. 调用[email protected]查找处理器信息

2. 调用[email protected]为内核自身创建页表

3. 调用处理器底层初始化函数[email protected]/arm/mm/proc-v7.S,初始化 MMU,Cache,TLB

4. 调用[email protected]使能MMU

5. 调用[email protected]重定位数据段,清零BSS,然后跳转到C函数入口

[email protected]/main.c,start_kernel()函数是内核初始化 C 语言部分的主体。这个函数完成系统底层基本机

制,包括处理器、存储管理系统、进程管理系统、中断机制、定时机制等的初始化工作。由于这个函数过于复

杂,这里仅阐述关键点。

6. 调用setup_arch完成架构相关的初始化

7. 调用pidhash_init初始化pid hast机制

8. 调用sched_init初始化调度器

9. 调用init_IRQ初始化中断机制

10. 调用softirq_init完成软中断初始化

11. 调用local_irq_enable打开中断

12. 调用console_init完成控制台初始化

13. 调用rest_init

由上可知,rest_init函数创建了两个内核线程,分别是kernel_init和kthreadd。kernel_init函数将完成设备驱动

程序的初始化,并调用init_post函数启动用户空间的init进程。kthreadd的作用是管理调度其他的内核线程。

14. 调用do_basic_setup函数初始化设备,完成外设及其驱动程序(直接编译进内核的模块)的加载和初始化。

a. [email protected]/cpuset.c

创建cpuset工作队列,它的作用是控制每个程序在哪个核心执行,对于多核的CPU。

b. [email protected]/kmod.c

创建khelper工作队列,它的作用是指定用户空间的程序路径和环境变量,最终运行user space的程序。

c. [email protected]/shmem.c

初始化tmpfs。

d. [email protected]/base/init.c

初始化设备模型。

e. [email protected]/irq/proc.c

初始化/proc/irq。

f. [email protected]/main.c

调用所有构造函数。

g. do_initcalls

初始化子系统。注意,.initcall.init节所保存的函数地址有一定的优先级,越前面的函数优先级越高,会被先调

用。include/linux/init.h定义若干的宏协助内核模块添加它们的初始化函数到.initcall.init节。如需控制同一优先

级的初始化函数执行顺序,可以通过修改模块的Makefile调动编译链接顺序。

15. 调用init_post函数启动用户空间的init进程。在Android系统中,init进程在system/core/init目录下实现。

init_post函数会调用run_init_process 执行ramdisk_execute_command,在run_init_process中,

kernel_execve负责创建用户空间的init进程。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 10:46:09

全志平台linux启动流程分析的相关文章

STB 参考Linux启动流程分析

STB启动流程 1. uboot启动(Fastboot启动) 硬件资源检测(如CPU,DDR Size,Nand  flash,mem size,flash size) print Version(如HW Version,Boot Version,Loader Version) boot设置模型的选择(autoboot or stop) 2. Starting kernel 各种接口驱动的启动() Creating 10 MTD partitions on “hinand” 网卡驱动,USB驱动

u-boot启动流程分析(1)_平台相关部分

转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的“board—>machine—>arch—>cpu”框架,介绍u-boot中平台相关部分的启动流程.并通过对启动流程的简单分析,掌握u-boot移植的基本方法. 注1:本文所使用的u-boot版本,是2016/4/23从u-boot官网(git://git.denx.de/u-boot.git)导入的一个快照,具体可参考“https://github

Android5 Zygote 与 SystemServer 启动流程分析

Android5 Zygote 与 SystemServer 启动流程分析 Android5 Zygote 与 SystemServer 启动流程分析 前言 zygote 进程 解析 zygoterc 启动 SystemServer 执行 ZygoteInitrunSelectLoop SystemServer 启动过程 Zygote 的 fork 本地方法分析 forkSystemServer ZygoteHookspreFork 创建 system_server 进程 ZygoteHooks

Linux系统启动流程分析与关机流程

Linux 系统启动流程分析 Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端. 用户登录系统. init程序的类型: SysV: init, CentOS 5之前, 配置文件: /etc/inittab. Upstart: init,CentOS 6, 配置文件: /etc/inittab, /etc/init/*.conf. Systemd: systemd, CentOS 7,配置文件: /usr/lib/

u-boot启动流程分析(2)_板级(board)部分

转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global data介绍以及背后的思考 5. 前置的板级初始化操作 6. u-boot的relocation 7. 后置的板级初始化操作 1. 前言 书接上文(u-boot启动流程分析(1)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_i

记录Linux启动流程的工具bootchart

/*********************************************************************  * Author  : Samson  * Date    : 04/28/2014  * Test platform:  *              3.11.0-12-generic #19-Ubuntu  *              GNU bash, version 4.2.45  * ****************************

ubuntu upstart启动流程分析

ubuntu自从6.10版本之后就使用了较新的upstart机制来进行系统的初始化. upstart是一种基于事件驱动的服务启动机制,可以使多个系统任务在保持依赖关系的前提下并发启动(据说这样这样启动会比较快,理论上应当如此).使用upstart机制时,我们通过/etc/init下的一系列 *.conf 配置文件来指定各种系统服务的依赖关系(启动时机).系统启动时,upstart主进程/sbin/init会解析这些配置文件,按照指定的依赖关系并发启动各种服务与应用. 主要程序 upstart有三

YARN Container 启动流程分析

YARN Container 启动流程分析 本文档从代码出发,分析了 YARN 中 Container 启动的整个过程,希望给出这个过程的一个整体的概念. 文档分为两个部分:第一部分是全局,从头至尾地把 Container 启动的整个流程串联起来:第二部分是细节,简要分析了 Container 启动流程中涉及到的服务.接口和类. 注意: 基于 hadoop-2.6.0 的代码 只写了与 Container 启动相关的逻辑,并且还大量忽略了很多细节,目的是为了得到一个整体的概念. 为了让分析更具体

ubuntu为什么没有/etc/inittab文件? 深究ubuntu的启动流程分析

最近,因和队友一起做linux开发,因为用的不是同一版本linux(他用arch, 我用ubuntu),再配置上经常就不一样,就如这个inittab文件,于是深究了一下原因: Linux 内核启动 init ,init进程ID是1,是所有进程的父进程,所有进程由它控制. Ubuntu 的启动由upstart控制,自9.10后不再使用/etc/event.d目录的配置文件,改为/etc/init. 查看当前的运行级别,Ubuntu 桌面默认是2. ? 1 runlevel Ubuntu 的系统运行