Linux系统启动详解(二)

上节讲到了Linux启动大体流程,及grub的作用,本节主要扯扯initramfs的那些事,并且通过简单修改initramfs,将整体操作系统运行到了内存中。

3       initramfs

3.1     简述

  在2.4内核中initrd为boot loader initialized RAM Disk,linux启动前boot loader先将initrd文件解压,并加载到内存中。boot loader加载内核后,会先运行initrd,再switch_root到真正root fs。

  在2.6内核中将initrd升级为initramfs,与initrd相比其作用相同,但是initramfs流程更加简洁,即解压initramfs后,运行init脚本,所以任务交由init脚本来完成。

更多initrd与initramfs的说明可参见文献[3]。

[3]:Linux2.6内核的Initrd机制解析http://www.ibm.com/developerworks/cn/linux/l-k26initrd/

3.2     init基本流程

  initramfs的真正作用加载硬件模块和文件系统模块,用于切换到root device上的真正的root fs上。当然由于root fs应该支持存在于md或者dm设备上,所以在initramfs期间也会加载md和dm模块,如果md编译进行了内核的话,从加载的模块中是查看不到的。

以下是通过在initramfs中的init文件中添加log,分析一个大概的开机流程,非细节。

1)         解压并加载initramfs到内存后,当前root fs就是initramfs,所以/下所有文件都来源于initramfs。

2)         通过挂载/proc和/sys;mknod创建基本的设备/dev/console、/dev/null等。

3)         udev规则对硬件进行扫描,加载对应模块,创建对应设备,对于grub.conf中设置的root设备,若创建成功,则会在/dev/下创建/dev/root的链接指向对应真实设备。

4)         与此同时,无限循环判断/dev/root是否已存在,若不存在,再次执行所有udev规则,尝试是否有新硬件已准备就绪,判断40次后(约20秒),仍未找到,则报出“no root device fonud, sleep forever”

5)         通过root device挂载真正的root fs。

6)         判断/proc目录是否存在,作为root fs已挂载成功的标准(此时的/proc仅仅是个空目录)。

7)         判断真正的root fs的init脚本是否存在,一般是/sbin/init

8)         root fs已挂载到/sysroot目录后,执行switch_root /sysroot /sbin/init。

9)         switch_root命令执行后,initramfs的任务全部完成,切换到真正的root fs,开始执行/sbin/init

3.3     initramfs过程中的模块加载情况

begin init:

Opening /proc/modules: No such file or directory

pre udev:

Module                  Size  Used by

after udev:

Module                  Size  Used by

sd_mod                 37157  0

crc_t10dif              1507  1 sd_mod

sr_mod                 16162  0

cdrom                  39769  1 sr_mod

mptspi                 16537  0

mptscsih               35302  1 mptspi

mptbase                91106  2 mptspi,mptscsih

scsi_transport_spi     26117  1 mptspi

pata_acpi               3667  0

ata_generic             3611  0

ata_piix               22588  0

dm_mod                 76856  0

after mount root fs, before switch root:

Module                  Size  Used by

ext4                  353883  1

mbcache                 7918  1 ext4

jbd2                   88969  1 ext4

sd_mod                 37157  2

crc_t10dif              1507  1 sd_mod

sr_mod                 16162  0

cdrom                  39769  1 sr_mod

mptspi                 16537  1

mptscsih               35302  1 mptspi

mptbase                91106  2 mptspi,mptscsih

scsi_transport_spi     26117  1 mptspi

pata_acpi               3667  0

ata_generic             3611  0

ata_piix               22588  0

dm_mod                 76856  0

3.4     initramfs的解压&&压缩

1、  解压:

-bash-4.1# file initramfs-2.6.32-71.el6.5.vsds.x86_64.img

initramfs-2.6.32-71.el6.5.vsds.x86_64.img: gzip compressed data, from Unix, last modified: Tue Dec 18 17:25:14 2012, max compression

# gzip文件格式,所以需要先mv为gz文件

-bash-4.1# mv initramfs-2.6.32-71.el6.5.vsds.x86_64.img initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz

-bash-4.1# file initramfs-2.6.32-71.el6.5.vsds.x86_64.img

initramfs-2.6.32-71.el6.5.vsds.x86_64.img: ASCII cpio archive (SVR4 with no CRC)

-bash-4.1# gunzip initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz

initramfs-2.6.32-71.el6.5.vsds.x86_64.img

#此时为cpio格式

-bash-4.1# mkdir initramfs

-bash-4.1# cd initramfs

-bash-4.1# cpio -id ../initramfs

