linux啟動流程grub管理及故障排錯


grub介紹

grub: GRand Unified Bootloader
grub 0.97: grub legacy
grub 2.x: grub2

grub legacy:
stage1: mbr  硬盤的前446個字節為第一個階段mbr,中間64個字節為分區表信息,最后兩個字節為55AA標記位
stage1_5: mbr之后的扇區,讓stage1中的bootloader能識別stage2所在的分區上的文件系統
stage2:磁盤分區(/boot/grub/)

  

grub.conf詳解

[root@zhou grub]# cat 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/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0   #默認從哪個title啟動,一個title代表一個內核
timeout=5  #啟動菜單界面停留的超時時長
splashimage=(hd0,0)/grub/splash.xpm.gz   #xpm.gz是背景圖片 
hiddenmenu
title CentOS 6 (2.6.32-696.el6.x86_64)
	root (hd0,0)    #hd0,0表示第一塊硬盤的第一個分區
	kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=11efc218-6676-4741-94c2-d8aaab0abd1a rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
#  /vmlinuz-2.6.32-696.el6.x86_64  前面的/表白/boot
#ro root 表示操作系統的根;
#rhgb表示圖像,quiet表示安靜,啟動的時候不顯示內核文件啟動的內容
	initrd /initramfs-2.6.32-696.el6.x86_64.img 

 centos6啟動時需第二次掛載根,在系統啟動后需執行第一個啟動腳本/etc/rc.d/rc.sysinit,下圖可以看到一些掛着的信息:

[root@zhou grub]# cat /etc/rc.d/rc.sysinit |grep mount
if [ ! -e /proc/mounts ]; then
	mount -n -t proc /proc /proc
	mount -n -t sysfs /sys /sys >/dev/null 2>&1
	modprobe usbcore >/dev/null 2>&1 && mount -n -t usbfs /proc/bus/usb /proc/bus/usb
	mount -n -t usbfs /proc/bus/usb /proc/bus/usb
#remount /dev/shm to set attributes from fstab #669700
mount -n -o remount /dev/shm >/dev/null 2>&1
#remount /proc to set attributes from fstab #984003
mount -n -o remount /proc >/dev/null 2>&1
if [ -n "$SELINUX_STATE" -a -x /sbin/restorecon ] && __fgrep " /dev " /proc/mounts >/dev/null 2>&1 ; then
    echo $"Unmounting file systems"
    umount -a
    mount -n -o remount,ro /
