随着智能终端功能的越来越庞大,与之,硬件配置越来越高,开机时间却越来越长。人们在享受强大功能的同时,对冗长的智能终端的开机时间却越来越缺乏耐心。

为了“取悦”用户,需要提供较好的用户体验,那么就必须使得智能终端尽可能短的进入“可工作”状态。

       本文中的“尽可能短的开机时间”,“开机优化”、“开机时间优化”均表示同一个意思。

       如果计划对linux系统进行开机时间优化,那么就必须熟悉linux启动流程,本小节主要从框架上对Linux启动做简单的介绍,并不会详细的描述。

       如下图:

需要明确的是preloader、lk(Little Kernel)、kernel、android这些系统镜像文件是存储在nand flash中的,然后每个芯片都有个boot rom,在上电时刻,boot rom开始启动,boot rom加载preloader到内部SRAM中,preloader被加载完成之后,程序就从boot
rom跳转到preloader处开始执行,preloader初始化好外部RAM之后,preloader将lk(或uboot)加载外部RAM中,然后跳转到lk(或uboot)中去执行,lk(或uboot)紧接着就加载bootimage(包括kernel和ramdisk)到外部RAM中,然后去执行kernel部分。



1.1BootRom

ROM code是芯片厂商直接烧写到芯片中。

(1)  设备上电后,Boot ROM开始运行。

(2)  BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。

(3)  BootROM通过UART/USB和flash工具握手。

(4)  BootROM通过UART下载pre-loader镜像到NANDflash/EMMC中,然后重启。

(5)  BootROM加载pre-loader到内部SRAM汇总,因为DRAM还没有初始化。

(6)  BootROM跳转到pre-loader并执行。

1.2 BootLoader

BootLoader程序也有多种类型,不同的BootLoader程序,其引脚参数不同。



(1) SD方式

(2) NorFlash Rom方式

(3) NandFlash Rom + chip方式

       一般情况下,发布的正式版本,引脚参数都是固定的,是不可改变的。

1.2.1 preLoader

preloader也就是BootLoader的第一部分。

       pre-loader是内置的loader,它的主要功能如下:

(1)  负责在芯片组平台(chipset platform)上准备好可执行的环境

(2)  如果外部工具有效,它会试图通过UART或是USB来和外部工具握手。(比如USB升级)

(3)  从NAND/EMMC加载U-Boot,并跳转到U-Boot。

(4)  使用工具握手,设备能够触发进入下载模式来下载需要的镜像,或是进入工厂/测试模式,比如META模式和ATE工厂模式,在这些模式下可以测试模块,或是通过传递引导参数给U-Boot和linux内核来校准设备(devicecalibration)

1.2.2 U-Boot

U-Boot也就是BootLoader的第二部分。

 

1) 初始化本阶段使用的硬件设备

2) 检测系统内存映射

3) 将内核从Flash读取到RAM中

4) 为内核设置启动参数

       U-Boot在执行过程中必须设置和初始化 Linux 的内核启动参数。Linux内核在启动过程中会根据该启动参数进行相应的初始化工作。

5) 调用内核映像

       U-Boot完成的最后一项工作便是调用 Linux内核。如果 Linux 内核存放在 Flash 中,并且可直接在上面运行(这里的 Flash指 Nor Flash),那么可直接跳转到内核中去执行。但由于在 Flash 中执行代码会有种种限制,而且速度也远不及
RAM 快,所以一般的嵌入式系统都是将 Linux内核拷贝到 RAM 中,然后跳转到 RAM 中去执行。不论哪种情况,在跳到 Linux 内核执行之前 CUP的寄存器必须满足以下条件:r0=0,r1=处理器类型,r2=标记列表在 RAM中的地址。

智能终端在该阶段可能做了更多动作。

1.3 kernel

start_kernel是所有 Linux 平台进入系统内核初始化后的入口函数,它主要完成剩余的与硬件平台相关的初始化工作,在进行一系列与内核相关的初始化后,调用第一个用户进程-init
进程并等待用户进程的执行,这样整个 Linux 内核便启动完毕。该函数所做的具体工作有:

       1) 调用 setup_arch()函数进行与体系结构相关的第一个初始化工作;