initramfs/                                 initramfs-2.6.32-71.el6.5.vsds.x86_64.img

-bash-4.1# cpio -id < ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img

72953 blocks

2、  压缩:

-bash-4.1# find . | cpio -c -o > ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img

72953 blocks

-bash-4.1# gzip ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img

-bash-4.1# cp ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz /boot

3.5     实例---将整个操作系统运行在内存

  以下使用方案并未真正应用,以下纯属个人理解,供参考。

3.5.1  优点 && 缺点

1、优点:

1)         运行速度更快。开机后,由于系统运行在内存,运行速度要更快。

2)         文件系统不会损坏。系统异常断电,或者其它破坏操作,不会引起操作系统损坏。

3)         节省存储介质空间。操作系统可以进行压缩后存放在可存储介质中(压缩率约80%),甚至可以存放在网络环境上,开机后,解压再到内存。

4)         便于多台系统统一升级升级。若系统压缩文件存放在网络环境上,那么文件升级,使用这个文件的任意台设备升级过程就仅仅是重启就可以做到。

2、缺点:

1)         开机速度略慢。由于启动过程需要将操作系统解压到内存,会略慢一点,约10 ~ 20秒不明显。

2)         root fs无法存储数据。由于系统运行在内存,重启后新存储的丢失。因此,一般需要存储数据的分区单独挂载一个非易失的介质上。

3)         内存要求更大。由于内存固定部分会划分一个ram disk,用于运行操作系统。对于操作系统就需要900M空间的应用,内存2G就不足以支撑整个系统。

4)         更新系统较麻烦。对于需要频率更改系统的环境,若要生效,需要重新制作压缩文件,较麻烦。

3.5.2  应用场景

  目前嵌入式系统大多使用此方案,应该是基于其较小的存储空间,及无用户写入数据要求而决定的。(本人不是做嵌入式的,纯属个人猜测哈)

3.5.3  实现思路

思路一:就是把整体系统做成initramfs。(未测试)

  initramfs就是一个小文件系统,也是开机第一个加载的文件系统,所以把整体系统都做成initramfs,那么系统启动只需要2个文件即可,一是内核vmlinux;二是initramfs。

  也就是说在initramfs最后要切换到真正的root fs时,不切换到了,直接运行系统中的/sbin/init。

  但是initramfs可能会达到300M(root fs900M左右),boot loader会不会需要加载很长时间?

思路二:在initramfs运行过程中,将压缩的系统解压并复制到内存中运行

  在上节已说明initramfs其实就是执行一个init脚本,简单修改脚本流程。当寻到到root device设备后,将挂载root device挂载到/sysroot修改为,挂载root device到其它挂载点,再从root device中找到之前制作的压缩的系统文件,将文件解压到ramdisk中,挂载ramdisk到/sysroot,再切换到真正的root fs。

3.5.4  实现代码

  以下仅根据思路二为基本,完成的一个简单模型。

  将系统文件解压并复制到内存,那么先得将真正的root fs制作为一个系统文件,再通过initramfs的过程将其加载到内存。

1、  root fs文件ramlinux.img.gz的制作。

  开始只将参考资料[2]中文件制作为了ramlinux.img.gz(压缩后约80M,解压后给不到200M),开机系统就panic,想必是应该缺少文件导致,所以,就将整个/下所有文件都制作到ramdisk.img.gz中,系统正常运行。

  制作ramdisk.img.gz的脚本为mkrootfs.sh如下:

#!/bin/sh

rootfs="/mnt/ram"

umount $rootfs

rm -rf $rootfs

# make ram disk and mount

dd if=/dev/zero of=/dev/ram bs=1M count=900

echo y | mkfs.ext2 /dev/ram

mkdir $rootfs

mount -o loop /dev/ram $rootfs

# cp file to ram disk

pre_dir="/"

#pre_dir="/mnt/sdf1/"

# all file in dir cp to ram disk

cpdir=(bin boot cgroup etc home lib lib64 media opt sbin selinux srv usr var)

for dir_i in ${cpdir[@]}

do

echo "cp -av $pre_dir$dir_i $rootfs"

cp -av $pre_dir$dir_i $rootfs

done

# just mkdir, not cp file

mkdir=(proc sys tmp mnt root)

for dir_j in ${mkdir[@]}

do

echo "mkdir $rootfs/$dir_j"

mkdir $rootfs/$dir_j

done

# create dev device

mkdir $rootfs/dev

dev=`find /dev`

for dev_i in ${dev[@]}

do

if [ $dev_i = "/dev/ram" -o $dev_i = "/dev" ]

then

