zoukankan      html  css  js  c++  java
  • Linux Kernel系列一:开篇和Kernel启动概要

    前言

    近期几个月将Linux Kernel的大概研究了一下,以下须要进行深入具体的分析。主要将以S3C2440的一块开发板为硬件实体。大概包含例如以下内容:

    1 bootloader分析,以uboot为主,结合详细开发板的情况。我的目标是解释清楚uboot的工作原理(说实话,分析过程中不太想被硬件绑架,可是须要以一个实际的样例

    来做分析)

    2 kernel部分,这就非常多内容了。打算从kernel启动的流程開始分析。

    3 除kernel本身外,还有非常多的知识,比如ld的输入script分析等,这里会一起介绍。


    kernel启动流程概要

    一:内核Image的组成
    1 ES(Embed System)启动的时候,CPU加电,运行的第一条语句是Bootloader,这个很类似PC机上的BIOS。BL将内核载入后,控制器移交给LK
    2 LK运行的第一条语句是什么?vmlinux是单体的内核表示。依据前面说的内核编译连接知识,第一条语句是head.S中(历史原因,MD,有非常多文件都叫head.S)
     我们须要又一次分析一下内核(这里就是zImage了)的组成,(方法非常easy,研究make的运行过程,通过make V=1 zImage能够得到差点儿所有信息)
    • vmlinux,这个是未压缩、未strip的内核模块,ELF结构
    • Image:二进制、未压缩、可是strip后的内核
    • head.o:ARM相关的,由BL将控制权转交给它。即前面提到的head.S生成
    • pigg.gz:Image文件的gzip压缩
    • piggy.o:由piggy.S生成,这个S文件通过include Bin方式将Image包括进来。piggy的意思就是背负、肩扛。非常形象不是?
    • misc.o:从上面看,涉及到一些解压方面的内容,而misc提供一些辅助函数
    • vmlinux:悲催.....这个文件是head+pigg+misc构成的vmlinux。名字一样不是?真的非常混淆!
    • zImage:再由上面这个vmlinux压缩而来
    图1非常好得展示了这个过程。

    图1 内核的构成
    3 piggy的故事
    piggy.S非常有意思,建立了一个section,而且有一个标志来指示piggy.gz的边界。
    piggy相应的是一个叫bootstrap的image,注意,Bootstrap和Bootloader不一样,它是在BL之后的一段代码,用来
    解压kernel,设置内存等作用。也能够叫second stage boot。
     
    4 Bootloadre和BootstrapLoader
    BL和BSL的差别是什么?
    • BL仅仅是初始化硬件,不依赖linux,不处理linux
    • BSL在BL后执行,依赖linux,由于要解压linux。另外一个重要点就是BSL须要为LINUX的执行建立环境
    BSL的工作包含:
    • head.O:初始化CPU等工作
    • misc.O:解压,重定位(比如将kernel移动到另外一个位置上) decompress_kernel
    • 其它工作
    init/main.c:start_kernel
    启动调用图见图2.

    图2 启动调用流程图
    以下来分析这个启动流程
    1 kernel中的head.o分析:尽量保持CPU系列的通用,比如arm的CPU等初始化都在做。可是详细板子(比如CPU+其它硬件)怎么初始化?这就是由mach文件夹中的初始化函数做到的。所以,kernel初始化分为:generic CPU初始化+详细板子的初始化。head.o初始化后,跳转到main.o的start_kernel,继续后面的流程
    2 start_kernel:(init/main.c):start_kernel的转移由head.O做的,只是代码一般包括在更通用的head_common.S中
       以后想做kernel的分析,就从main開始吧. start_kernel做了什么事情呢?
    • 刚才仅仅是初始化了cpu相关的,而详细和板子相关的由start_arch运行
    3 kernel 參数分析:kernel command line。注意,这个參数是由BL传递给kernel的,只是这个參数又是谁设置的呢?又存在什么地方呢?这个line放在一个global的地方,
      另外,kernel怎样处理这些參数呢?有一个比較好的办法,__set_up宏,将一些參数和相应的函数指针存在一个特殊的section中,然后循环调用这个section中的函数。(和驱动module中的非常像)。定义在init.h中。关于一些特殊參数的取值,在arch/arm/kernel/vmlinux.lds.S中定义。(以后得去看看ld的manual了)__set_up这个宏另一个flags比方early,表示处理阶段是否在early-stage做。标志有__init的section终于占用的内存会被抛弃..
    4 子系统初始化:包含中断、等。?section嵌套section?
    5 kernel_init进程:start_kernel最后会fork一个kernel_init进程,而原运行进程变成idle进程了..
    6 用户空间的init进程:由kernel_init进程终于通过execve init完毕
    7 參考文献。ELP这本书给的參考文献都巨强..

     

  • 相关阅读:
    guava cache 缓存
    策略模式干掉if-else,switch
    一.投资理论
    死锁问题
    Redis连接数居高不下的问题
    Entity Framework Core To SQL问题
    数据字典
    Core2.0升级2.2
    NetCoreAPI版本控制
    WEBAPI的请求方式与请求类型
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4201225.html
Copyright © 2011-2022 走看看