天天看点

Grub&initrd&initramfs详解

<code>一、GRUB(Boot loader)</code>

<code>二、Grub命令行</code>

<code>三、Grub加密</code>

<code>四、进入单用户模式</code>

<code>五、Grub损坏,修复</code>

<code>六、救援模式</code>

<code>七、内核模块获取</code>

<code>八、ramdisk和initrd</code>

<code>九、内核信息输出的伪fs</code>

<code>十、initramfs和initrd的区别</code>

一、GRUB(Boot loader)

    Grub:GRand Unified Bootloader

        Grub 0.x:grub legacy

        Grub 1.x:grub2

    grub legacy:

        stage:mbr

        stage1_5:mbr之后的扇区中,让stage1中的bootloader能识别stage2所在的分区上的fs

            //提供stage2的文件系统所需的驱动

        stage2:磁盘分区之上的,提供选择界面,供用户选择os

            stage2及内核等通常放置于一个基本磁盘分区

    配置文件:/boot/grub/grub.conf链接文件:/etc/grub.conf

    功用:

    1.提供菜单,并提供交互式接口

        e:编辑模式,用于编辑菜单

        c:命令模式,交互式接口

            root (hd0,0)  //CentOS7的

            kernel /vmlinuz-x86_64 ro root=/dev/mapper/vg0-root

            initrd /intramfs*.img

            boot //开机即可

        CentOS7:

            insmod gzio

            insmod part_msdos

            insmod xfs

            set root=(hd0,msdos1)/Centos7如何使用

            linux16 /vmlinuz-3.*.x86_64 root=/dev/mapper/centos-root ro //linux取代centos 6的kernel

                        //注意vmlinuz前面的 / 不能去掉

            initrd16 /initramfs-*.img

            boot //重新启动即可

        注意:linux16 root=/dev/mapper/centos-root 必须指定,否则会出错

            指定root文件路径

    2.加载用户选择的内核或OS

        允许传递参数给内核

        可隐蔽此菜单

    3.为菜单提供了保护机制

        为编辑菜单进行认证

        为启用内核或os系统进行认证