echo "find $dev_i pass........................................... "

continue

fi

echo "cp -R $dev_i $rootfs/dev"

cp -R $dev_i $rootfs/dev

done

# do ramlinux.img from ram disk

umount $rootfs

dd if=/dev/ram of=/mnt/bigspace/ramlinux.img bs=1M

gzip /mnt/bigspace/ramlinux.img

2、  initramfs加载root fs文件ramlinux.img.gz。

  initramfs挂载真正的root fs,是通过执行initramfs的mount目录下的*.sh来完成的,在mount目录下加入98mount-ramdisk.sh,移除99mount-root.sh(原挂载root device到/sysroot的脚本)。由98mount-ramdisk.sh来完成系统文件的解压,及挂载。

  98mount-ramdisk.sh如下:

#!/bin/sh

echo "Mount root device for get img file"

mount -o defaults --rw /dev/root /mnt

echo "zcat img file to ram"

/bin/zcat /mnt/root/ramlinux.img.gz > /dev/ram

umount /mnt

echo "mount -o loop /dev/ram /sysroot"

mount -o loop /dev/ram /sysroot

echo "ls /sysroot"

/bin/ls /sysroot/

[ -d "/sysroot/proc" ] || echo "proc not exist 5555555555555555555........"

3、  完成以上步骤后,将initramfs解压,拷贝98mount-ramdisk.sh到mount目录下,删除99mount-root.sh,重新生成initramfs,覆盖/boot下的原文件,重启即生效。

4、  其它注意。由于解压ramlinux.img需要zcat命令,但此命令initramfs中未加入,因此,还需要从系统中拷贝zcat命令到initramfs的bin目录下。(拷贝命令前,需要通过ldd /bin/zcat查看该命令是否有对应动态链接库,如果有要一并cp-R到initramfs的对应目录下,否则仅拷贝命令,命令是无法执行的)

5、  重启后的系统环境:

a)         重启后,系统从挂载信息即可看出当前系统已运行在内存中,并且touch的新文件,重启无未保存,挂载信息如下:

-bash-4.1# df -h

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda1             886M  886M     0 100% /

tmpfs                 2.0G   52M  1.9G   3% /dev/shm

/dev/sda2             146M   32M  106M  24% /var/log

 (/的挂载设备应该不是/dev/sda1,应该是df命令在当前模型下显示的问题,应该是/dev/ram,由于只是简单模型搭建,很多配置未修改成导致。)

b)         /dev/sda1是grub.conf中设置的root device,也是ramlinux.img文件真正存储的介质。

-bash-4.1# cat /boot/grub/grub.conf

# grub.conf generated by anaconda

#

# Note that you do not have to rerun grub after making changes to this file

# NOTICE:  You do not have a /boot partition.  This means that

#          all kernel and initrd paths are relative to /, eg.

#          root (hd0,0)

#          kernel /boot/vmlinuz-version ro root=/dev/sda1

#          initrd /boot/initrd-[generic-]version.img

#boot=/dev/sda

default=0

timeout=5

splashimage=(hd0,0)/boot/grub/splash.xpm.gz

hiddenmenu

title SkySAN Storage System (2.6.32-71.el6.5.vsds.x86_64)

root (hd0,0)

kernel /boot/vmlinuz-2.6.32-71.el6.5.vsds.x86_64 ro root=UUID=212c95a4-56d0-44fc-93ce-73b5f3e8cf2a rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us

initrd /boot/initramfs-2.6.32-71.el6.5.vsds.x86_64.img

3.6     init脚本中加入log信息

  在理解init脚本过程中,为了更深入的理解init的作用,及当前环境状态,往往需要打印一些我们自己需要的信息,在打印到屏幕的同时,如果可能保存文件,便于多次阅读更好。

方法如下:

logfile="/tmp/logfile"

# tee用于将输出到屏幕的信息,同时保存文件,-a:不覆盖文件原内容,相当于>>

echo "begin init -------------------------------------------------------" 2>&1 | tee -a $logfile

lsmod 2>&1 | tee -a $logfile

sleep 5

……

#在swith_root前,将文件拷贝到/dev/目录下,切换到root fs后,可以保留。

cp $logfile /dev/

exec switch_root "$NEWROOT" "$INIT" $initargs

……

时间: 2024-10-10 16:27:33

Linux系统启动详解(二)的相关文章

10.Linux系统启动详解

