您的足迹: Linux交换空间 Linux启动详解

Linux启动详解

Linux启动详解

系统引导过程简介

系统引导过程主要由以下几个步骤组成(以硬盘启动为例)

  1. 开机;
  2. BIOS加电自检(POST—Power On Self Test),内存地址为0fff:0000;
  3. 将硬盘第一个扇区(0头0道1扇区,也就是Boot Sector)读入内存地址0000:7c00处;
  4. 检查(WORD)0000:7dfe是否等于0xaa55.若不等于则转去尝试其他介质;如果没有其他启动介质,则显示 ”No ROM BASIC” ,然后死机;
  5. 跳转到0000:7c00处执行MBR中的程序;
  6. MBR先将自己复制到0000:0600处,然后继续执行;
  7. 在主分区表中搜索标志为活动的分区.如果发现没有活动分区或者不止一个活动分区,则停止;
  8. 将活动分区的第一个扇区读入内存地址0000:7c00处;
  9. 检查(WORD)0000:7dfe是否等于0xaa55,若不等于则显示 “Missing Operating System”,然后停止,或尝试软盘启动;
  10. 跳转到0000:7c00处继续执行特定系统的启动程序;
  11. 启动系统. 以上步骤中(2),(3),(4),(5)步由BIOS的引导程序完成;(6),(7),(8),(9),(10)步由MBR中的引导程序完成.

一般多系统引导程序(如Smart Boot Manager, BootStar, PQBoot等)都是将标准主引导记录替换成自己的引导程序,在运行系统启动程序之前让用户选择想要启动的分区.而某些系统自带的多系统引导程序(如 LILO,NT Loader等)则可以将自己的引导程序放在系统所处分区的第一个扇区中,在Linux中即为两个扇区的SuperBlock.

注:以上步骤中使用的是标准的MBR,多系统引导程序的引导过程与此不同.

引导扇区

Boot Sector组成

Boot Sector也就是硬盘的第一个扇区,它由MBR(Master Boot Record), DPT(Disk Partition Table) 和 Boot Record ID三部分组成.

MBR又称为主引导记录,占用Boot Sector的前446个字节(0~0x1BD),存放系统主引导程序(它负责从活动分区中装载并且运行系统引导程序).

DPT即主分区表占用64个字节(0x1BE~0x1FD),记录磁盘的基本分区信息.主分区表分为四个分区项,16Byte描述一个分区,即四个主分区,分别记录每个主分区的信息.

如果需要5个以上的分区,只能把一个主分区改为扩展分区形式存在(其实所谓的扩展分区也是一个主分区)。

Boot Record ID 即引导区标记占用两个字节(0x1FE~0x1FF),对于合法引导区,它等于0xaa55。

其中aa55是固定的字符,就是Magic Number,占用2byte,目的是让存在于bootloader区的管理程序在辨认扇区时,可以确认所存储的这个地方就是MBR,就点像MBR的身份证。
这里特别注意的是,平时用的fdisk /mbr命令,并不是将所有的MBR区块都格式化,这这里只是格式最前面的bootloader区的446byte区域。所以,如果partition table有问题的话,使用这个命令是没有任何帮助的。

这里简单总结一下:

  1. 一块硬盘只有4个主分区,每个主分区大小为16byte
  2. MBR是由bootloader(446byter)+partition table(64byte)+Magic Number(2字节)=512字节组成
  3. 如果partition table丢失,那么硬盘上所有的数据都将不可恢复

Boot Secor具体结构如图:

Boot Secor具体结构如图

linux如何启动

机器加电启动后,BIOS开始检测系统参数,如内存的大小,日期和时间,磁盘设备以及这些磁盘设备用来引导的顺序,通常情况下,BIOS都是被配置成首先检查软驱或者光驱(或两者都检查),然后再尝试从硬盘引导。如果在这些可移动的设备中,没有找到可引导的介质,那么BIOS通常是转向第一块硬盘最初的几个扇区,寻找用于装载操作系统的指令。

装载操作系统的这个程序就是boot loader.

linux里面的boot loader通常是lilo或者grub,从Red Hat Linux 7.2起,GRUB(GRand Unified Bootloader)取代LILO成为了默认的启动装载程序。

什么是GRUB

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

Grub特点简介

提供一个功能强大的命令行接口