对不同的体系结构来说该函数有不同的定义。对于 ARM 平台而言,该函数定义在arch/arm/kernel/Setup.c。它首先通过检测出来的处理器类型进行处理器内核的初始化,然后通过 bootmem_init()函数根据系统定义的 meminfo 结构进行内存结构的初始化,最后调用paging_init()开启 MMU,创建内核页表,映射所有的物理内存和 IO空间。

       2) 创建异常向量表和初始化中断处理函数;

       3) 初始化系统核心进程调度器和时钟中断处理机制;

       4) 初始化串口控制台(serial-console);

ARM-Linux 在初始化过程中一般都会初始化一个串口做为内核的控制台,这样内核在启动过程中就可以通过串口输出信息以便开发者或用户了解系统的启动进程。

       5) 创建和初始化系统 cache,为各种内存调用机制提供缓存,包括;动态内存分配,虚拟文件系统(VirtualFile System)及页缓存。

       6) 初始化内存管理,检测内存大小及被内核占用的内存情况;

       7) 初始化系统的进程间通信机制(IPC);

       当以上所有的初始化工作结束后,start_kernel()函数会调用 rest_init()函数来进行最后的初始化,包括创建系统的第一个进程-init 进程来结束内核的启动。Init 进程首先进行一系列的硬件初始化,然后通过命令行传递过来的参数挂载根文件系统。最后init
进程会执行用 户传递过来的“init=”启动参数执行用户指定的命令,或者执行以下几个进程之一:

execve("/sbin/init",argv_init,envp_init);

execve("/etc/init",argv_init,envp_init);

execve("/bin/init",argv_init,envp_init);

execve("/bin/sh",argv_init,envp_init)。

       当所有的初始化工作结束后,cpu_idle()函数会被调用来使系统处于闲置(idle)状态并等待用户程序的执行。至此,整个 Linux 内核启动完毕。

1.4 Init

init命令是Linux下的进程初始化工具,init进程是所有Linux进程的父进程,它的进程号为1。init命令是Linux操作系统中不可缺少的程序之一,init进程是Linux内核引导运行的,是系统中的第一个进程。

1.4.1 /etc/inittab

作为系统的第一个执行的程序“/sbin/init”。init程序做的工作相当多,除了利用设置文件“/etc/inittab”来获取运行等级之外,还会通过运行等级的设置值启动不同的服务项目。运行等级是指linux通过设置不同等级来规定系统用不同的服务来启动,让linux的使用环境不同。

"/etc/inittab"中有这么一句" si::sysinit:/etc/init.d/rcS",表明系统需要主动使用"rcS"这个shell脚本来设置系统环境。但这个文件的文件名在各个版本中基本上都是有区别的。

# /etc/inittab: init(8)configuration.
# $Id: inittab,v 1.91 2002/01/2513:35:21 miquels Exp $ # The default runlevel.
id:3:initdefault: 1:012345:respawn:/sbin/getty -n -LttyMT0 115200 vt100 -l /bin/sh # Boot-time systemconfiguration/initialization script.
# This is run first except whenbooting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS

1.4.2 rcS

1.  source/etc/profile

2.  挂载 fstab 基本的文件系统 (/, proc, sys, devpts, tmpfs…)

3.  然后转 rc.local

#! /bin/sh
#设置环境变量
source /etc/profile # Don't use scripts. Just use mount-a for fast boot.
/bin/mount-avt nonfs,nosmbfs #if [ -e /etc/readahead_early ];then
# echo Start readahead /etc/readahead_early
# busybox readahead `cat /etc/readahead_early` &
#fi # Run /etc/rc.d/rc.local if it exists
[ -x /etc/rc.d/rc.local ] &&/etc/rc.d/rc.local

1.4.3 用户自定义引导程序(/etc/rc.d/rc.local)

一般来说,自定义的程序不需要执行上面所说的繁琐的建立shell增加链接文件的步骤,只需要将命令放在rc.local里面就可以了,这个shell脚本就是保留给用户自定义启动内容的。

1.  设置终端参数 stty

2.  设置基本网络相关参数 (lo, hosts, resolv.conf, …)

......

