zoukankan      html  css  js  c++  java
  • ARM Linux从Bootloader、kernel到filesystem启动流程

    转自:http://www.veryarm.com/1491.html

    ARM Linux启动流程大致为:bootloader ---->kernel---->root filesystem。bootloader 是一上电就拿到cpu 的控制权的,而bootloader实现了硬件的初始化。bootloader俨然就成了Power on 之后”第一个吃螃蟹”的代码。

    谈到这就得想到硬件机制是如何满足这个功能的了。CPU内部一般都集成小容量的SRAM (又叫stapping stone,垫脚石),当系统一上电,NAND controler 就自动地将Nand flash 里的前内容复制到垫脚石里,而PC 指针一上电就指向垫脚石的起始地址0x00000000。这样这一部分的代码就可以得到执行。所以,这一部分的代码就是 bootloader 部分,那一上电bootloader 不就可以得到运行了么?事实确实如此,在嵌入式Linux的软件系统中,nandflash前面一部分代码往往就是bootloader ,然后就是kernel, 再接着就是根文件系统。

    说了这么多,好像都没说到启动流程啊,别着急,咱慢慢谈,所谓磨刀不误砍柴工嘛。

    要说启动流程,如果只是简单的介绍从哪到哪,谁干了啥啥,得到的结果可能只是只知其然不知其所以然。个人觉得随着CPU的PC指针走,循着代码的足迹才能把整个流程理清楚,当找到了代码的执行过程,再分析一下代码,自然知道了哪个部分完成了哪些事,更重要的是为代码的移植打下了坚实的基础。自然这个过程是痛苦和枯燥的,甚至是看代码看了几天也没弄明白,不过这也是一种锻炼。

    bootloder 

    前面说了,bootloader一上电就拿到了cpu 的使用权,它当然得干一些初始化的工作啊,比如关闭看门狗、设置cpu 的运行模式、设置堆栈等等比较急迫的事情。当然还要对主板的一些其他硬件进行简单的初始化,比如外部DDR内存、网卡、显示屏、nand flash等等的初始化工作,最后还要负责把Linux内核加载到内存中。正所谓责任和权力是并存的嘛,你得到了权益,当然就得付出。当bootloader 完成它的使命之后就会把cpu 的使用权交给下一部分代码:kernel 。

    kernel

    在讨论kernel 是如何启动之前,先了解kernel 的组成结构以及是如何得来的。下面这张图是内核编译即将结束时显示的信息:

    11f36c7a535f07454fa15220c9e2cf87

    下面的这张图说明了上面的编译过程,

    9ae59fb6dc568a9fd3838b9d87f004cc

    可以看到,当内核源文件编译链接成 vmlinux 文件以后还进行了几个模块的编译和链接。其中

    (1)vmlinux 是ELF格式的object文件,这种文件只是各个源代码经过连接以后的得到的文件,并不能在arm平台上运行

    (2)经过objcopy这个工具转换以后,得到了二进制格式文件Image,Image文件相比于vmlinux 文件,除了格式不同以外,还被去除了许多注释和调试的信息

    (3)Image文件经过压缩以后得到了piggy.gz ,这个文件仅仅是Image的压缩版,并无其他不同

    (4)接着编译生成另外几个模块文件misc.o、big_endian.o、head.o、head-xscale.o,这几个文件组成一个叫 bootstrap loader 的组件,又叫引导程序。编译生成 piggy.o 文件。

    (5)最后piggy.o文件和bootstrap loader 组成一个bootable kernel Image 文件(可启动文件)。

    可以看到最后得到的可执行文件就是上图最右边那个,这也是我们最后烧写到开发板的镜像。其中piggy.o 就是内核镜像,而剩下的几个文件就组成了引导程序。

    下面开始讨论CPU的流转过程,还是用一个图来展示:

    294474c84d19f650fe64c3bbbc49ee19

    从上图可以看出,系统一上电就开始执行bootloader。当bootloader 执行完以后,把控制权交给了引导程序的head.o 文件里的start 标号处,当引导程序完成引导工作以后就将控制权转给真正的内核的head.o 文件里的start 标号处。这里就是内核的入口点,最后内核的head.o将控制交给main.o 的start_kernel 函数。这样,通过查看相应的代码就可以知道这些代码到底完成了哪些工作。在这里我们可以找到相应的代码,分析一下,看它们到底完成哪些事。下面是我的分析结果

    引导程序:

    head.o从bootloader接过控制权,并完成如下任务:

    1. 使能 I/D caches ,关闭中断 , 建立C运行环境(即设置堆栈)由 head.o 和head-xscal.o 完成
    2. 解压缩并重定位代码 ,由misc.o 完成
    3. 其他硬件相关的设置,如big.endian.o 为cpu设置大端模式

    内核入口点:从引导程序接过控制权,完成如下任务

    1. 检查有效的cpu 和cpu的信息
    2. 创建初始化页表入口
    3. 使能MMU
    4. 检测错误并报告
    5. 跳转到内核本身 main.c 文件里的 start_kernel()函数

    内核启动:

    从 kernel 的head.o接过控制权,开始内核的启动,在这里完成内核的初始化,如内核各个子系统的初始化。

    root filesystem

    到此止,kernel完成了系统硬件探测及硬件驱动的初始化,内核空间的相关工作已经完成,开始向用户空间转移,内核空间通过一个间接的initrd(一个虚拟的文件系统)向用户空间过度,然后开始挂载根文件系统了,其过程:initrd ----> /sbin/init ----> /etc/inittab

    initrd是一个虚拟的文件系统,里面有lib、bin、sbin、usr、proc、sys、var、dev、boot等一些目录,其目录有点像真的/,所以我们称之为虚拟的根文件系统,作用就是将kernel和真的根文件系统建立关联关系,让kernel去initrd中加载根文件系统所需要的驱动程序,并以读写的方式挂载根文件系统,并让执行用户当中第一个进程init

    init执行完毕以后会启动系统内的/etc/inittab文件,来完成系统系统的初始化工作。

  • 相关阅读:
    pipelinewise 学习二 创建一个简单的pipeline
    pipelinewise 学习一 docker方式安装
    Supercharging your ETL with Airflow and Singer
    ubuntu中使用 alien安装rpm包
    PipelineWise illustrates the power of Singer
    pipelinewise 基于singer 指南的的数据pipeline 工具
    关于singer elt 的几篇很不错的文章
    npkill 一个方便的npm 包清理工具
    kuma docker-compose 环境试用
    kuma 学习四 策略
  • 原文地址:https://www.cnblogs.com/aaronLinux/p/5540474.html
Copyright © 2011-2022 走看看