且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Grub&initrd&initramfs详解

更新时间:2022-09-25 22:53:48

1
2
3
4
5
6
7
8
9
10
一、GRUB(Boot loader)
二、Grub命令行
三、Grub加密
四、进入单用户模式
五、Grub损坏,修复
六、救援模式
七、内核模块获取
八、ramdisk和initrd
九、内核信息输出的伪fs
十、initramfs和initrd的区别

一、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命令行窗=====================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
一、菜单命令 
菜单命令只能用于grub配置文件的全局配置部分,不能用在grub命令行交互界面,菜单命令在配置文件中应放在其它命令之前。 
1、default  //设置默认启动的菜单项 
2、fallback  //设置启动某菜单项失败后反回的菜单项 
3、hiddenmenu //隐藏菜单界面 
4、timeout //设置菜单自动启动的延时时间 
5、title  //开始一个菜单项 
二、常规命令 
常规命令可以应该于配置文件和grub命令行交互界面,可使用的常规命令有 
1、bootp //通过bootp初始化网络设备 
2、color //设置菜单界面的颜色 
3、device //指定设备文件作为驱动器 
4、dhcp //通过DHCP初始化网络设备 
5、hide  //隐藏某分区 
6、ifconfig //手工配置网络设备 
7、pager //改变内部页程序的状态 
8、partnew //新建一个主分区 
9、parttype //改变分区的类型 
10、password 为菜单界面设置口令 
11、rarp //通过RARP初始化网络设置 
12、serial //设置串口设备 
13、setkey //设置键盘映射 
14、splashimage //设置GRUB启动时的背景图片文件 
15、termainal //选择终端类型  
16、tftpserver //指定TFTP服务器 
17、unhide //还原某隐藏分区 
三、命令行和菜单项命令 
命令行和菜单项命令可应该于GRUB配置文件的菜单项设置中,也可以用在GRUB命令交互界面。 
1、bolcklist //显示某文件所在分区位置(block list notation) 
2、boot //启动操作系统 
3、cat //显示文件内容  
4、chainloader //把启动控制权软交给另外的启动引导器 
5、cmp //比较两个文件 
6、configfile //加载已存在的GRUB配置文件 
7、debug //设置为debug模式 
8、displayapm //显示APM BIOS信息 
9、displaymem //显示内存配置 
10、embed //嵌入Stage 1.5文件 
11、find //查找包括某文件的所有设备 
12、fstest //测试文件系统 
13、geometry //显示某驱动器的物理信息 
14、halt //停止计算机运行(软件关机) 
15、help //显示GRUB的命令帮助信息 
16、impsprobe //查询对称多处理器(SMP)的信息 
17、initrd //加载initrd文件 
18、install //安装GRUB 
19、ioprobe //查询某驱动器的输入输出(I/O)端口 
20、kernel //引导操作系统内核  
21、lock //锁定某GRUB导菜单项,使其输入密码后才可启动 
22、makeactive //激活某主分区 
23、map //虚拟映射某驱动器 
24、md5crypt //使用MD5加密口令 
25、module //加载模块 
26、modulenounzip //加载模块不进行解压 
27、pause //暂停并等待按键 
28、quit //退出GRUB 
29、reboot //重新启动计算机 
30、read //读取内存中的内容 
31、root //设置GRUB的root设备 
32、rootnoverify //设备GRUB的root设备但不装载文件系统 
33、savedefault //保存当前的启动菜单项为默认启动 
34、setup //自动安装GRUB 
35、testload //从文件系统中测试读取某文件 
36、testvbe //测试VESA BIOS EXTENSION 
37、uppermem //强制设置主机上位内存的大小 
38、vbeprobe //查询VESA BIOS EXTENSION信息    
===============================================


三、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系统
        硬盘:新加硬盘-->分区-->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" > 
                    文件系统命令(cat和echo)
                    查看:cat /proc/sys/PATH/TO/FILE
                    设定:echo "VALUE" > /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 > /proc/sys/vm/drop_caches    //清空缓存
            
    /sys:    
        echo 1 > /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,如需转载请自行联系原作者