1、linux系统启动流程:
post--->根据主板上ROM固件中的系统设置、判断从哪个设备启动--->读取设备的第一扇区的前512字节(MBR),判断用什么bootloader引导系统到内存中--->启动内核程序,有可能会借助于ramdisk--->将内核装载在内存中,建立临时根文件系统(rootfs),完成根系统切换--->启动第一个用户进程init(pid1:/sbin/init、/etc/inittab:设定默认运行级别、etc/init/*.conf:init的配置文件、初始化脚本参数及启动对应级别下的服务)--->启动终端
2、GRUB(bootloader):grand unified bootloader
grub0.x:grub legacy(centos5/6)
grub1.x:grub2
3、grub legacy:此版本的grub分为三个阶段
stage1:引导安装在MBR中的引导程序(bootloader)
stage1_5:MBR之后的扇区,让stage1中的bootloader能识别stage2所在分区上的文件系统
stage2:存放在磁盘上的grub(存放位置:/boot/grub),grub的配置文件:/boot/grub/grub.conf,在etc目录下有此文件的连接文件:/etc/grub.conf,如下:
[root@localhost ~]# ll /etc/grub.conf
lrwxrwxrwx. 1 root root 22 Dec 31 20:14 /etc/grub.conf -> ../boot/grub/grub.conf
[root@localhost ~]#
注意:stage2阶段及内核通常放置于同一个磁盘分区。
grub.conf的配置示例: [root@localhost boot]# cat 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 have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-358.el6.x86_64.img [root@localhost boot]# |
4、stage2 grub的作用:
①、提供菜单,并提供交互命令接口
e:编辑模式,用于编辑菜单
c:命令模式,交互式接口
②、加载用户选择的内核或操作系统
允许传递参数给内核
可隐藏此菜单
③、为grub菜单提供了保护机制
为编辑菜单进行认证
为启动内核或操作系统进行认证
5、grub根介绍:
grub一般放在的目录下/boot/grub,那么/boot这个目录是否单独分区就直接决定了grub所在根(/)的位置,
如果一块磁盘上分了两个区a和b,分区a单独给boot用(即存在grub、vmlinuz),分区b单独给根(/)用,那么/boot/grub的根就是磁盘分区a,此时grub的根即为分区a;
如果一块磁盘上就分了一块区,并将grub、vmlinuz放置于/boot下,那么此时grub的根为/boot,
boot被做成单独的简单分区,而根(/)被放在逻辑卷中,即boot可以不使用逻辑卷,可以是单独分区,centos5/6默认是将根(/)放在逻辑分区上的。
注意:grub不能访问软raid、逻辑卷等复杂操作。
6、grub识别设备的方法实现:
(hd#,N)
hd:hardware disk,硬盘
#:第#块磁盘,用数字表示,从0开始编号
N:硬盘的第N个分区,用数字表示,从0开始编号
如:(hd0,0):表示第一块磁盘的第一个分区,注意“()”括号必须写,固定格式。
7、grub的命令行接口
help:获取命令列表
help KEYWORD:获取特定命令的使用帮助
find:搜索磁盘上的文件;格式:find(hd#,N)/PATH/TOSOMEFILE
如:find(hd0,0)/vmlinuz-2.6.32-504.el6.x86_64
root (hd#,N):设定(hd#,N)为grub的根,即设置哪块磁盘哪个分区为根,此时可以用find直接去查找文件,如:find /vmlinuz-2.6.32-504.el6.x86_64
kernel /PATH/TO/SOMEFILE:设定本次启动时用到的内核文件在哪里,内核文件通常命名为linuz,z表示压缩;
kernel除了指定内核文件位置之外,还可以添加许多内核支持使用的命令参数,如:init=/bin/init,selinux=0等等
initrd /PATH/TO/SOMEFILE:用来指ramdisk文件在哪里,即设定为选定的内核提供额外文件的ramdisk,需要注意的是:ramdisk的版本号与内核的版本号必须完全匹配
boot:引导启动选定的内核
grub.conf的配置示例: [root@localhost boot]# cat 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 have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 //启动的默认菜单项,即title的编号,默认从0开始编号,0、1、2、3.... timeout=5 //菜单项默认显示时间 splashimage=(hd0,0)/grub/splash.xpm.gz //grub菜单的背景图片,640*480的14位图 hiddenmenu //隐藏菜单 password [--md5] 12345678 //定义编辑菜单的密码认证,--MD5可选,不过不用md5加密直接写明文密码即可 title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64) //定义菜单项,即开机显示的菜单选项 root (hd0,0) //设定grub根所在位置 kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet ///vmlinuz-2.6.32-358.el6.x86_64设定启动的内核文件,root=/dev/mapper/VolGroup-lv_root设定真正的根文件系统位置(设备文件的位置) initrd /initramfs-2.6.32-358.el6.x86_64.img //设定与内核匹配的ramdisk文件 password [--md5] 12345678 //启动选定内核或操作系统是的密码认证 [root@localhost boot]# 注意:可以用grub-md5-crypt命令生成密码密码 示例: [root@localhost ~]# grub-md5-crypt Password: Retype password: $1$YQoXf/$JhHIskqgm8tlc7YdIQJnx. [root@localhost ~]# |
8、进入单用户模式:
①、编辑grub菜单(选定要编辑的title,然后使用“e”命令)
②、在选定的kernel后附加:数字1或s或S或single,这几个参数都可以实现进入单用户模式。
③、在kernel所在行键入“b”键,进入单用户
grub配置文件丢了,会显示grub提示符,此时只需要启动系统,然后编辑一个grub
如果grub文件坏了,如grub stage1坏了,只要bootloader坏了,磁盘上所有系统都将无法引导,此时只能修复bootloader(如:重新安装grub),如进入救援模式或把硬盘拆下来放到其他系统上使用grub-install命令重新安装grub文件。
重新安装grub的命令:grub-install
9、grub-install:重新安装grub(这是一个完整安装,会安装三个不同阶段的文件)
场景一:主机有两块硬盘,想给第二块磁盘安装grub
场景二:主机上没有grub,但是可以启动(可以借助光盘上的grub引导系统,开始时只要有grub菜单或者能进入grub提示符,就可以指定grub根文件在光盘上、内核文件在光盘上,内核文件在哪没有关系;可以从光盘、u盘启动系统)
场景三:windows和linux双系统共存,建议先安装windows再安装linux,因为windows的引导文件不能引导linux,如果先安装linux再安装windows的话,那么windows的bootloader会覆盖掉linux的
安装示例步骤:
①、在系统上安装一块新的硬盘 [root@localhost ~]# fdisk -l /dev/[sh]d[a-z] Disk /dev/sda: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x0005cab3 Device Boot Start End Blocks Id System /dev/sda1 * 1 64 512000 83 Linux Partition 1 does not end on cylinder boundary. /dev/sda2 64 1306 9972736 8e Linux LVM Disk /dev/sdb: 2147 MB, 2147483648 bytes //sdb上没有分区,需要先创建一个分区用来作为boot分区,如步骤② 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 [root@localhost ~]# ②、创建分区: #fdisk /dev/sdb //可以创建多个分区,用p命令显示如下 Device Boot Start End Blocks Id System /dev/sdb1 1 100 802226 83 Linux /dev/sdb2 101 126 208845 82 Linux swap / Solaris /dev/sdb3 127 261 1084387+ 83 Linux [root@localhost ~]# partx -a /dev/sdb //重新识别分区 [root@localhost ~]# cat /proc/partitions //查看分区信息 major minor #blocks name 8 0 10485760 sda 8 1 512000 sda1 8 2 9972736 sda2 8 16 2097152 sdb 8 17 802226 sdb1 8 18 208845 sdb2 8 19 1084387 sdb3 253 0 7938048 dm-0 253 1 2031616 dm-1 [root@localhost ~]# [root@localhost ~]# mke2fs -t ext4 /dev/sdb1 //格式化分区为ext4类型的文件系统 [root@localhost ~]# mke2fs -t ext4 /dev/sdb3 [root@localhost ~]# mkswap /dev/sdb2 ③、创建boot目录,并将sdb1挂载到root目录:grub比较较真,需要认到boot目录,在其下放置grub文件。 [root@localhost ~]# mkdir /mnt/boot [root@localhost ~]# mount /dev/sdb1 /mnt/boot/ [root@localhost ~]# ls /mnt/boot/ lost+found [root@localhost ~]# [root@localhost ~]# grub-install --root-directory=/mnt /dev/sdb //将grub安装到磁盘sdb上,由于sdb1要成为grub的根,因此--root-directory=/mnt设置grub的根为mnt,注意,不要写成/mnt/boot,因为grub会自己找boot目录 Probing devices to guess BIOS drives. This may take a long time. Installation finished. No error reported. This is the contents of the device map /mnt/boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (fd0)/dev/fd0 (hd0)/dev/sda (hd1)/dev/sdb [root@localhost ~]# [root@localhost ~]# ls /mnt/boot/ //验证grub会自动找boot并在其下有个grub目录 grub lost+found [root@localhost ~]# [root@localhost ~]# ls /mnt/boot/grub/ device.map ffs_stage1_5 minix_stage1_5 stage2 xfs_stage1_5 e2fs_stage1_5 iso9660_stage1_5 reiserfs_stage1_5 ufs2_stage1_5 fat_stage1_5 jfs_stage1_5 stage1 vstafs_stage1_5 //stage1已经安装在sdb1这块磁盘上了 //注意此处没有grub配置文件,grub配置文件只能自己写。写这个文件需要有内核文件和initrd文件,由于此处没有,只能去拷贝放在此目录下 [root@localhost ~]# [root@localhost ~]# cp /boot/vmlinuz-2.6.32-358.el6.x86_64 /mnt/boot/ //为了生成grub配置文件必须要有的 [root@localhost ~]# cp /boot/initramfs-2.6.32-358.el6.x86_64.img /mnt/boot/ //为了生成grub配置文件必须要有的 [root@localhost ~]# vi /mnt/boot/grub.conf //编辑一个grub配置文件 default=0 timeout=5 title centos6 (custom) root (hd0,0) kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=/dev/sda3 init=/bin/bash //第一个init程序不再是/sbin/init程序 而是/bin/bash作为第一个应用程序 initrd /initramfs-2.6.32-358.el6.x86_64.img [root@localhost ~]# [root@localhost ~]# mkdir /mnt/sysroot //创建一个临时根文件目录名 [root@localhost ~]# mount /dev/sdb3 /mnt/sysroot/ //sdb3作为临时根 [root@localhost ~]# cd /mnt/sysroot/ [root@localhost sysroot]# mkdir -pv etc bin lib sbin lib64 dev proc sys tmp var usr var home root mnt media //创建根下应有的目录
[root@localhost sysroot]# cp /bin/bash /mnt/sysroot/bin/ //复制一个bash,做为系统启动后的测试用 [root@localhost sysroot]# ldd /bin/bash //查看程序所依赖的库文件有哪些 linux-vdso.so.1 => (0x00007fff7188d000) //库文件访问入口 libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007ff09692f000) libdl.so.2 => /lib64/libdl.so.2 (0x00007ff09672b000) libc.so.6 => /lib64/libc.so.6 (0x00007ff096397000) /lib64/ld-linux-x86-64.so.2 (0x00007ff096b55000) [root@localhost sysroot]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/ //复制库文件到相应的目录下,模仿此块硬盘启动的bash程序 [root@localhost sysroot]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64/ [root@localhost sysroot]# cp /lib64/libc.so.6 /mnt/sysroot/lib64/ [root@localhost sysroot]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/ [root@localhost sysroot]# [root@localhost sysroot]# chroot /mnt/sysroot/ //测试临时根文件系统是否可用 bash-4.1# //由于只复制了一个bash程序,所以此处显示如此 bash-4.1# ls //由于只复制了一个bash程序,所以此处显示如此 bash: ls: command not found bash-4.1# exit //bash内置命令 exit [root@localhost sysroot]# [root@localhost boot]# sync //同步到磁盘 至此,配置完成。 验证:将第二块磁盘放在到一个新系统中,做为唯一一块盘看看是否可行 selinux=0 |
10、安装本机grub(grub坏掉了,但是没有重启)(注意:bootloader在grub的第一阶段,grub的第一阶段放置于mbr上,如果grub第一阶段文件坏了,就看到不到引导菜单)
方法一:如果有备份:
[root@localhost ~]# dd if=/dev/sda of=/root/mbr.bak count=1 bs=512 //备份mbr
[root@localhost ~]# dd if=/dev/zero of=/dev/sda bs=200 count=1 //破坏mbr,将前200字节用“0”来填充
[root@localhost ~]# grub-install --root-directory=/dev/sda //安装grub修复。
修复完成,可以重启验证
注意:此方法不要求grub下有必要的文件(stage1、stage1_5、stage2)
方法二:
[root@centos6 ~]# grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
grub> root (hd0,0) //指定grub所在的根目录
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0) //安装grub的第一阶段至hd0中;setup用来安装grub的第一阶段,hd0用来指定硬盘
setup (hd0)
Checking if "/boot/grub/stage1" exists... no
Checking if "/grub/stage1" exists... yes
Checking if "/grub/stage2" exists... yes
Checking if "/grub/e2fs_stage1_5" exists... yes
Running "embed /grub/e2fs_stage1_5 (hd0)"... 27 sectors are embedded.
succeeded
Running "install /grub/stage1 (hd0) (hd0)1+27 p (hd0,0)/grub/stage2 /grub/grub.conf"... succeeded
Done.
grub> quit
quit
[root@centos6 ~]#
修复完成,可以重启验证
11、紧急救援模式下修复grub
当grub文件被破坏(如mbr中的前446字节坏掉,此时又重新启动了),则现在应该进行紧急救援修复,步骤如下:
①、插入安装镜像光盘
②、重启电脑,选择从光盘引导;菜单项选择“rescue install system”(紧急救援模式,此种模式类似windows的WPE),或者敲入esc键,在命令提示符下输入:linux rescue
③、进入shell后,改变系统根目录至临时根(#chroot /mnt/sysimage),这一步很重要
④、#grub-install --root-directory=/ /dev/sda //安装grub至磁盘sda上,并将根目录设置为“/”它会自动去找/boot。