mount -n /dev/pts >/dev/null 2>&1
	mount_empty() {
			mount -n --bind "$RW_MOUNT$1" "$1"
	mount_dirs() {
			mount -n --bind "$RW_MOUNT$1" "$1"
	mount_files() {
			mount -n --bind "$RW_MOUNT$1" "$1"
	# Common mount options for scratch space regardless of
	mountopts=
	rw_mount_dev=$(blkid -t LABEL="$RW_LABEL" -l -o device)
	# First try to mount scratch storage from /etc/fstab, then any
	# to wipe the scratch storage clean.  If both fail, then mount
	if mount $mountopts "$RW_MOUNT" > /dev/null 2>&1 ; then
	elif [ x$rw_mount_dev != x ] && mount $rw_mount_dev $mountopts "$RW_MOUNT" > /dev/null 2>&1; then
		mount -n -t tmpfs $RW_OPTIONS $mountopts none "$RW_MOUNT"
					mount_empty $path
					mount_files $path
					mount_dirs $path
	# place where they can place minimal amounts of persistent
	# create the bind mounts.  However, until that's all ready this
	# First try to mount persistent data from /etc/fstab, then any
	state_mount_dev=$(blkid -t LABEL="$STATE_LABEL" -l -o device)
	if mount $mountopts $STATE_OPTIONS "$STATE_MOUNT" > /dev/null 2>&1 ; then
	elif [ x$state_mount_dev != x ] && mount $state_mount_dev $mountopts "$STATE_MOUNT" > /dev/null 2>&1;  then
		mount -t nfs $CLIENTSTATE/$HOSTNAME $STATE_MOUNT -o rw,nolock
		mount_state() {
				mount -n --bind "$STATE_MOUNT$1" "$1"
				mount -n --bind "$STATE_MOUNT/$file" "$file"
				mount_state "$path"
				mount_state "$path"
        if mount | grep -q /var/lib/nfs/rpc_pipefs ; then
                mount -t rpc_pipefs sunrpc /var/lib/nfs/rpc_pipefs && service rpcidmapd restart
		echo $"Unmounting file systems"
		umount -a
		mount -n -o remount,ro /
		echo $"Unmounting file systems"
		umount -a
		mount -n -o remount,ro /
remount_needed() {
  state=$(LC_ALL=C awk '/ \/ / && ($3 !~ /rootfs/) { print $4 }' /proc/mounts)
# Remount the root filesystem read-write.
update_boot_stage RCmountfs
if remount_needed ; then
  action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw /
# If relabeling, relabel mount points.
	# Enter mounted filesystems into /etc/mtab
	mount -f /
	mount -f /proc >/dev/null 2>&1
	mount -f /sys >/dev/null 2>&1
	mount -f /dev/pts >/dev/null 2>&1
	mount -f /dev/shm >/dev/null 2>&1
	mount -f /proc/bus/usb >/dev/null 2>&1
# mounted). Contrary to standard usage,
# filesystems are NOT unmounted in single user mode.
# The 'no' applies to all listed filesystem types. See mount(8).
	action $"Mounting local filesystems: " mount -a -t nonfs,nfs4,smbfs,ncpfs,cifs,gfs,gfs2,glusterfs -O no_netdev
	action $"Mounting local filesystems: " mount -a -n -t nonfs,nfs4,smbfs,ncpfs,cifs,gfs,gfs2,glusterfs -O no_netdev
/bin/mount -t binfmt_misc none /proc/sys/fs/binfmt_misc > /dev/null 2>&1

 實驗一:構建第一階段錯誤,使用dd命令清除mbr

 

 

 

mbr清0之后查看,如下圖:

 

 

mbr清零后,reboot的狀態界面,如下圖:

 

 

實驗一:grub第一個階段破壞,修復之:

安裝grub:
方法一: grub-install
安裝grub stage1和stage1_5到/dev/DISK磁盤上,並復制GRUB相關文件
到 DIR/boot目錄下
grub-install --root-directory=DIR /dev/DISK  #DIR代表操作系統的根 /dev/DISK是boot所在的硬盤
方法二: grub
grub> root (hd#,#) 
grub> setup (hd#)

  

通過光盤進入救援模式

 

 進入救援模式后,發現mbr確實被破壞了,如下圖:

 

 使用第二種方法恢復:

grub> root (hd0,0) 
grub> setup (hd0)

 

 執行修復命令quit退出shell,reboot就可以正常進入系統里,至此grub第一階段修復完成。

 注意:第二種方法需要/boot/grub目錄下的相關文件都需要存在,否則恢復不成功。

 

實驗二:將/boot/grub下的文件移除,修復之:

 

清除后,使用第一種方法,顯然報錯,如下圖

 

 使用第二種方法修復,就能成功,如下圖:

 

 

 

 

實驗三:破壞grub的1.5階段,使用dd命令跳過前512個字節,清楚后面20個扇區,如何恢復。

 

 發現第1.5階段確實清零了,如下圖:

 

 破壞1.5階段后reboot,發現階段的啟動功能還是有,可以進入grub界面,只是加載不了文件系統驅動導致起不來,出現下面狀態界面:

 

 

恢復之:使用方法二恢復

 

 

恢復完grub1.5階段后,因為/boot/grub目錄下沒有grub.conf文件,需要執行下面命令指定內核文件和initramfs文件。

 

 

上圖只是對本次啟動有效,進入系統后需要手動寫grub.conf文件,或者從別處拷貝一個到/boot/grub目錄下,下圖是我自己手工寫的grub.conf文件:

 

 

 實驗四:自定義啟動菜單背景圖:

 

 使用concert工具將自己的圖片轉換成xpm格式:

 

 

將轉換后的圖片壓縮,並移動到/boot/grub 目錄下。

 

 reboot就可以看到啟動菜單自己定義的背景圖片。

 

 實驗五:清空/boot目錄下所有文件,如何修復:

 

 

清空/boot目錄后,重啟界面如下圖:

 

 

 修復,救援模式進行恢復,如下圖:

 

 

恢復grub第1和1.5階段以后還確實grub.conf文件,下面我自己手寫。如下圖

 

 恢復grub后,發現/boot目錄下只有grub目錄,還缺少內核文件和initramfs文件,需要執行下面命令生成,也可以直接使用rpm從光盤安裝,下面我使用mkinitrd命令生成。如下圖:

 

 

 

 實驗五:操作系統的根基於lvm的,grub被破壞,並且/etc/fstab文件也被刪除,如何修復。

下圖可以看到目前/ 是以lvm的方式掛載的,並且內核文件制定的操作系統的根路徑也是lvm。

 

 

 下圖不光破壞/boot,這時候/etc/fstab文件也破壞了

 

 

 

 重啟進入救援模式,發現掛載關系也找不着了,沒有任何的分區:

 

 

 進入shell,查看掛載關系,發下硬盤沒有任何掛載關系,使用blkid查看,沒有任何lvm文件系統的掛載關系。

 

 使用lvdisply查看,發現LV Status 是not available

 

 

 

 

 

 

 使用vgdisply,找到VG名字,然后激活VG

 

 

使用vgchange -ay VolGroup 激活VG卷組

 

 

 

 激活卷組后發現lv的狀態是活躍的:

 

 

 使用blkid命令,發現文件系統都激活了

 

 

 

修復/etc/fstab文件

 

 

 修復/boot

 

 

 

 手寫grub.conf文件:

 

 reboot,就可以正常進入系統,至此修復完畢。

 

 

 上面都是關於centos6的啟動修復,下面是centos7的grub修復:

實驗一:刪除/boot/grub目錄,如何修復:

 

 重啟后狀態界面如下圖:

 

 進入救援模式,恢復grub

 

 

 

 實驗二:刪除/boot

 

 

進入救援模式:

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM