轻松识破linux内核启动过程中的“”套路“”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轻松识破linux内核启动过程中的“”套路“”相关的知识,希望对你有一定的参考价值。

    内核启动流程相关的内容让很多热爱linux的小伙伴既爱又恨,因为这是了解linux系统基本构造的良好过程同时由于其本身复杂且底层,脑子中的脉络不是很清晰,本文就总结了一些优秀博文,以自己的理解来解构一下。

     本文的环境是CentOS 6.8,

    基本过程:

  技术分享庖丁解牛:

   1.POST

       Bios的功能由两部分组成, 

         步骤1:上电自检POST(Power-on self test),主要负责检测系统外围关键设备(如:CPU、内                 存、显卡、I/O、键盘鼠标等)是否正常。例如,最常见的是内存松动的情况,BIOS自                 检阶段会报错,系统就无法启动起来;

         步骤2:步骤1成功后,便会执行一段小程序用来枚举本地设备并对其初始化。这一步主要是根               据我们在BIOS中设置的系统启动顺序来搜索用于启动系统的驱动器,如硬盘、光盘、U                 盘、软盘和网络等。我们以硬盘启动为例,BIOS此时去读取硬盘驱动器的第一个扇区                 (MBR,512字节),然后执行里面的代码。 BIOS的任务就完成后将系统启动的控制权移交               到MBR部分的代码。


2.MBR(Master Boot Record):主引导扇区位于整个硬盘的0磁头0柱面1扇区,包括硬盘主引导记录MBR(Master Boot Record)和分区表。其中主引导记录的作用就是检查分区表是否正确以及确定哪个分区为引导分区,并在程序结束时把该分区的启动程序,也就是操作系统引导扇区调入内存加以执行。

技术分享



stage1:stage1是直接被写入到MBR中去的,这样机器一启动检测完硬件后,就将控制权交给了GRUB的代码。也就是上图所看到的前446个字节空间中存放的是stage1的代码。BIOS将stage1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务非常单纯,仅仅是将硬盘0头0道2扇区读入内存。而0头0道2扇区内容是源代码中的/stage2/start.S,编译后512字节,它是stage2或者stage1_5的入口

stage1.5它存放在硬盘0头0道3扇区向后的位置,stage1_5作为stage1和stage2中间的桥梁,stage1_5有识别文件系统的能力,此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行。

技术分享

当stage2被载入内存执行时,它首先会去解析grub的配置文件/boot/grub/grub.conf,然后加载内核镜像到内存中,并将控制权转交给内核。而内核会立即初始化系统中各设备并做相关的配置工作,其中包括CPU、I/O、存储设备等。

关于Linux的设备驱动程序的加载,有一部分驱动程序直接被编译进内核镜像中,另一部分驱动程序则是以模块的形式放在initrd(ramdisk)中


  1. default=1    # 默认启动的内核title, 0 表示是第一个  

  2. timeout=5    # 默认等待时间  

  3. splashimage=(hd0,0)/grub/splash.xpm.gz    # 指定菜单的背景图片的路径。为xpm格式,采用gzip压缩,只能为14bits色  

  4. hiddenmenu    # 隐藏菜单  

  5. title CentOS (2.6.32-358.el6.x86_64)    # 标题名,用户可自定义  

  6.     root (hd0,0)    # 指定 grub 的根位置  

  7.     # 指定 kernel 文件的位置,还要指出 root(系统启动后) 的位置,挂载方式 ro,这项很关键。  

  8.     # 加载后会启动 init 进程。  

  9.     kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/mapper/vg0-root rd_NO_LUKS rd_NO_DM LANG=en_US.UTF-8 rd_LVM_LV=vg0/swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=vg0/root  KEYBOARDTYPE=pc KEYTABLE=us rhgb crashkernel=auto quiet rhgb quiet  

  10.     # 在内核启动过程中装载根文件系统时有用  

  11. initrd /initramfs-2.6.32-358.el6.x86_64.img 

3.kernel:

    自身初始化:

    探测可识别到的所有硬件设备;

加载硬件驱动程序:(有可能会借助于randisk加载驱动)

以只读方式挂载根文件系统,防止内核对根文件系统有损坏

运行用户空间的第一个应用程序:/sbin/init



a.ramfs

  1.  initramfs 是以 gzip 压缩的 cpio 格式的文件。内核启动时将他作为一个临时的根文件系统。  

  2. # grub 的 stage2 将initrd加载到内存里,让后将其中的内容释放到内容中,  

  3. # 内核便去执行init脚本,这时内核将控制权交给了init文件处理。  

  4. # init 它也主要是加载各种存储介质相关的设备驱动程序。当所需的驱动程序加载完后,  

  5. # 会创建一个根设备,然后将根文件系统rootfs以只读的方式挂载。  

  6. # 这一步结束后,释放未使用的内存,转换到真正的根文件系统上面去,同时运行/sbin/init程序,  

  7. # 执行系统的1号进程。此后系统的控制权就全权交给/sbin/init进程了。 

b.


4.系统初始化



一览众山小:

技术分享













本文出自 “mylinux” 博客,请务必保留此出处http://luxiangyu.blog.51cto.com/9976123/1851240

以上是关于轻松识破linux内核启动过程中的“”套路“”的主要内容,如果未能解决你的问题,请参考以下文章

linux内核分析作业3:跟踪分析Linux内核的启动过程

Linux 系统启动过程

linux学习-Linux系统启动过程

Linux 系统启动过程

Linux内核启动及根文件系统载入过程

跟踪调试Linux内核的启动过程