这样就给用户提供了一个功能强大的接口,伸展了用户启动操作系统的灵活性,这种功能,对于非x86构架的许多机器上,已经存在了很多年了。

支持LBA大容量硬盘访问模式

在LBA模式出现之前,启动的程序只能访问1024柱面的硬盘,大约就是8G空间,后面的空间就无法访问了,因为grub对LBA的支持,让操作系统调用的灵活性大大的增加了

可以支持ext2文件系统

这个功能可以让Grub直接访问到放在硬盘分区上的配置文件,从而一旦MBR收到破坏,只需要重新写MBR,不需要重新写配置文件便可以恢复启动

grub工作原理

那么启动的时候grub是如何被载入的呢? grub有几个重要的文件:

  1. stage1
  2. stage2
  3. 有的时候需要stage1.5

这些文件一般都在/boot/grub文件夹下面

grub被载入通常包括以下几个步骤:

  • 装载基本的引导装载程序(stage1),stage1很小,网上说是512字节,但是在我的系统上用 du -b /boot/grub/stage1 显示的是1024个字节,不知道是不是grub版本不同的缘故还是我理解有误.stage1通常位于主引导扇区里面,对于硬盘就是MBR了,stage1的主要功能就是装载第二引导程序(stage2).这主要是归结于在主引导扇区中没有足够的空间用于其他东西了,我用的是grub 0.93,stage2文件的大小是 107520 bit.
  • 装载第二引导装载程序(stage2),这第二引导装载程序实际上是引出更高级的功能,以允许用户装载入一个特定的操作系统。在GRUB中,这步是让用户显示一个菜单或是输入命令。由于stage2很大,所以它一般位于文件系统之中(通常是boot所在的根分区).

上面还提到了stage1.5这个文件,它的作用是什么呢?

你到/boot/grub目录下看看,fatstage1.5 e2fsstage1.5 xfsstage1.5等等,很容易猜想stage1.5和文件系统有关系.有时候基本引导装载程序(stage1)不能识别stage2所在的文件系统分区,那么这时候就需要stage1.5来连接stage1和stage2了.

因此对于不同的文件系统就会有不同的stage1.5.但是对于grub 0.93好像stage1.5并不是很重要,因为我试过了,在没有stage1.5的情况下, 我把stage1安装在软盘的引导扇区内,然后把stage2放在格式化成ext2或者fat格式的软盘内,启动的时候照常引导,并不需要e2fsstage1.5或者fatstage1.5.

下面是我的试验:

# mkfs.ext2  /dev/fd0
# mount -t ext2  /dev/fd0  /mnt/floppy
# cd  /mnt/floppy
# mkdir boot
# cd  boot
# mkdir grub  (以上三步可用mkdir -p  boot/grub命令完成)
# cd grub
# cp  /boot/grub/{stage1,stage2,grub.conf}  ./
# cd; umount /mnt/floppy

以上几步把软盘格式化成ext2格式,然后把stage1,stage2,grub.conf这几个启动的时候必须的文件拷贝到软盘的指定目录下.下面安装grub到软盘上.

# grub  (进入grub环境)
grub>install (fd0)/boot/grub/stage1 (fd0) (fd0)/boot/grub/stage2 p (fd0)/boot/grub/grub.conf

以上这条命令也可以用下面的两句代替

 grub>root (fd0)    #grub的根目录所在的分区
 grub>setup (fd0)   #这一步就相当于上面的install命令

我在这里解释一下

install (fd0)/boot/grub/stage1 (fd0)  (fd0)/boot/grub/stage2 p (fd0)/boot/grub/grub.conf 这条命令.

install

告诉GRUB将(fd0)/boot/grub/grub/stage1 安装到软驱的引导扇区(fd0).

(fd0)/boot/grub/stage2

告诉grub stage2这个文件所在的位置.

参数后面跟着(fd0)/boot/grub/grub.conf

 告诉grub的配置文件所在的位置.

好了,让BIOS从软驱启动,试一下,没有e2fsstage1.5文件照样能够进入系统.其实这就是一个小小的启动盘啊.(了解了grub的运行原理,就简单多了^_^)

现在我们已经到grub的开机选单这一步了,接下来grub所需要做的就是装载在一个特定分区上的操作系统,如linux内核。一旦GRUB从它的命令行或者配置文件中,接到开始操作系统的正确指令,它就寻找必要的引导文件,然后把机器的控制权移交给操作系统.

