RamDisk(Initrd)小结:html
名称:
initrd -- boot loader initialized RAM disk,就是由启动加载器进行初始化的RAM DISK;
描述:
/dev/initrd这个特殊文件是一个只读的块设备文件。/dev/initrd设备文件是一个在内核被启动以前由启动加载器进行初始化的RAM disk。
随后,内核利用/dev/initrd设备文件的内容进行两个阶段的(系统)自举。
boot loader 会将存储介质中的内核文件及 initrd文件(initrd会解压缩后再释放)加载到内存,而后内核进行初始化,内核启动时会在访问真正的根文件系统前先访问该内存中的 initrd 文件系统。
在(系统)自举的第一个阶段,挂载/dev/initrd中精简的根文件系统。这个根文件系统包含必备的liunx目录和程序,甚至也有一个init脚本(或程序linuxrc;在RedHat5中是init),必需的一些驱动模块;而后执行init脚本,完成加载驱动及模块的任务;脚本执行后期,会借助刚才加载的驱动及模块挂载上真正的根文件系统,而且切换根文件系统从精简的initrd根文件系统到根文件系统;node
在第二个阶段,根文件系统已经被挂载,系统会运行真正根文件系统中的/sbin/init继续完成系统其它的初始化工做;
(在桌面或服务器 Linux 系统中,initrd 是一个临时的文件系统。其生存周期很短,只会用做到真实文件系统的一个桥梁。在不少没有存储设备的嵌入式系统中,initrd 是永久的根文件系统;)
补充:
在真正的运行环境中,对内核需求是短小而精悍,不该该静态包含进太多驱动模块;因此其采用模块化设计,大部分设备模块是在须要使用时才加载相应驱动的。可是Linux内核启动最后一步,须要挂载根文件系统,而后运行/sbin/init建立init内核线程来引导初始化系统。而根文件系统可能在硬盘、磁盘阵列、nfs、flash上,同时根文件系统的格式也是五花八门。此时,要是实在不想包含这么多驱动到内核的话,可使用initrd做为一个过渡。另外,内核在编译的时候,是能够选择是否支持initrd,若是使用initrd,则系统自居是两段式的。若是不使用initrd,须要编译进去各类驱动(没作过相关实验,不发表看法:网上编译内核教程一堆堆的,可是貌似不少问题,你要感受那是理所固然的...就引导了o(╯□╰)o);而且若是换新的文件系统,可是刚好内核又没有更换,这是胡恐怕只有从新编译内核了而不是仅仅的只mkinitrd就完事大吉了。linux
下面是2.6内核对模块选择路径:
Linux Kernel Configuration
-> Device Drivers
->Block devices
->RAM block device support
->Default number of RAM disks (设定Ramdisk的个数,默认是16)
->Default RAM disk size (kbytes) (设定Ramdisk的大小,默认4096k)
Linux Kernel Configuration
->General setup
->Inital RAM filesystem and RAM disk(initramfs/initrd) support
服务器
若是对Ramdisk的支持已经编译进内核,咱们就可使用它了,固然对于我RedHat5.4来讲默认是使用该项的;
RamDisk文件系统中脚本init做用:
init文件是RamDisk的核心文件,其中的其余文件都是为该脚本服务的;临时Mount虚拟root,并自动运行该文件系统中的init脚本 文件 ,这个文件将实际加载真实物理root所须要的设备驱动模块(如raid或scsi驱动),和文件系统驱动模块,全部必需的驱动调入后,这个脚本将物理root Mount上,并卸下Ramdisk虚拟根文件系统,此时根文件系统就已经为真实根文件系统了,而后系统进入正常引导,加载各service ,启动应用程序;app
init脚本的格式:ide
- #!/bin/nash
- mount -t proc /proc /proc
- setquiet
- echo Mounting proc filesystem
- echo Mounting sysfs filesystem
- mount -t sysfs /sys /sys
- echo Creating /dev
- mount -o mode=0755 -t tmpfs /dev /dev
- mkdir /dev/pts
- mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts
- mkdir /dev/shm
- mkdir /dev/mapper
- echo Creating initial device nodes
- mknod /dev/null c 1 3
- mknod /dev/zero c 1 5
- mknod /dev/systty c 4 0
- mknod /dev/tty c 5 0
- mknod /dev/console c 5 1
- mknod /dev/ptmx c 5 2
- mknod /dev/rtc c 10 135
- mknod /dev/tty0 c 4 0
- mknod /dev/tty1 c 4 1
- mknod /dev/tty2 c 4 2
- mknod /dev/tty3 c 4 3
- mknod /dev/tty4 c 4 4
- mknod /dev/tty5 c 4 5
- mknod /dev/tty6 c 4 6
- mknod /dev/tty7 c 4 7
- mknod /dev/tty8 c 4 8
- mknod /dev/tty9 c 4 9
- mknod /dev/tty10 c 4 10
- mknod /dev/tty11 c 4 11
- mknod /dev/tty12 c 4 12
- mknod /dev/ttyS0 c 4 64
- mknod /dev/ttyS1 c 4 65
- mknod /dev/ttyS2 c 4 66
- mknod /dev/ttyS3 c 4 67
- echo Setting up hotplug.
- hotplug
- echo Creating block device nodes.
- mkblkdevs
- echo "Loading uhci-hcd.ko module"
- insmod /lib/uhci-hcd.ko
- echo "Loading ohci-hcd.ko module"
- insmod /lib/ohci-hcd.ko
- echo "Loading ehci-hcd.ko module"
- insmod /lib/ehci-hcd.ko
- mount -t usbfs /proc/bus/usb /proc/bus/usb
- echo "Loading jbd.ko module"
- insmod /lib/jbd.ko
- echo "Loading ext3.ko module"
- insmod /lib/ext3.ko
- echo "Loading scsi_mod.ko module"
- insmod /lib/scsi_mod.ko
- echo "Loading sd_mod.ko module"
- insmod /lib/sd_mod.ko
- echo "Loading scsi_transport_spi.ko module"
- insmod /lib/scsi_transport_spi.ko
- echo "Loading mptbase.ko module"
- insmod /lib/mptbase.ko
- echo "Loading mptscsih.ko module"
- insmod /lib/mptscsih.ko
- echo "Loading mptspi.ko module"
- insmod /lib/mptspi.ko
- echo "Loading dm-mod.ko module"
- insmod /lib/dm-mod.ko
- echo "Loading dm-mirror.ko module"
- insmod /lib/dm-mirror.ko
- echo "Loading dm-zero.ko module"
- insmod /lib/dm-zero.ko
- echo "Loading dm-snapshot.ko module"
- insmod /lib/dm-snapshot.ko
- echo Waiting for driver initialization.
- stabilized --hash --interval 250 /proc/scsi/scsi
- echo Making device-mapper control node
- mkdmnod
- mkblkdevs
- echo Scanning logical volumes
- lvm vgscan --ignorelockingfailure
- echo Activating logical volumes
- lvm vgchange -ay --ignorelockingfailure VolGroup00
- resume /dev/VolGroup00/LogVol01
- echo Creating root device.
- mkrootdev -t ext3 -o defaults,ro /dev/VolGroup00/LogVol00
- echo Mounting root filesystem.
- mount /sysroot
- echo Setting up other filesystems.
- setuproot
- echo Switching to new root and running init.
- switchroot
脚本执行过程分析:
第一行#!/bin/nash是一个redhat本身的微型解释器。只包含精简的命令,能作基本的mount、insmod、mkdev等,主要是为了减少iitrd体积;
mount命令挂载上了initrd释放出来的各类内核文件系统/proc、/sys、/dev到相应的位置;
mknod生成各类设备节点;hotplug开始监听系统总线热插拔的磁盘等uevent事件。mkblkdevs将这些热插拔的磁盘节点建立到/dev下。
接着insmod开始安装usb,block设备,scsi设备,ide设备,device-mapper的设备驱动,随后系统总线就会收到这些事件,mkblkdevs又会把他们的节点建立到/dev下。咱们的硬盘多数是在这个阶段被找到并建立了相应的设备节点。而后是加载启动逻辑卷管理,使咱们的设备能使用逻辑卷名称。这一步能够不要的
而后是加载启动逻辑卷管理,使咱们的设备能使用逻辑卷名称;(该步骤非必要)
(重要)下面mkrootdev:该命令能够建立根文件系统的设备节点;查找内核参数当中的“root=”项;而后解析mkrootdev后面的-t 和-o参数,若是-t是nfs,并且,-o中包含dhcp,那么root的相关信息从dhcp主机取得,若是-o选项不包含dhcp或者-t不是nfs, 则从root=内核参数取真正root文件系统的位置,若是没有root=参数,使用mkrootdev后面的设备做为root设备。若是是-t nfs那么直接添加入口到/etc/fstab文件,包括-t的文件系统类型和-o的选项。若是-t指定的文件系统不是nfs,那么它建立名称为/dev/root的节点,它的Major,Minor设备号使用root=参数的设备号(若是有),或mkrootdev后面的设备的设备号。;它不只可以根据root=/dev/xxx来生成对应的设备节点,还可以在碰到root=LABEL=/ 的状况下探测全部的硬盘分区,以便找到对应着卷标为/的分区。
因此,mkrootdev -t ext3 -o defaults,ro /dev/VolGroup00/LogVol00这行,会将一条入口信息写入内存中的/etc/fstab,如: /dev/root /sysroot ext3 defaults,ro 0 0 ;注意此时设备是/dev/root.而不是/dev/VolGroup00/LogVol00,但他们的设备号是同样的。
紧接着后面的mount /sysroot;就会读取/etc/fstab并加载刚刚mkrootdev写入的这条入口信息所指定的设备,这就是加载/dev/root 到/sysroot下。这时咱们的真正的root才被加载到了系统中。nash在mount时,若是只有一个参数,以它做为root加载点,且它必须是 /sysroot(会同fstab中的作比较)。若是有加载点和设备参数,-t -o必须也被提供,mount丢弃/etc/fstab中的入口的内容,而使用参数提供的信息加载root设备。若如本例,至此/sysroot下是真正物理系统的root分区。/是initrd的内存盘。
setuproot 并不接受任何参数,而以上面的/sysroot做为咱们的root。安装全部的子分区到/sysroot下。也就是创建咱们的根文件系统树,若是咱们的root 不是由单个分区组成的话。这些信息从/sysroot/etc/fstab.sys中读取。若是它不存在,就从initrd的/etc /fstab.sys中读取。若是仍然不存在,就创建默认的文件系统树:
挂载(Bind挂载方式)/proc 到/sysroot/proc ,/sys到/sysroot/sys
最后switchroot卸载/dev,/proc,/sys文件系统,挂载(移动挂载方式)/sysroot到/下面.,而后卸载initrd的/。打开 /dev/console到描述符3,将stdin,stdout,stderr所有定向到3(console),分析内核参数,寻找init=,若是有,以它做为init程序执行,不然,执行默认:搜寻第一个找到的/sbin/init;/etc/init;/bin/init;/bin/sh执行,这就 是全部进程的父进程0
模块化
文章参考:ui
关于Linux-gate.so.1的含义: http://www.linuxidc.com/Linux/2007-07/6221.htm spa
Linux boot process (initrd part):
http://bbs.kylin-linux.com/htm_data/9/1003/209.html
http://www.mike.org.cn/articles/linux-xiangjie-linux-initrd/
拓展参考: http://www.ibm.com/developerworks/cn/linux/l-initrd.html(IBM上面用busybox实现了一个精简的initrd)线程
整理过程,不免出错,但愿共同探讨;