二、Grub命令行窗口

    help:获取帮助列表

    help root //查看root的帮助信息,设置grub的根设备

            //此时os尚未启动,但是grub有自己的fs驱动可以直接访问

            //但是grub的fs驱动是有限的,不可能太大,因此不能识别软fs,raid,lvm等

    help KEYWORD:详细帮助信息

            //boot是可以不单独分区的,根fs如果使用基本分区的话

            //但是根fs,必须能够被grub识别才可以

            //如果root直接指定根所在分区,boot文件也放在跟分区中也是可以的

            //这时grub root需要指定根所在分区,并能够识别该分区

    如何标识设备:

        (hd#,#) //第#块磁盘的,第#个分区

        (hd0,0) //

    find (hd#,#)/vmlinuz-   

    root DEVICE //设置根设备 root (hd0,0)

    kernel /PATH/TO/KERNEL_FILE  //vmlinuz:z标识压缩存放,设定本次启动时用到的内核文件

        //额外内核支持的很多参数

        init=/paht/to/init

        selinux=0

        root=/dev/mapper/centos-root //根文件系统所在

        ro 只读

        quiet 静默模式    

    initrd /PATH/TO/INITRAMFS_FILE //设定为选定的内核提供的额外的文件的ramdisk

    boot :引导启动选定的内核

============grub命令行窗=====================

<code>一、菜单命令 </code>

<code>菜单命令只能用于grub配置文件的全局配置部分,不能用在grub命令行交互界面,菜单命令在配置文件中应放在其它命令之前。 </code>

<code>1、</code><code>default</code>  <code>//设置默认启动的菜单项 </code>

<code>2、fallback  </code><code>//设置启动某菜单项失败后反回的菜单项 </code>

<code>3、hiddenmenu </code><code>//隐藏菜单界面 </code>

<code>4、timeout </code><code>//设置菜单自动启动的延时时间 </code>

<code>5、title  </code><code>//开始一个菜单项 </code>

<code>二、常规命令 </code>

<code>常规命令可以应该于配置文件和grub命令行交互界面,可使用的常规命令有 </code>

<code>1、bootp </code><code>//通过bootp初始化网络设备 </code>

<code>2、color </code><code>//设置菜单界面的颜色 </code>

<code>3、device </code><code>//指定设备文件作为驱动器 </code>

<code>4、dhcp </code><code>//通过DHCP初始化网络设备 </code>

<code>5、hide  </code><code>//隐藏某分区 </code>

<code>6、ifconfig </code><code>//手工配置网络设备 </code>

<code>7、pager </code><code>//改变内部页程序的状态 </code>

<code>8、partnew </code><code>//新建一个主分区 </code>

<code>9、parttype </code><code>//改变分区的类型 </code>

<code>10、password 为菜单界面设置口令 </code>

<code>11、rarp </code><code>//通过RARP初始化网络设置 </code>

<code>12、serial </code><code>//设置串口设备 </code>

<code>13、setkey </code><code>//设置键盘映射 </code>

<code>14、splashimage </code><code>//设置GRUB启动时的背景图片文件 </code>

<code>15、termainal </code><code>//选择终端类型  </code>

<code>16、tftpserver </code><code>//指定TFTP服务器 </code>

<code>17、unhide </code><code>//还原某隐藏分区 </code>

<code>三、命令行和菜单项命令 </code>

<code>命令行和菜单项命令可应该于GRUB配置文件的菜单项设置中,也可以用在GRUB命令交互界面。 </code>

<code>1、bolcklist </code><code>//显示某文件所在分区位置(block list notation) </code>

<code>2、boot </code><code>//启动操作系统 </code>

<code>3、cat </code><code>//显示文件内容  </code>

<code>4、chainloader </code><code>//把启动控制权软交给另外的启动引导器 </code>

<code>5、cmp </code><code>//比较两个文件 </code>

<code>6、configfile </code><code>//加载已存在的GRUB配置文件 </code>

<code>7、debug </code><code>//设置为debug模式 </code>

<code>8、displayapm </code><code>//显示APM BIOS信息 </code>

<code>9、displaymem </code><code>//显示内存配置 </code>

<code>10、embed </code><code>//嵌入Stage 1.5文件 </code>

<code>11、find </code><code>//查找包括某文件的所有设备 </code>

<code>12、fstest </code><code>//测试文件系统 </code>

<code>13、geometry </code><code>//显示某驱动器的物理信息 </code>

<code>14、halt </code><code>//停止计算机运行(软件关机) </code>

<code>15、help </code><code>//显示GRUB的命令帮助信息 </code>

<code>16、impsprobe </code><code>//查询对称多处理器(SMP)的信息 </code>

<code>17、initrd </code><code>//加载initrd文件 </code>

<code>18、install </code><code>//安装GRUB </code>

<code>19、ioprobe </code><code>//查询某驱动器的输入输出(I/O)端口 </code>

<code>20、kernel </code><code>//引导操作系统内核  </code>

<code>21、</code><code>lock</code> <code>//锁定某GRUB导菜单项,使其输入密码后才可启动 </code>

<code>22、makeactive </code><code>//激活某主分区 </code>

<code>23、map </code><code>//虚拟映射某驱动器 </code>

<code>24、md5crypt </code><code>//使用MD5加密口令 </code>

<code>25、module </code><code>//加载模块 </code>

<code>26、modulenounzip </code><code>//加载模块不进行解压 </code>

<code>27、pause </code><code>//暂停并等待按键 </code>

<code>28、quit </code><code>//退出GRUB </code>

<code>29、reboot </code><code>//重新启动计算机 </code>

<code>30、read </code><code>//读取内存中的内容 </code>

<code>31、root </code><code>//设置GRUB的root设备 </code>

<code>32、rootnoverify </code><code>//设备GRUB的root设备但不装载文件系统 </code>

<code>33、savedefault </code><code>//保存当前的启动菜单项为默认启动 </code>

<code>34、setup </code><code>//自动安装GRUB </code>

<code>35、testload </code><code>//从文件系统中测试读取某文件 </code>

<code>36、testvbe </code><code>//测试VESA BIOS EXTENSION </code>

<code>37、uppermem </code><code>//强制设置主机上位内存的大小 </code>

<code>38、vbeprobe </code><code>//查询VESA BIOS EXTENSION信息    </code>

<code>===============================================</code>

三、Grub加密

    /etc/grub/grub.conf :Centos5,6

    配置项:        

        default=# //哪个用来默认启用,菜单项(title)编号从0开始

        timeout=5 //指定菜单选项等待选项的时长

        splashimage=(hd#,#)/PATH/TO/INITRAMFS_FILE //默认启用的界面

        //password [--md5] STRING:菜单编辑认证 //可以不用

        hiddenmenu=[0/1] //隐藏菜单

        title TITLE //定义菜单项“标题”

            root (hd#,#):grub查找stage2及kernel文件所在的设备分区,为grub的“根”

            kernel /PATH/TO/VMLINUZ_FILE [ARG] :启动的内核

            initrd /PATH/TO/INITRAMFS_FS  :内核匹配的ramfs文件

            //password [--md5] STRING:启动选定到的内核或os时进行认证

    加密命令:grub-md5-crypt    

        password --md5 jisdjfidjsifjsdiyeou

        password xiaoxin //可以明文存放,但是不安全

    CentOS7:

        grub2-setpassword

四、进入单用户模式

        1.编辑grub菜单(e命令)

        2.kernel 最后加上 single/1,s/S

        3.在kernel所在行,键入“b”命令 //Cenetos7 ctrl+x

    CentOS7:也是如此,只是仍然需要输入root密码来进入单用户模式            

五、Grub-instll/grub2-install 

grub-install 

    安装grub

        //建议先安装windows后安装linux

        grub-install / grub2-install

    安装新的grub        

        mkdir /mnt/boot

        mount /dev/sdb1 /mnt/boot //sdb是一个新硬盘

        grub-install --root-directory=/mnt /dev/sdb

                //指定root目录/mnt只需指定mnt即可,而不是/mnt/root

        grub将安装在sdb这个硬盘上的mbr中

    新加一个硬盘://当拆了第一个硬盘之后,他就变成了sda

        sdb1:boot

        sdb2:swap

        sdb3:/

    vim /mnt/boot/grub/grub.conf

        default=0

        timeout=5

        title CentOS (EXpress)

            root (hd0,0)

            kernel /vmlinuz ro root=/dev/sda3 selinux=0 init=/bin/bash  //

            initrd /initramfs.img

    cp /boot/vmlinuz*  /mnt/boot/vmlinuz

    cp /boot/initramfs /mnt/boot/initramfs.img

    mkdir /mnt/boot/sysroot ; cd /mnt/boot/sysroot

    mkdir -pv etc bin sbin lib lib64 dev proc sys tmp var usr home mnt media

    ldd /bin/bash //查看bash依赖的库

    cp bash命令

    chroot /mnt/sysroot/   //切换根就可以了

    创建一个新的虚拟机

        然后使用刚才建立的硬盘

    破坏分区表:

        dd if=/dev/zero of=/dev/sda bs=200 count=1 //小于446,分区表不要破坏

        1.grub-install --roo-directory=/   /dev/sda 

        2.grub 命令模式修复

            root (hd0,0) //必须有grub目录,里面的stage1,stage1_5都是存在的

            setup (hd0) //安装第一阶段到第一块硬盘上

            exit 

六、救援模式    

    借助于光盘实现

    linux rescue //命令行键入,进入救援模式

    默认会挂载原有的os到/mnt/sysimage上

    chroot /mnt/sysimage

    grub-install --root-directory=/  /dev/sda 

    exit //退出到光盘镜像

    reboot即可

练习:

    1.新加硬盘,提供直接单独运行bash系统

        硬盘:新加硬盘--&gt;分区--&gt;mount--

            sdb1:/mnt/boot: //sdb1挂载地        :: /mnt/boot/[vmliuz,intramfs,grub{grub.conf}]    //切换目录

            sdb3:/mnt/sysroot: //sdb3挂在地      ::bin[bash],etc,sbin..                            //真实的根

            grub-install: /mnt

            grub文件

                kernel ...  init=/bin/bash

        注:创建grub的那台主机,需要关机,才可以,否则kernel panic

    2.破坏本机bootloader,grub stage1,在救援模式下修复

    3.为grub设置保护功能

    ldd命令:输出共享库依赖

        ldd /bin/ls

        //第一个没有定义任何的,是真正定义调用其他库文件的入口

        左侧:库文件的名称

        右侧:库文件的路径

    ldd /bin/ls | grep -o "/lib.*.so.[[:digit:]]"

    ldd /bin/ls | grep -o "/lib.*.so.[^[:space:]]*" //非空白字符出现一次

七、内核模块获取

    uname命令:显示系统信息

    uname -s //kernel-name

        -r release

        -m machine,x86_64,i386

        -v 编译版本

        -n hostname

    lsmod //查看模块信息

        /proc/modules 

        查看模块状态信息

    modinfo //显示模块的详细信息

        modinfo ext4

        modinfo //默认查找路径是/lib/modules/VERSION-release/

        -k kerel //多内核,指定其他kernel

        -F field //只显示指定字段的value值

            modinfo -F filename btrfs

        -n //显示文件路径

    modprobe:添加和删除模块

        modprobe -r //删除

        modprobe mou_name //装载

        -C //指定配置文件,默认配置文件/etc/modprobe.d/*.conf

        注意:正在使用的模块千万不要卸载

    depmode命令

        生成依赖关系,modules.dep和map files

        内核模块依赖关系文件及系统信息映射文件的生成工具

    模块装载和卸载的另一组命令

        insmod:

            insmod [filename] [module options...]

                filename:模块文件的文件路径

                insmod `modinfo -n btrfs` //存在依赖

                modprobe会自动解决依赖关系,而insmod需要手动解决    

                modinfo btrfs //会显示依赖关系

        rmmod :

            rmmod btrfs //不需要完整路径

八、ramdisk和initrd

    1.mkinitrd ,Centos5,6

    2.dracut,Centos6,7

    mkinitrd [options] [initrd-img] kernel-versio

    //为当前正在使用中的内核重新制作ramdisk文件

    mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)

    --with=[module] //手动加载其他模块到initrd文件中

    --preload //initramfs所听的模块,需要预先加载的模块

    dracut 命令

        //更底层,更功能更强悍

        dracut /boot/initramfs-$(uname -r).img $(uname -r)

    mkinitrd -v -f myinitrd.img $(uname -r)

        -f指定要创建的映像文件,指定内核版本

来自: http://man.linuxde.net/mkinitrd

        内核模块支持动态装载和卸载

    ramdisk:

        辅助性文件,并非必须,取决于内核是否能够直接驱动rootfs所在的设备

        目标设备驱动:例如

                目标设备驱动:scsi设备驱动

                逻辑设备驱动:逻辑设备驱动

                文件系统:例如xfs文件系统

        ramdisk是一个简装版的rootfs

九、内核信息输出的伪fs

    /proc :内核状态及统计信息的输出接口;同时,还提供了一个配置接口,/proc/sys

        参数:

            只读:信息输出,数字标识的进程目录

            可写:可接受用户指定的一个新value

                (1)sysctl命令

                    专用于查看和设置/proc/sys目录中的值的

                    sysctl -a //查看所有可供调的值

                    sysctl net.ipv4.ip_forward

                    sysctl -w net.ipv4.ip_forward=1 //赋值,临时生效

                    sysctl kernel.hostname=www.test.com //-w可带可不带

                    -w :仅仅是写入,默认不带

                    -p:重读配置文件

                (2)echo "value" &gt; 

                    文件系统命令(cat和echo)

                    查看:cat /proc/sys/PATH/TO/FILE

                    设定:echo "VALUE" &gt; /proc/sys/PATH/TO/FILE

        注意:上述两种方式的设定,仅当前运行内核有效

        配置文件 

            /etc/sysctl.conf :CentOS6

            /etc/sysctl.d/*.conf :CentOS7

                net.ipv4.ip_forward = 1

            sysctl -p /etc/sysctl.d/a.conf //重读配置文件,立即生效

            注意:linux的地址是系统的不是网卡的,

                //一个ip能够达到该主机,则该主机上的所有网卡的地址都可以ping到,即使不在同一个网段

            echo 3 &gt; /proc/sys/vm/drop_caches    //清空缓存

    /sys:    

        echo 1 &gt; /proc/sys/net/ipv4/icmp_echo_ignore_all //忽略别人的ping操作

        输出内核识别出的各硬件设备的相关属性信息,也有内核对硬件特性可设置参数

        因此可通过此目录修改硬件特性

        udev //linux2.6之后,按需创建设备文件

            //读取/sys目录下硬件设备信息,按需为各硬件设备,创建设备文件

            //udev是用户空间程序,正是/sys的存在,使他能够读取设备信息,根据设备信息,创建设备文件

            //专用工具:udevadm,hotplug

            //有的是内核自己创建的,例如/dev/sda,结合udev实现

            udev为设备创建设备文件时,会去读其实现定义好的规则文件,一般在/etc/udev/rules.d/目录下,以及/usr/lib/udev/rules.d/目录下,以及/usr/lib/udev/rules.d目录下

    问题:克隆的虚拟机只有个eth1,就是没有eth0

        1./etc/udev/rules.d/70-persistent-net.rules

        2.修改网卡的配置文件

        3.卸载网卡模块,然后重新装载

十、initramfs和initrd的区别

boot loader装入kernel, 然后kernel需要执行/sbin/init, 读取 这个文件就必须先mount根文件系统, 早期是通过启动时的root=参数告诉内核根文件系统在哪个设备上,  随着硬件和技术的发展,现在根文件系统可能位于一个网络存储如NFS上, 可能由于RAID而

散布于多个设备上, 可能位于一个加密设备上需要提供用户名和密码,这时root=参数就显得不够了. 为了应付这种局面, 先后出现两种机制来作为boot loader装载kernel到真正的/sbin/init执行这个启动 过程的桥梁: initrd和initramfs, 两者有类似的地方, 比如都是

由内核执行其上的某个程序(initrd是/linuxrc, initramfs是/init),由这个程序决定加载什么驱动以及如何装载根文件系统.

initrd:

 ram disk是一个基于ram的块设备,因此它占据了一块固定的内存, 而且事先要使用特定的工具比如mke2fs格式化,还需要一个文件系统 驱动来读写其上的文件。

 如果这个disk上的空间没有用完,这些未用的内存就浪费掉了,并且 这个disk的空间固定导致容量有限,要想装入更多的文件就需要重新格式化。

 由于Linux的块设备缓冲特性, ram disk上的数据被拷贝到page cache (对于文件数据)和dentry cache(对于目录项), 这个也导致内存浪费.

initramfs:

最初的想法是Linus提出的: 把cache当作文件系统装载. 他在一个叫ramfs的cache实现上加了一层很薄的封装, 其它内核开发人员编写了一个改进版tmpfs, 这个文件系统上的数据可以写出到交换分区, 而且可以设定一个tmpfs装载点的最大尺寸以免耗尽内存. initramfs就是

tmpfs的一个应用.

优点:

     (1)tmpfs随着其中数据的增减自动增减容量.

     (2)在tmpfs和page cache/dentry cache之间没有重复数据.

     (3)tmpfs重复利用了Linux caching的代码, 因此几乎没有增加内核尺寸, 而caching的代码已经经过良好测试, 所以tmpfs的代码质量也有保证.

     (4)不需要额外的文件系统驱动.

另外, initrd机制被设计为旧的"root="机制的前端, 而非其替代物,它假设真正的根设备是一个块设备, 而且也假设了自己不是真正的根设备,这样不便将NFS等作为根文件系统, 最后/linuxrc不是以PID=1执行的, 因为1这个进程ID是给/sbin/init保留的. initrd机制找到真正的根设备后将

其设备号写入/proc/sys/kernel/real-root-dev, 然后控制转移到内核由其装载根文件系统并启动/sbin/init.

initramfs则去掉了上述假设, 而且/init以PID=1执行, 由init装载根文件系统并用exec转到真正的/sbin/init, 这样也导致一个更为干净漂亮的设计.

本文转自MT_IT51CTO博客,原文链接:http://blog.51cto.com/hmtk520/1978582,如需转载请自行联系原作者

继续阅读