一个典型完整的引导linux的命令如下:

  title Linux
         root(hd0,0)
         kernel /bzImage  ro  root=/dev/ram0
         initrd /initrd.img

这里有必要注意一下几个问题:

  1. grub的磁盘以及分区的命名方式和linux有所区别,第一个磁盘是从0开始,第一个分区也是从0开始.譬如第一个硬盘的第5分区在linux下面是/dev/hda5 ,而在grub里面是(hd0,4).再如/dev/fd0在grub里面是(fd0,0).
  2. 不管是IDE硬盘hda,hdb还是SCSI硬盘sda,sdb在grub里面都是以hd方式命名.譬如虚拟机里面的/dev/sda2在grub里面是(hd0,1),再如/dev/hdb7在grub里面以(hd1,6)命名。
  3. 要搞清楚上面两个root的关系,root (hd0,0)中的root是grub命令,它用来指定 boot 所在的分区作为grub的根目录.而root=/dev/ram0是kernel的参数,它告诉操作系统内核加载完毕之后,真实的文件系统所在的设备.要注意grub的根目录和文件系统的根目录的区别。

再回到上面的几行命令.

kernel命令用来指定内核所在的位置,"/"代表(hd0,0),也就是grub的boot目录。

注意:(如果/boot和/为同一分区,则需要指明为/boot路径)

initrd命令用来指定初始化ram的img文件所在位置.
grub载入内核bzImage并展开到指定位置(应该是0x100000这个地方),同时载入initrd.img到内存。

grub的任务至此就结束了,下面grub将机器的控制权转交给操作系统(linux).

操作系统接到控制权之后,开始start_kernel,接着内核将initrd.img展开到/dev/ram0为临时根文件系统,执行里面的linuxrc文件.

这里有必要说一下initrd的作用特别是它里面的核心文件linuxrc的作用

initrd的工作原理

当存在initrd的时候,机器启动的过程大概是以下几个步骤(当initrd这一行用noinitrd 命令代替后,就不存在initrd了)

1)boot loader(grub)加载内核和initrd.img
2)内核将压缩的initrd.img解压成正常的ram disk并且释放initrd所占的内存空间
3)initrd作为根目录以读写方式被挂载
4)initrd里面的文件linuxrc被执行
5)linuxrc挂载新的文件系统
6)linuxrc使用pivot_root系统调用指定新的根目录并将现有的根目录place到指定位置.
7)在新的文件系统下正式init
8)initrd被卸载.

为了便于理解,我将red hat linnux9 里面的initrd-2.4.20-8.img拿出来分析一下.这其实是一个压缩了的文件,是以gz结尾的.

[root@localhost root]# cp /boot/initrd-2.4.20-8.img  /mnt/initrd-2.4.20-8.gz
[root@localhost root]# gunzip /mnt/initrd-2.4.20-8.gz
[root@localhost root]# mount -o loop /mnt/initrd-2.4.20-8  /mnt/ram
[root@localhost root]# cd /mnt/ram
[root@localhost ram]# ls
   bin dev etc lib linuxrc loopfs  proc sbin sysroot
[root@localhost ram]#ls bin
   insmod modprobe nash
[root@localhost ram]#ls lib
   Buslogic.o  ext3.o  jbd.o  scsi_mod.o   sd_mod.o
[root@localhost ram]ls  dev
   console  null  ram  systty  tty1  tty2  tty3  tty4

sbin目录是指向bin目录的一个连接,其他目录是空的.

[root@localhost ram]# cat linuxrc
 
#!/bin/nash
1.  echo "Loading scsi_mod.o module"
2.  insmod /lib/scsi_mod.o
3.  echo "Loading sd_mod.o module"
4.  insmod /lib/sd_mod.o
5.  echo "Loading BusLogic.o module"
6.  insmod /lib/BusLogic.o
7.  echo "Loading jbd.o module"
8.  insmod /lib/jbd.o
9.  echo "Loading ext3.o module"
10. insmod /lib/ext3.o
11. echo Mounting /proc filesystem
12. mount -t proc /proc /proc
13. echo Creating block devices
14. mkdevices /dev
15. echo Creating root device
16. mkrootdev /dev/root
17. echo 0x0100 > /proc/sys/kernel/real-root-dev
18. echo Mounting root filesystem
19. mount -o defaults --ro -t ext3 /dev/root /sysroot
20. pivot_root /sysroot /sysroot/initrd
21. umount /initrd/proc

