首页 > 代码库 > Linux系统启动流程之grub

Linux系统启动流程之grub

什么是GRUB

 

  GNU GRUB 是一个多重操作系统启动管理器。GNU GRUB 是由GRUB(GRand Unified Bootloader) 派生而来。GRUB 最初由Erich Stefan Boleyn 设计和应用;

  系统启动引导管理器,是在计算机启动后运行的第一个程序,他是用来负责加载、传输控制到操作系统的内核,一旦把内核挂载,系统引导管理器的任务就算完成退出,系统引导的其它部份,比如系统的初始化及启动过程则完全由内核来控制完成。


Linux中GRUB的配置文件

[root@localhost ~]#vim /boot/grub/grub.conf

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Red Hat Enterprise Linux Server (2.6.18-164.el5)
    root (hd0,0)
    kernel /vmlinuz-2.6.18-164.el5 ro root=LABEL=/ rhgb quiet
    initrd /initrd-2.6.18-164.el5.img


  1、破坏grub前400b:  (grub占用446b,只破坏部分grub)

[root@localhost ~]# dd if=/dev/zero of=/dev/sda count=1 bs=400
1+0 records in
1+0 records out
400 bytes (400 B) copied, 5.3e-05 seconds, 7.5 MB/s
[root@localhost ~]# sync
[root@localhost ~]# sync


  2、修复grub:  ( 操作第一步后未退出该Linux系统 )

[root@localhost ~]# grub    #进入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)      #第一个硬盘hd0,boot在第一个分区上0
root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)       #set表示安装grub
setup (hd0)
 Checking if "/boot/grub/stage1" exists... no   #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)"...  15 sectors are embedded.
succeeded       #安装grub成功
 Running "install /grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/grub/stage2 /grub/grub.conf"... succeeded
Done.
grub> quit
quit
[root@localhost ~]# vi /etc/grub.conf
...
default=0
timeout=15
splashimage=(hd0,0)/grub/splash.xpm.gz
#hiddenmenu
password --md5 $1$Zu2p2/$QAIN26LbJRJITA622oUZU.
title My Linux
   root (hd0,0)
   kernel /vmlinuz-2.6.18-164.el5 ro root=LABEL=/ rhgb quiet
   initrd /initrd-2.6.18-164.el5.img


  3、安装grub第二种方式:

可指定任意设备,安装前做好分区,有分区表,将boot目录挂载

# grub -install--root-directory=/path/to/boot‘s_parent_dir   /PATH/TO/DEVICE


[root@localhost ~]# mke2fs -j /dev/sdc1     #1#格式化硬盘
[root@localhost ~]# mke2fs -j /dev/sdc2
[root@localhost ~]# mkswap /dev/sdc3
Setting up swapspace version 1, size = 139825 kB
[root@localhost ~]# mkdir /mnt/boot
[root@localhost ~]# mount /dev/sdc1 /mnt/boot/   #2#映射boot分区
[root@localhost ~]# mount
/dev/sdc1 on /mnt/boot type ext3 (rw)
[root@localhost ~]# grub-install --root-directory=/mnt  /dev/sdc #3#自动在/mnt下找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. #已创建grub
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      #grub中硬盘的映射关系
(hd1)    /dev/sdb
(hd2)    /dev/sdc
[root@localhost ~]# cd /mnt/boot/
[root@localhost boot]# tree   #以下为grub-install生成的文件自动放在boot下
.
|-- grub
|   |-- device.map
|   |-- e2fs_stage1_5
|   |-- fat_stage1_5
|   |-- ffs_stage1_5
|   |-- iso9660_stage1_5
|   |-- jfs_stage1_5
|   |-- minix_stage1_5
|   |-- reiserfs_stage1_5
|   |-- stage1
|   |-- stage2
|   |-- ufs2_stage1_5
|   |-- vstafs_stage1_5
|   `-- xfs_stage1_5
`-- lost+found
2 directories, 13 files
[root@localhost boot]# vim /mnt/boot/grub/grub.conf   #4#新建grub.conf文件

default=0
timeout=5
title Fake Mylinux
    root (hd0,0)
    kernel /vmlinuz
    initrd /initrd.img

[root@localhost boot]# sync    #必须多次同步
[root@localhost boot]# umount /mnt/boot/     #在/boot上无法卸载自己
umount: /mnt/boot: device is busy
umount: /mnt/boot: device is busy
[root@localhost boot]# cd
[root@localhost ~]# umount /mnt/boot/     #切换后卸载成功

新建虚拟机,并连接这个IDE硬盘:(hd2) /dev/sdc,再启动该硬盘对应的系统即可。


  4、grub.conf文件丢失时进入系统命令,详如附

