全志linux关机键,全志平台linux启动流程分析

转载:全志平台linux启动流程分析

一、BROM阶段

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

下面展示了BROM的执行流程

a4c26d1e5885305701be709a3d33442f.png

二、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执行过程

a4c26d1e5885305701be709a3d33442f.png

2. boot1的执行过程

a4c26d1e5885305701be709a3d33442f.png

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. 第一阶段

a4c26d1e5885305701be709a3d33442f.png

在第一阶段会关闭I/D

cache和MMU,因此,整个U-Boot是直接运行在物理地址上。

2.

第二阶段

a4c26d1e5885305701be709a3d33442f.png

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.

调用__lookup_processor_type@head-common.S查找处理器信息

2.

调用__create_page_tables@head.S为内核自身创建页表

3.

调用处理器底层初始化函数__v7_setup@arch/arm/mm/proc-v7.S,初始化

MMU,Cache,TLB

4.

调用__enable_mmu@head.S使能MMU

5.

调用__mmap_switched@head-common.S重定位数据段,清零BSS,然后跳转到C函数入口

start_kernel@init/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.

cpuset_init_smp@init/cpuset.c

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

b.

usermodehelper_init@init/kmod.c

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

space的程序。

c.

init_tmpfs@mm/shmem.c

初始化tmpfs。

d.

driver_init@driver/base/init.c

初始化设备模型。

e.

init_irq_proc@kernel/irq/proc.c

初始化/proc/irq。

f.

do_ctors@init/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进程。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
全志R16平台编译linux系统V1.0.txt 2017/4/11 13:36 (编译请使用编译android的lichee的选项编译生成的.config文件,不然直接编译会报错!!!!) rootroot@cm-System-Product-Name:/home/wwt/linux_r16$ tar zxvf lichee_parrotv1.1_20161202.tar.gz rootroot@cm-System-Product-Name:/home/wwt/linux_r16$ cd lichee/ rootroot@cm-System-Product-Name:/home/wwt/linux_r16/lichee$ ./build.sh config Welcome to mkscript setup progress All available chips: 0. sun8iw5p1 Choice: 0 All available platforms: 0. android 1. dragonboard 2. linux 3. tina Choice: 2 All available kernel: 0. linux-3.4 Choice: 0 All available boards: 0. bell-one 1. evb 2. evb-20 3. evb-30 4. evb-rtl8723bs 5. sc3813r Choice: 3 rootroot@cm-System-Product-Name:/home/wwt/linux_r16/lichee$ ./build.sh 错误1: KCONFIG_AUTOCONFIG=/home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/build/buildroot-config/auto.conf KCONFIG_AUTOHEADER=/home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/build/buildroot-config/autoconf.h KCONFIG_TRISTATE=/home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/build/buildroot-config/tristate.config BUILDROOT_CONFIG=/home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/.config /home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/build/buildroot-config/conf --silentoldconfig Config.in # # make dependencies written to .auto.deps # ATTENTION buildroot devels! # See top of this file before playing with this auto-preprequisites! # make[1]:正在离开目录 `/home/wwt/linux_r16/lichee/buildroot' You must install 'makeinfo' on your build machine makeinfo is usually part of the texinfo package in your distribution make: *** [dependencies] 错误 1 make:离开目录“/home/wwt/linux_r16/lichee/buildroot” ERROR: build buildroot Failed rootroot@cm-System-Product-Name:/home/wwt/linux_r16/lichee$ d/buildroot-config/conf.o /home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buildroot/build/buildroot-config/zconf.tab.o -o /home/wwt/linux_r16/lichee/out/sun8iw5p1/linux/common/buil
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值