1-10行是加载一些必要的模快.

11-12行加载proc内核文件系统

13-14行利用nash内建的命令mkdevices创建块设备,mkdevices是根据/proc/partitions文件创建里面列出的所有块设备.

15-16行利用nash内建的命令mkrootdev,mkrootdev使它后面的参数/dev/root成为一个块节点从而使得根分区设备被挂载,其中根分区设备由grub.conf里面的kernel命令后面所带的参数root=决定,如果root=参数没有被指定,/proc/sys/kernel/real-root-dev文件将提供根分区设备号.

17行将数字256写入到后面的文件里面去.

18-19行挂载根文件系统到/sysroot目录下,/dev/root里面的内容就是root=参数所指定的设备里面的内容

20行调用pivot_root改变根目录所在地并place旧的根目录到指定的位置.

21行卸载旧的根目录里面的proc内核文件系统.

从这里面我们总结一下linuxrc的作用: (参考/usr/src/linux-2.4/Documentation/initrd.txt文档)

1)/linuxrc文件决定在挂载真正的文件系统之前所需完成的事情(譬如加载必要的网络驱动或者加载ext3文件系统).
2)/linuxrc加载必要的模块.
3)/linuxrc挂载根文件系统
4)/linuxrc调用pivot_root来改变根目录

既然linuxrc的主要目的是加载模快用的,那如果我们的内核没有动态的模块而所需的功能都是静态编译进内核的,那么是不是可以不用linuxrc文件呢?答案是可以不用,在普通的linux操作系统里面可以加入noinitrd选项以告知bootloader 不使用initrd.如果我们做网关,因为ram是我们的文件系统的载体,所以initrd一行当然不能去掉,但是我们可以不用linuxrc文件,sysroot文件夹和initrd文件夹.

linuxrc执行完毕之后,系统就会以真正的根目录正式init.

系统在/bin/或者/sbin目录下找到init程式,然后根据它的配置文件/etc/fstab进行初始化,最后调用mingetty程式启动login完成引导.

Grub2详解

如何定义缺省项目

若要列出系统开机时显示的所有选项,请执行以下指令:

[root@host ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux 7 (Core), with Linux 3.10.0-229.14.1.el7.x86_64
1 : CentOS Linux 7 (Core), with Linux 3.10.0-229.4.2.el7.x86_64
2 : CentOS Linux 7 (Core), with Linux 3.10.0-229.el7.x86_64
3 : CentOS Linux 7 (Core), with Linux 0-rescue-605f01abef434fb98dd1309e774b72ba

/boot/grub2/grubenv 档是不能手动编辑的。请采用以下指令:

[root@host ~]# grub2-set-default 2
[root@host ~]# grub2-editenv list
saved_entry=2

留意上述 awk 指令输出的第一个项目的编号是 0。

开机选单是自动创建出来的

请勿尝试手动编辑开机选单,因为它是按照 /boot/ 目录内的文件自动创建出来的。

然而你可以调整 /etc/default/grub 档内定义的通用设置,及在 /etc/grub.d/40_custom 档内加入个别自定项目。

/etc/default/grub 档的内容如下:

GRUB_TIMEOUT=5
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

通用于所有项目的内核选项都通过 GRUBCMDLINELINUX 行来定义。

举个例说,要是你想看见详细的开机消息,删除 rhgb quiet。
要是你想看见标准的开机消息,只删除 rhgb。

执行以下指令便能套用更改了的设置:

[root@host ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-229.14.1.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.14.1.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-229.4.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.4.2.el7.x86_64.img
Found linux image: /boot/vmlinuz-3.10.0-229.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-605f01abef434fb98dd1309e774b72ba
Found initrd image: /boot/initramfs-0-rescue-605f01abef434fb98dd1309e774b72ba.img
done

UEFI 系统上的指令是 grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg

如何在Grub2里使用LABEL

Add the following lines to your /etc/defaut/grub :

GRUB_DISABLE_LINUX_UUID=true
GRUB_ENABLE_LINUX_LABEL=true
# mount -o bind /dev /mnt/root/dev
# mount -o bind /proc /mnt/root/proc
# mount -o bind /sys /mnt/root/sys
# mount -o bind /run /mnt/root/run
# chroot /mnt bash
 
grub2-mkconfig -o ~/grub.cfg
 
grub2-install --root-directory=/media --force /dev/sdd

如何发现并加载另外的操作系统引导

打开探测发现:

grep 'GRUB_DISABLE_OS_PROBER' /etc/default/grub

如果为空或者是true,则需要打开探测功能:

sudo vi /etc/default/grub
GRUB_DISABLE_OS_PROBER=false

运行os-prober并更新grub引导文件

sudo update-grub
如果是windows系统,还要添加其它模块:
menuentry 'Microsoft Windows 10' {
  insmod part_gpt  #现在一般是gpt格式的硬盘
  insmod fat       #实际上是fat格式,可以自己试一下是vfat还是fat
  insmod chain
  search --fs-uuid --no-floopy --set=root UUID-XXXX
  chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi #注意大写
}

详解畅谈Linux initrd系统

摘要

将刚刚找到的root 路径mount到Linux initrd中的/sysroot下,但要注意,这时的/sysroot就好像rescue mode的/mnt/sysimage目录,是一样的意思,都只是先将实体操作系统存在的实体路径mount到一个虚拟操作系统(在这里是initrd)的暂存目录中,再通过切换的方式转为实体的主目录。

Linux initrd有很多值得学习的地方,这里我们主要介绍Linux initrd,包括介绍nash等方面,Linux initrd 讲究了很多重要的事情,init的执行在这里分为以下几部操作,请对所区分的各个部分加以了解。

定义主目录(root)的路径

mkrootdev指令是nash这一支shell所提供的功能,主要就是在要转换之前先行将主目录定义清楚,默认会将GRUB中kernel command line所设置root=xxx中的xxx路径先建立好。

将root 路径mount到/sysroot下将刚刚找到的root 路径mount到Linux initrd中的/sysroot下,但要注意,这时的/sysroot就好像rescue mode的/mnt/sysimage目录,是一样的意思,都只是先将实体操作系统存在的实体路径mount到一个虚拟操作系统(在这里是initrd)的暂存目录中,再通过切换的方式转为实体的主目录。不同的是,在rescue mode中用的是chroot;但在Linux initrd用的则是switchroot指令,之所以会有这样的差异,是因为rescue mode直接使用了操作系统的指令,而initrd在加载时,并没有操作系统的指令可用,因此是通过nash内置的指令。

或许有人会问,rescue mode不也是以Linux initrd的方式加载的吗?是的,但要在此补充说明的是,虽然都是Linux initrd,但rescue mode中的initrd是光盘直接提供的,而这里所说的Linux initrd则是安装操作系统后由操作系统直接产生的,两者有很多不同之处。您若有兴趣,不妨将光盘的initrd文件打开来看,将会发现该Linux initrd中的init文件并不是一个脚本文件,而是一个真正可以在操作系统下执行的程序。

当然,存放在CD或DVD中的Linux initrd文件是为用户安装操作系统所使用的,会遇到许多软、硬件的不同需求,因此,initrd的文件所需存放的资料(像module)远比操作系统开机所需加载的Linux initrd文件多得多。像Fedora Core 6安装光盘中的initrd文件几乎是操作系统下initrd文件的4倍之多。

建立其他的文件系统

在主目录(在initrd阶段为/sysroot)建好之后,setuproot指令开始运行,将Linux initrd通过init建立好的/proc、/sys、/de目录中所有资料转移到/sysroot,以方便转换到新的实体操作系统,这也是nash内置的功能。

切换到新的root目录,并开始执行实体系统下的init文件

switchroot是nash在2.6版kernel以后的版本才可使用的新功能,刚刚setuproot把所有和操作系统有关的目录都建立在/sysroot后,setuproot会将/sysroot切换为实体操作系统下的主目录(/),完成后会顺便将所有之前Linux initrd存在内存中的资料清空,如同所有在虚拟文件系统(包括/sys、/proc或/dev等)中的资料,因此,当switchroot执行完成时,内存中就不会再有Linux initrd所建的任何目录及文件,完全由实体操作系统来运行。

总结

在此要特别强调,千万不要在您的计算机实验上述所提到nash支持的setuproot及switchroot两种功能,虽然本章一开始就说明了如何执行nash及如何实际使用nash中的功能,但如果使用到setuproot及switchroot两者其中之一,都会对操作系统造成破坏,尤其是switchroot。原因是这两者原本就是要为切换到实体操作系统做准备,但并不会理会本身所存在的路径是属于内存或是实体硬盘。

当用户执行时,会强迫由setuproot将原本在操作系统中/proc、/sys及/dev的文件先做搬移操作,这样在开机时,就会因为被删除掉许多重要文件而造成无法正常开机,更惨的是,接着会执行switchroot,我们提过这个功能会将切换过后遗留的文件全部清掉,这在实体操作系统所代表的就是将硬盘中的资料全数删除,因此,在执行完switchroot后,就只剩原本console的画面陪伴你,重开机后就一个不剩了,想做实验的用户,千万要考虑清楚再下手。

当然,在switchroot执行后,就进入操作系统程序,而这个重责大任就交给存在于实体操作系统中的init这个程序。

启动的流程图

了解UUID

UUID是128位整数(16字节)的全局唯一标识符(Universally Unique Identifier),是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。

通常平台会提供生成UUID的API。UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。

由以下几部分的组合:

当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。

关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12),可以从cflib 下载CreateGUID() UDF进行转换。

使用UUID的好处在分布式的软件系统中(比如:DCE/RPC, COM+,CORBA)就能体现出来,它能保证每个节点所生成的标识都不会重复,并且随着WEB服务等整合技术的发展,UUID的优势将更加明显。关于UUID的更多信息可以多google一下。

查询设备的UUID标识

我们如何知道一个分区的 UUID 呢? 有 3 种方法:

1. 通过浏览 /dev/disk/by-uuid/ 下的设备文件信息

[root@VM-Arch ~]# ls -al /dev/disk/by-uuid/
total 0
drwxr-xr-x 2 root root  0 2009-03-14 06:07 .
drwxr-xr-x 5 root root  0 2009-03-14 06:07 ..
lrwxrwxrwx 1 root root 10 2009-03-14 06:07 12eb77c3-fe99-4d8b-bde5-7b9ae754759f -> ../../sda2
lrwxrwxrwx 1 root root 10 2009-03-14 06:07 95ac2b44-fdeb-435b-a815-48162301ec43 -> ../../sda4
lrwxrwxrwx 1 root root 10 2009-03-14 06:07 b47c6e50-e055-46b3-b359-b664578f6d75 -> ../../sdb1
lrwxrwxrwx 1 root root 10 2009-03-14 06:07 beae76e2-82a0-4943-b81f-acb4360b4bad -> ../../sda1
lrwxrwxrwx 1 root root 10 2009-03-14 06:07 ccad474c-fe73-48ec-8fab-7e333e0c26f8 -> ../../sda3

2. 通过 vol_id 命令

# vol_id /dev/sdb5 
ID_FS_USAGE=filesystem 
ID_FS_TYPE=vfat 
ID_FS_VERSION=FAT32 
ID_FS_UUID=0909-090B 
ID_FS_UUID_ENC=0909-090B 
ID_FS_LABEL=SWAP 
ID_FS_LABEL_ENC=SWAP 
ID_FS_LABEL_SAFE=SWAP 

3. 通过 blkid 命令

[root@VM-Arch ~]# blkid /dev/sdb1
/dev/sdb1: UUID="b47c6e50-e055-46b3-b359-b664578f6d75" TYPE="ext4"

通过这三种方法都可以获得分区的 UUID,UUID 依据分区不同,长度和格式都不相同。

如何为新设备创建UUID

首先用以上三种方法获取新设备的UUID号

[root@VM-Arch ~]# blkid /dev/sdb1
/dev/sdb1: UUID="b47c6e50-e055-46b3-b359-b664578f6d75" TYPE="ext4"

然后写入对应的/etc/fstab文件,如

UUID=b47c6e50-e055-46b3-b359-b664578f6d75 /mnt ext4 defaults 0 1

系统无法启动的解决

a. MBR错误或被覆盖

一般是在安装双系统的时候,覆盖了原来的MBR数据,导致系统无法正常引导启动,也包括其它的损坏MBR的操作。

解决方法

  1. 如果grub还能继续使用,可以利用grub-shell模式进行修复
  2. 如果grub不能继续使用,则需要利用光盘进行rescue模式,进入修复模式后,有两种操作方式:
2.1 直接键入grub,进入命令行模式,进行如下操作: 
      >root  (hd0,0)           <--boot分区所在的盘符 
      >setup (hd0,0) 
2.2 使用grub-install /dev/hda --root-directory=/mnt/sysimage 

b. 备份MBR记录

# dd if=/dev/sda of=/mbr.rec bs=512 count=1 
# od -x /mbr.rec

MBR记录

引导程序出错

关键字:root,kernel,initrd,ro root,LABEL

一般来说,有这么几种情况:

a.  找不到内核文件 
b.  找不到VFS 
c.  找不到init等级 

前提

要熟悉grub shell的用法,利用文本方式 或者 光盘拯救模式进入系统)