grub> find

grub> root (hd#,N)

grub> kernel/vmlinuz-2.6.18-308.el5 ro root=LABEL=/

grub> initrd/initrd-2.6.18-308.el5.img

grub> boot


技术分享


  5、Kernel初始化的过程:

1、设备探测

2、驱动初始化(可能会从initrd(initramfs)文件中装载驱动模块)

3、以只读挂载根文件系统;

4、装载第一个进程init(PID:1)

 

id:runlevels:action:process

id: 标识符

runlevels: 在哪个级别运行此行;

action: 在什么情况下执行此行;

process: 要运行程序;

 

id:3:initdefault:

 si::sysinit:/etc/rc.d/rc.sysinit   

 

ACTION:

initdefault: 设定默认运行级别

 sysinit:   系统初始化

  wait:     等待级别切换至此级别时执行

respawn: 一旦程序终止,会重新启动

 

/etc/rc.d/rc.sysinit完成的任务:

1、激活udev和selinux;

2、根据/etc/sysctl.conf文件,来设定内核参数;

3、设定时钟时钟;

4、装载键盘映射;

5、启用交换分区;

6、设置主机名;

7、根文件系统检测,并以读写方式重新挂载;

8、激活RAID和LVM设备;

9、启用磁盘配额;

10、根据/etc/fstab,检查并挂载其它文件系统;

11、清理过期的锁和PID文件;

 

/etc/inittab中服务控制方法:

for I in /etc/rc3.d/K*; do

  $I stop

done

 for I in /etc/rc3.d/S*; do

  $I start

done

##: 关闭或启动的优先次序,数据越小越优先被选定

先关闭以K开头的服务,后启动以S开头的服务;


  6、使用锁文件,查看服务是否开起来,学习其控制方法

#!/bin/bash
#
# chkconfig: 2345 77 22
# description: Test Service
LOCKFILE=/var/lock/subsys/myservice
STATUS(){
  if [ -e $LOCKFILE ];then
    echo "Running..."
  else
    echo "Stopping..."
  fi
}

USAGE(){
  echo "`basename $0` {start|stop|restart|status}"
}

case $1 in
start)
  echo "Starting..."
  touch $LOCKFILE;;
stop)
  echo "Stopping..."
  rm -f $LOCKFILE &> /dev/null;;
restart)
  echo "Restarting..." ;;
status)
  STATUS;;
*)
  USAGE;;

esac


[root@localhost etc]# ./myservice.sh start
Startin...
[root@localhost etc]# ./myservice.sh status
Running...
[root@localhost etc]# ./myservice.sh stop
Stopping...
[root@localhost etc]# ./myservice.sh status
Stopping...

[root@localhost etc]# ./myservice.sh
myservice.sh {start|stop|restart|status}
[root@localhost etc]# 


[root@localhost init.d]# cp myservice.sh  /etc/rc.d/init.d/myservice

[root@localhost init.d]# chkconfig --list httpd  #查看httpd服务
httpd              0:off    1:off    2:off    3:off    4:off    5:off    6:off

[root@localhost rc.d]# find /etc/rc.d/ -name "*myservice*"  #查看无此服务
/etc/rc.d/init.d/myservice

[root@localhost rc.d]# chkconfig --add myservice  #自动创建服务链接
[root@localhost rc.d]# find /etc/rc.d/ -name "*myservice*"
/etc/rc.d/init.d/myservice
/etc/rc.d/rc6.d/K22myservice
/etc/rc.d/rc0.d/K22myservice
/etc/rc.d/rc5.d/S77myservice
/etc/rc.d/rc1.d/K22myservice
/etc/rc.d/rc3.d/S77myservice
/etc/rc.d/rc2.d/S77myservice
/etc/rc.d/rc4.d/S77myservice

[root@localhost rc.d]# chkconfig --del myservice  #自动删除服务链接
[root@localhost rc.d]# find /etc/rc.d/ -name "*myservice*"
/etc/rc.d/init.d/myservice
[root@localhost rc.d]# chkconfig --list myservice
myservice  0:off    1:off    2:on    3:on    4:on    5:on    6:off
[root@localhost rc.d]# chkconfig --level 24 myservice off  #修改指定哪些级别关闭
[root@localhost rc.d]# chkconfig --list myservice
myservice  0:off    1:off    2:off    3:on    4:off    5:on    6:off

[root@localhost rc.d]# cat /etc/rc.d/rc.local    #S99,最后一个启动的程式
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don‘t
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

在此文件rc.local中最后一行加入命令即可执行所需要的程式。


脚本学习范例:cat  /etc/rc.d/rc.sysinit       cat  /etc/inittab 


---end---

Linux系统启动流程之grub