系统启动 之 Linux系统启动概述(1)的更多相关文章

  1. 系统启动 之 Linux系统启动概述(2)

    博客:http://blog.csdn.net/younger_china/article/details/51615916 Linu系统启动是一个"冗长乏味"的过程,那么我们现就 ...

  2. Linux 入门记录:十八、Linux 系统启动流程 + 单用户修改 root 密码 + GRUB 加密

    一.系统启动流程 一般来说,Linux 系统的启动流程是这样的: 1. 开机之后,位于计算机主板 ROM 芯片上的 BIOS 被最先读取,在进行硬件和内存的校验以及 CPU 的自检没有异常后, BIO ...

  3. Linux系统启动那些事—基于Linux 3.10内核【转】

    转自:https://blog.csdn.net/shichaog/article/details/40218763 Linux系统启动那些事—基于Linux 3.10内核 csdn 我的空间的下载地 ...

  4. Linux系统启动详解(一)

    本篇主要以Centos为例,讲述整个Linux系统启动过程,包括了grub引导,initramfs流程,/sbin/init执行rc.sysinit及rc的大体流程. 另外,本篇有一个实例来说明,将整 ...

  5. 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除

    目录 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除 18.1 centos6系统启动过程及相关配置文件 18.1.1 centos6系统启动过程 18.1.2 centos6启 ...

  6. Linux学习之CentOS(二十一)--Linux系统启动详解

      在这篇随笔里面将对Linux系统的启动进行一个详细的解释!我的实验机器是CentOS6.4,当然对于现有的Linux发行版本,其系统的启动基本上都是一样的! 首先我们来看下Linux系统启动的几个 ...

  7. linux基础-附件1 linux系统启动流程

    附件1 linux系统启动流程 最初始阶段当我们打开计算机电源,计算机会自动从主板的BIOS(Basic Input/Output System)读取其中所存储的程序.这一程序通常知道一些直接连接在主 ...

  8. Linux系统启动过程分析

    [原创]Linux系统启动过程分析-wjlkoorey258-ChinaUnix博客http://blog.chinaunix.net/uid-23069658-id-3142047.html 经过对 ...

  9. Linux系统启动流程及安装命令行版本

    Debian安装 之前也安装过很多次linux不同版本的系统,但安装后都是直接带有桌面开发环境的版本,直接可以使用,正好最近项目不是很忙,想一直了解下Linux的整个启动流程,以及如何从命令行模式系统 ...

随机推荐

  1. 《Machine Learning》系列学习笔记之第三周

    第三周 第一部分 Classification and Representation Classification 为了尝试分类,一种方法是使用线性回归,并将大于0.5的所有预测映射为1,所有小于0. ...

  2. Linux+Nginx+Asp.net Core部署

    上篇<Docker基础入门及示例>文章介绍了Docker部署,以及相关.net core 的打包示例.这篇文章我将以oss.offical.site站点为例,主要介绍下在linux机器下完 ...

  3. 【转】Objective-C Runtime

    之前在找Runtime资料,这篇条理是相对比较清晰,对我最有启发的一篇,转载以作记录. 对于iOS小白,值得多看几遍,会有不少收获. --------------------------------- ...

  4. 【记录】iOS10 点击推送栏的问题

    之前做的一个用户点击 推送栏然后处理相应事件是在这里面处理的 - (void)application:(UIApplication *)application didReceiveRemoteNoti ...

  5. SQL SERVER 执行大于80M的SQL 脚本

    在CMD控制器窗口 使用SqlCmd命令来执行 具体请看 SqlCmd /? 或者MSDN

  6. 遍历Arraylist的方法

    package com.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; publ ...

  7. 【VB超简单入门】五、基本输出输入

    之前讲了VB IDE的基本操作和概念,接下来要开始将VB语言的编程了. 程序最重要的部分是输出和输入,输入数据,经过计算机处理,再输出结果.本文将介绍两种最基本的输出输入方法,分别是Print.Msg ...

  8. Webstorm less watcher 配置

    file > sttings > File watchers > 添加LESS watcher 配置如图:

  9. python运用中文注释时报错解决方法

    写了一段简单的代码,不知 为什么总是报错,后来上网查了一下才知道原因,当用中文进行注释时需要添加如下代码:# coding=utf-8          (注意:该段代码必须放在最前面才能有用,并且 ...

  10. PPAPI插件开发指南

    转载请注明出处:http://www.cnblogs.com/fangkm/p/4401075.html 前言 插件一直是浏览器的重要组成部分,丰富浏览器的运行能力,实现一些HTML+JS实现不了本地 ...