先来看一下grub的引导代码:

title    eAROS,kernel2.6.24-18-rt 
root     (hd0,6)
kernel  /boot/vmlinuz-2.6.24-18-rt root=UUID=eaa449dc-fbb9 ro quiet   或者
kernel  /boot/vmlinuz-2.6.24-18-rt root=LABEL=/ ro quiet splash 
initrd  /boot/initrd.img-2.6.24-18-rt 

了解UUID

引导后无法登录或看不到提示符

a./etc/inittab有问题,出错的情况有几种:

1.如果出现INIT:No inittab file found。     <-   一般来说就是inittab文件丢失或者有错误。 
2.如果能够启动,但运行到了非法的等级,如level9,需要修正 。
3.启动后就重新启动,如:l3:3:wait:/etc/rc.d/rc6,则可能是运行级别配置错误。

b./etc/rc.sysinit文件有问题

解决方法:

rpm -qf /etc/inittab --root /mnt/sysimage 
rpm -ivh --force rpm-package --root /mnt/sysimage 
rpm -ivh --replacepkg srpm-package --root /mnt/sysimage 
reboot 

c./etc/fstab 有问题,无法正常挂载设备

<filesystem>      <mountpoint>    <type> <options>          <dump> <pass> 
 proc             /proc            proc  defaults            0        0 
 /dev/sda6        swap             swap                 0        0 
 /dev/sda7        /                ext3  relatime,errors=remount-ro  0 1 
 /dev/sda9        /eAR             ext3  relatime,errors=remount-ro 0 0 