10.Linux系统启动详解 ·1.BIOS,负责检查硬件并且查找可启动设备, ·2.MBR:Boot Code, ·bios找到可启动设备后执行其引导代码,MBR的前446字节, ·/boot/grub/stage1内容为当前硬盘MBR的镜像, ·3.执行引导程序-GRUB ·grub是现在Linux使用的主流引导程序,可以用来引导大多数主流系统, ·Linux的grub可以识别windows的启动程序,但windows的会覆盖Linux的,故先windows后Linux, ·grub相关文件

linux系统启动详解

要学习linux的命令,我们需要先了解linux系统是如何工作的,这里我们先了解linux是如何在一台电脑上启动加载的!! linux系统启动过程 第一步.  BIOS初始化  1.  BIOS检测所有的外置设备,查看有哪些外围设备在活动区  2.  开始寻找启动磁盘--根据BIOS的设置导找启动文件存放的位置 第二步.执行启动加载器  1. 先到MBR(主引导记录)磁盘导找启动文件,比如:grub /LILO  2. 到boot partition(启动分区)去找启动文件-比如:grub /L

Linux系统启动详解(一)

本篇主要以Centos为例,讲述整个Linux系统启动过程,包括了grub引导,initramfs流程,/sbin/init执行rc.sysinit及rc的大体流程. 另外,本篇有一个实例来说明,将整个操作系统运行在内存的实例(系统默认是使用一块物理磁盘存储操作系统). 1       概述 Linux系统从软件角度,启动大致过程如下: 1)         硬件及BIOS加载,通过启动项找到MBR,读取MBR中的boot loader,即我们常用的grub工具. 2)         boot

Linux入门-8 Linux系统启动详解

系统启动流程 BIOS MBR GRUB KERNEL INIT 单用户修改root密码 GRUB加密 系统启动流程 BIOS MBR: Boot Code 执行引导程序 - GRUB 加载内核 执行init runlevel BIOS Basic Input Output System,一般保存在主板的BIOS芯片中 计算机启动时首先运行BIOS,负责检查硬件并且查找可启动设备 可启动设备在BIOS设置中进行定义,如USB, CDROM, HD MBR 不同的系统有不同的MBR BIOS找到可

Linux 信号详解二(信号分类)

信号分类 信号分为可靠信号和不可靠信号 不可靠信号的缺点 ①:处理完信号,需要重新再注册信号:②信号可能丢失. Linux已经对缺点①做了优化,现在的不可靠问题主要指的是信号可能丢失 信号还可以分为实时信号和非实时信号--一般不可靠信号指的是前32种信号,这32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作 --可靠信号指的后32种信号 --非实时信号都不支持排队,都是不可靠信号:实时信号都支持排队,都是可靠信号.

Linux系统启动详解(三)

上节已系统initramfs已启动完成,将系统控制权交给了真正的rootfs的/sbin/init,下面就是/sbin/init干活的时间了. 4       /sbin/init initramfs的init脚本,通过switch_root命令,切换到真正的root fs后,执行的第一个程序就是root fs下的/sbin/init, 4.1     switch_root swith_root newroot init [arg] eg: initramfs中切换到真正的rootfs命令是s

Linux基本命令详解《二》(Linux中对目录和文件管理所使用的命令)

Linux基本命令详解<二>内容概述:Linux目录结构查看及检索文件备份及恢复文档vi文本编辑器一,Linux目录结构:树形目录结构(自顶而下)常见的子目录及作用:a./root:系统管理员root的宿主目录b./home:普通用户的宿主目录c./boot:系统内核/启动文件d./dev:设备文件e./etc:配置文件f./bin:所有用户可执行的命令g./sbin:管理员可执行的管理命令h./usr:应用程序i./var:日志文件(俗称可变长文件目录)j./proc :硬件配置信息k. /

Linux 目录详解 树状目录结构图

1.树状目录结构图 2./目录 目录 描述 / 第一层次结构的根.整个文件系统层次结构的根目录. /bin/ 需要在单用户模式可用的必要命令(可执行文件):面向所有用户,例如:cat.ls.cp,和/usr/bin类似. /boot/ 引导程序文件,例如:kernel.initrd:时常是一个单独的分区[6] /dev/ 必要设备, 例如:, /dev/null. /etc/ 特定主机,系统范围内的配置文件. 关于这个名称目前有争议.在贝尔实验室关于UNIX实现文档的早期版本中,/etc 被称为

Linux信号详解

Linux信号详解 一 信号的种类 可靠信号与不可靠信号, 实时信号与非实时信号 可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号 不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于 SIGRTMIN的都是非可靠信号. 非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信 号都是可靠信号, 表现在信号支持排队, 不会丢失, 发多少次, 就可以收到多少次. 信号值 位于 [SIGRTM