d. 文件系统错误,需要先行在单用户模式下,强制修复文件系统:

# fsck.ext3 -a /dev/hda1 

e. 系统无法识别的LABEL,导致无法正确挂载硬盘分区。

f. 硬盘低级错误,无空闲空间。用df命令查看空间容量。

看到login,但输入密码无法登录

  • 的确是密码错误,如果忘记了密码,则在单用户模式修改密码。
启用单用户模式:即在启动选项中加入 single or s 指令
  • root用户被锁。
在单用户模式,使用 usermod -U root 解锁用户即可,或者直接在/etc/passwd /etc/shadow中修改UID
  • root用户帐号已经过期
chage -l root|grep expire
  • 没有root用户,即没有uid为0的用户,运行这个命令帮助我们定位用户
# awk -F: '$3==0 { print $1 }' /etc/passwd  <- 列出所有为0的用户
  • 是否有/etc/nologin这个文件,有的话在单用户模式下删除即可。
  • /etc/securetty文件中没有tty表示1,2,3,4等)
  • PAM验证模块有异常,运行authconfig命令修复

检查用户信息的方法

查看帐户和密码的有效性

# chage -l root

查看帐号信息,目录和shell

# finger geminis

fedora,ubuntu无法找到root设备问题解决

一台比较老的LENOVO R510,安装ubuntu 8.10完成之后启动,在加载了kernel之后报错,提示

check rootdelay&check root=
ALERT! /dev/sda1 does not exist.

然后进入了initramfs,在ramfs里面手工mount /dev/sda1确是成功的,一开始以为是UUID的问题,去掉UUID使用sda之后仍旧这样,之后再grub中加入了

rootdelay=60

系统正常启动进去了

原因是系统加载后默认的rootdelay太短,导致系统还没有正常加载完设备驱动,就已经开始寻找root分区的内容,导致无法加载root分区。而fedora 10在启动后也同样停在加载硬盘这边,但是fedora没有任何提示,也没有busybox可以用,就是停在那边没有响应,只是报错找不到root分区。

注:一般在硬盘初始化速度比较慢的机器上引导启动容易出现这种故障

Linux系统快速启动的十大秘诀

   Linux需要重新启动是少有的。可是一旦需要,Linux启动常常是缓慢的。简单介绍一些加速的办法。其中一些方法不太难。

1: 撤消多余的服务

根据机器的用途,很多服务是不需要的。要是Linux只用作桌面,就不需要sendmail、httpd和另外许多服务。如果你的服务器只是Web服务器,也可以关掉许多服务。为此,可转到管理菜单,检查服务项目。只需撤消所有不想启动的服务选项。

2: 撤消多余的内核模块

假如你的桌面连接到以太网,就不需要装载无线内核模块。这是较为困难的任务,可能需要重新编译内核,而编译内核不是可以轻松担当的工作。为此,你大概需要内核源代码。接着,按照编译内核的标准步骤进行。不同在于你要搜查系统,撤除所有不需要的模块。

查明系统中当前安装和运行的内核模块的最好方法是安装Bootchart。它不仅会给你一个适宜的模块清单,而且还会说明系统启动过程中发生的事情。还可以发出命令:

chkconfig –list |grep 3:on

弄清楚正在运行什么服务。一旦知道装载了什么不需要的模块,就可以在内核重新编译期间将其移除。只要这样处理,编译的内核就完全适合你的体系结构。

3: 使用轻型窗口管理器代替GNOME或KDE

我插入小脚印窗口管理器的原因是——它们大幅度减少图形(界面)启动时间。代替不得不额外等待启动GNOME或KDE的30到60秒,为什么不等待用于启动Enlightenment或者XFCE的2到10秒呢?它们不仅节省启动时间,还会节省内存并解救处理臃肿软体(bloatware)这种令人头痛的事。

4: 使用基于文本的登录而不是图形登录

我的大多数Linux机器启动run level 3而非run level 5。这个运行级别将停在文本登录模式,我就在这个地方登录并发出startx命令,开始选择桌面。图形登录模式做两件事:增加装入时间并引起头痛的问题即试图从拙劣的X windows挣脱出来。

5: 使用轻型发行版

不要装载重型的Fedora,为什么不试一下Gentoo、Arch或Puppy Linux呢?这些较小的发行版的启动时间比更加臃肿的Fedora(甚至Ubuntu)要快很多。在较大的发行版中,OpenSuSE声称启动最快,但我还没有亲自试验。在最新的Fedora和Ubuntu之间,Ubuntu击败Fedora的启动时间(而且是即开即用)。

6: 使用Open BIOS

要是你相当聪明能干,准备升级PC固件,可以考虑迁移到开源BIOS。一个附加说明,使用开放固件允许Linux启动时真正初始化硬件(而不依赖BIOS)。最重要的是,许多开放BIOS可以设置满足机器的特殊需要。如果不走开放BIOS之路,至少也可以设置BIOS不寻找不存在的软盘驱动器,即直接启动第一个硬盘驱动器(首先不是CD驱动器)。

7: 回避DHCP

如果你工作在地址租约不是问题的家庭网络(或者小型企业网络)上,那么,机器就用静态IP地址。这将使机器不必出外访问DHCP服务器来获得IP地址。如果采取这种途径,就要确保配置文件/etc/resolve.conf也表达你的DNS服务器地址。

8: 热插拔可免就免

热插拔是指允许把新设备插上电源并立即使用的系统。如果你知道你的服务器不需要这种系统,就删除它。这将减少启动时间。在许多系统上,热插拔消耗大量启动时间。排除热插拔将发生的变化取决于你所用的发行版。注意:就绝大部分而言,udev已经取代热插拔。但如果你还在运行老一点的发行版,这样做还是适合的。

9: 要是真的大胆无畏,可尝试一下initng

initng系统充当sysvinit系统的替换物,并承诺彻底减少类UNIX操作系统的启动时间。如果你愿意了解运行中的initng系统,可以试一试Pingwinek LiveCD。

10: 利用Debian具有的代码

要是正在使用Debian,就有一行可用来将你的启动脚本转换成并行运行的简单代码。

如果检查一下/etc/init.d/rc脚本,就会看到:大约在24行有CONCURRENCY=none。把这一行改为CONCURRENCY=shell,你有可能目睹启动时间的减少。

上述大部分应该是最重要的,当然最快的使Linux启动提速的方法就是不要重启,所以,极少重新启动一般可以减轻启动时间的担子。

11: 重置Debian镜像的密码

wiki/public/linux/linux启动详解.txt · 最后更改: 2025/12/03 10:29