开关机流程(六)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、开机关机流程与Loader
1.开机流程简介
整个开机的程序是这样的:
1)加载BIOS的硬件信息,并取得第一个开机装置的代号;
2)读取第一个开机装置的MBR的boot Loader(亦即是lilo,grub,spfdisk等等)的开机
信息;
3)加载Kernel操作系统核心信息,Kernel开始解压缩,并且尝试驱动所有硬件装置;
4)Kernel执行init程序并取得run-level信息;
5)init 执行run-level的各个批次档(Scripts);
6)init执行/etc/rc.d/rc.local档案
7)执行/bin/login程序,并等待使用者登入
8)登入之后开始以shell控管主机
2.boot loader与Kernel载入
开机时第一个被读取的就是BIOS(Basic Input Output System),里面记录了主机板芯片组与相关的设定,读取了BIOS设定值之后,系统会根据BIOS的数据,进行开机自我测试(power on self test,POST),然后开始执行硬件侦测的初始化,并设定PnP装置,再定义出可开机的装置,之后开始进行开机装置的数据读取了(MBR相关的任务)。

然后主机开始尝试由储存媒体加载操作系统,系统会开始去第一个开机装置上面进行开机程序,读取硬盘的主引导扇区(Master Boot Record,MBR),而系统可以由主引导扇区所安装的开机管理程序(boot loader)开始执行核心辨识的工作。

当然,要加载Linux核心时,得使用支持Linux filesystem的boot loader了,目前主流的grub 开机管理程序,不但可以支持Linux,同时也支持Windows相关的核心系统。

而Windows 的loader却不认识Linux的核心档案。

选择一个好的boot loader会具有两个功能,就是:菜单功能(menu)和指向功能(pointer)。

读取核心档案后,Linux会将核心解压缩到主存储器中,并且利用核心的功能,开始测试与驱动各个周边装置,包括储存装置、CPU、网络卡、声卡等等。

核心档案一般会被放置到/boot里面,并且取名为/boot/vmlinuz才对!
在加载核心过程中,系统只会【挂载想根目录】,且以只读的方式挂载。

此外,为了让某些功能可以用档案的方式读取,会制作所谓的虚拟硬盘(RAM Disk)来辅助,那就是
initrd以及linuxrc的功用了。

利用boot loader的功能,可在加载核心的时候加载initrd的映像档(/boot/initrd-xxxx.img),Linux系统会主动的以initrd(man 4 initrd)来进行虚拟硬盘的建置,并且利用linuxrc(包含在initrd的映像档内)这个程序的功能来进行加载模块的动作。

Linuxr主要的特性是:
必须是linuxrc这个档名
必须放置在initrd所建立的虚拟硬盘的最顶层目录
必须要可以被核心所执行
在核心驱动周边硬件的工作完成之后,initrd所建立的虚拟硬盘就会被移除了。

不过,initrd 并非必要,一般来说,各大Linux distributions在建立核心时,都会一起建立出这个initrd 的映像档,辅助开机的顺利进行。

总之,在这个过程中,boot loader可找到Linux的核心档案并将它加载到主存储器中,同时可由initrd建立的虚拟硬盘(RAM Disk)辅助开机的进行,最后,将读处BIOS的主机硬件数据交由Linux核心来进行侦测并加载适当的驱动程序(driver),让整个主机硬件准备系统的要求。

整个流程有点像这样:
在在要
在核心完整的加载后,你的主机就开始正确的动作了。

3.第一支程序init及设定文件/etc/inittab与runlevel
整个Linux系统中第一支被执行的程序就是【/sbin/init】,它除了利用设定档【/etc/inittab】来取得开机的等级(run level)外,还会由这个run level的设定值来进行不同的开机服务项目的启动。

Linux是由设定run level来规定系统使用不同的服务来启动。

基本上,依据有无网络与有无X Window而将run level分为六个等级。

分别是:
1)Single user mode (单人维护模式,用在系统出问题时的维护)
2)Multi-user,without NFS(类似底下的run level 3,但无NFS服务)
3)Full multi-user mode(完整的含有网络功能的纯文字模式)
4)Unused(系统保留功能)
5)Xll(与run level 3类似,但使用X Window)
6)Reboot(重新开机)
开机是,系统的run level 是由/etc/inittab所设定的:
这个档案的语法是这样的:
所以可以得到这样的结论:
●如果不想让使用者【ctrl】+【alt】+【del】来重新启动系统,可以将底下这一行注释
掉:ca::ctrlaltdel:/sbin/shutdown –t3 –r now
●规定开机的预设run level是纯文字(3)或者是具有图形接口(X Window,5),可经由
【id:3:initdefault:】那个数字来决定!
4.init处理系统初始化流程(/etc/rc.d/rc.sysinit)
上面提到的/etc/inittab里有这一句【si::sysinit:/etc/rc.d/rc.sysinit】,这表示,我开始加载各项系统服务之前,得先做好整个系统环境,主要利用/etc/rc.d/rc.sysinit这个shell script 来设定好我的系统环境的。

/etc/rc.d/rc.sysinit主要的工作大抵有这几项:
1)取得网络环境与主机类型:
首先读取网络设定文件/etc/sysconfig/network,取得主机名称与预设通讯网关(gateway)等网络环境。

2)测试与挂载内存装置/proc及USB装置/sys:
除挂载内存装置/proc外,还会主动侦测系统上是否具有usb的装置,有则会主动加
载usb的驱动程序,并且尝试挂载usb的档案系统。

3)决定是否启动SELinux:
近期,很多distributions都加入了美国国家安全局发展的Security Enhance Linux套件,这个SELinux可以更加强化Linux操作环境的安全性。

不过对于新手来说,不是很容易上手。

因此,建议大家先不要启动。

4)接口设备的侦测与Plug and Play(PnP)参数的测试
根据核心在开机时侦测的结果(/proc/sys/kernel/modprobe)开始进行ide/scsi/网络/音效等接口设备的侦测,以及利用以加载的核心模块进行PnP装置的参数测试。

5)使用者自订模块的加载
使用者可以在/etc/sysconfig/modules/*.modules加入自订的模块,则此时会被加载到系统当中。

6)加载核心的相关设定
系统会主动去读取/etc/sysctl.conf这个档案的设定值,使核心功能成为我们想要的样子。

7)设定系统时间(clock);
8)设定终端机(console)字形;
9)设定RAID与LVM等硬盘功能
10)以fsck检验磁盘档案系统
11)进行磁盘配额quota的转换(非必要)
12)重新以可读取模式挂载系统磁盘
13)启动quota功能
14)启动系统随机数装置(产生随机数功能)
15)清除开机过程中的临时文件
16)将开机相关信息加载/var/log/dmesg档案中
5.启动系统服务与相关启动设定档
(/etc/rc.d/rc.n&/etc/sysconfig)
接下来,我们还得启动系统所需要的各项服务,依据在/etc/inittab里面提到的run level 设定值,就可以来决定启动的服务项目了。

各个不同的run level服务启动的各个shell script放在/etc/inittab中:
举例来说,run level 3的启动目录就是放在/etc/rc.d/rc3.d目录中,不同的distributions 这个目录可能会有差异。

这个目录下的档案,全部是以S或K为开头,而且全部是连结档案,连结到/etc/rc.d/init.d 里面的shell script。

而在/etc/rc.d/init.d这个目录其实是与/etc/ init.d是一样的,因为这两个目录是连结文件。

在/etc/rc.d/init.d下的shell script都是使用case….esac的语法,而且支持的变量($1)主要有start及stop。

一般,如果想要启动一些系统服务,如启动atd,需使用:
/etc/rc.d/init.d/atd start (也可以用/etc/ init.d/atd start)
如果是关闭服务,就是使用:
/etc/rc.d/init.d/atd stop
如果想要在run level 3的环境下执行某个服务,就是将服务写入/etc/rc.d/rc3.d中,而我们的服务已经在/etc/rc.d/init.d中建立好了,自然可以使用连续的方式连续到/etc/rc.d/rc3.d内的相关shell script啦。

为了解决start或stop这个变量,因此就有了S与K开头的档名了。

在/etc/rc.d/rc3.d内的,以S为开头的档案,开机时,需要【启动,start】的服务;而以K为开关的档案,【为开机时需要关闭的服务,stop】的档案连结。

在S与K后面接的
数字,代表该档案被执行的顺序。

6.使用者自订开机启动程序(/etc/rc.d/rc.local)
在完成run level 3的服务启动后,如果还有其它的动作要完成时,可以用/etc/rc.d/rc.local这个档案执行你想要执行的系统指令。

将它写入到/etc/rc.d/rc.local,该工作就会在开机的时候被自动加载。

7.根据/etc/inittab之设定,加载终端机或X-Window接口
在完成了系统所有服务的启动后,接下来Linux就会启动终端机或是X Window来等待使用者登入:
这一段代表,在run level 2,3,4,5时,都会执行/sbin/mingetty这个东东,而且执行六个,这也是为何我们Linux会提供【六个纯文字终端机】的设定所在了。

要注意的是那个respawan的init动作项目,它代表【当后面的指令被终止(terminal)时,init会主动的重新启动该项目】。

这也是为何我们登入tty1终端机接口后,以exit离开后,系统还是会重新显示等待使用者输入的画面的原因。

而至于我们的run level 5,除了这六个终端机外,init还会执行/etc/Xll/prefdm –nodaemon那个指令。

它主要的功能就是在启动X Window啦。

8.其它开机相关事项
1)关于模块:/etc/modprobe.conf
我们在/etc/rc.d/rc.sysinit中的加载使用者自订模块的地方,就是在/etc/sysconfig/modules/目录下,虽然核心提供的预设模块已经足够我们使用,但某些条件下还是得对模块进行一些参数的规划,此时,就得要使用到/etc/modprobe.conf。

意思是说:我的eth0,代表的是使用8139too这个核心模块,至于snd-card-0则使用snd-via82xx那个模块。

此外,snd-card-0这个模块在使用时,还使用index=0这个参数。

不过,这个档案通常在安装的时候,安装程序就会主动地建立这个档案。

除非你对系统提供的驱动程序模块不满意。

才会主动的修改这个模块加载的相关档案。

2)/etc/sysconfig/*
在整个开机的过程中,老是读取的一些服务的相关设定文件都是记录在/etc/sysconfig 目录下的。

需要注意的是:
●authconfig:
这个档案主要在规范使用者的身份认证,包括加密与否、加密的机制等;
●clock
此档案在设定Linux主机的时区,可以使用格林威治时间(GMT),也可使用台湾本地时间(local)。

基本上,在clock档案内的设定项目【ZONE】所参考的时区位于/usr/share/zoneinfo目录下的相对路径中。

而且要修改时区的话,还是将/usr/share/zoneinfo/Asia/Taipei这个档案复制到/etc/localtime中。

●desktop
这个与预设的X Window的窗口管理员(Window Manager)有关。

在FC4预设是以KDE为主要的WM。

●il8n
它在设定一些语系的使用方面,如文字接口下的日期显示问题。

如果你是以中文安装的,那么预设语系为big5,所以在纯文字接口下,你的档案日期显示就会呈现乱码。

这时更改il8n的档案,将里面的LC_TIME改成en即可。

●network-scripts /
至于network-scripts里面的档案,则是主要用在设定网络卡
9.核心与核心模块
在整个开机的过程中,能够成功驱动主机的硬件配备,是核心(kernel)的工作!而核心一般都是在压缩档,在使用前,需要解压缩才能加载主存储器中。

目前的核心都具有【可读取模块化驱动程序】的功能,就是所谓的模块化的功能。

模块化由硬件开发厂商提供,也有可能我们的核心本来就支持。

以下是核心与核心模块放置的位置:
●核心:/boot/vmlinuz或/boot/vmlinuz-version
●核心解压缩所需RAM Disk:/boot/initrd(/boot/initrd-version)
●核心模块:/lib/modules/version/kernel或/lib/modules/`uname -r` /kernel
●核心原始码:/usr/src/linux(要安装才会有,否则预设不安装)
如果该核心被顺利地加载系统当中,就会有几个信息记录下来:
●核心版本:/proc/version
●系统核心功能:/proc/sys/kernel
如果有个新硬件,而我的操作系统不支持,那就需要重新编译核心,并加入最新的硬件驱动程序原始码;将该硬件的驱动程序编译成模块,在开机是加载该模块
10.核心模块与相依性
基本上,核心的放置处是在/lib/modules/`uname -r` /kernel中,里面主要还分成几个目录:
linux会检查在/lib/modules/`uname -r` /modules.dep这个档案,它记录了在核心支持的模块的各项相依性。

利用depmod就可以建立该档案了。

范例一:若我已经做好一个网络卡驱动程序,假设文件名为 a.ko,该如何更新核心相仿性
难就难在将那个新的驱动程序模块编译出来,然后依据核心模块放置的目录去放置好,然后输入depmod后,去更新好modules.dep,如此,核心就能够认识该模块了。

11.核心模块的观察:lsmod,modinfo
以上显示的内容包括模块名称、模块的大小,此模块是否被其它模块所使用。

举例,上面的表格中,我的ip_conntrack_ftp模块其实还被ip_nat_ftp模拟所使用,也就是说,这两个模块之间应该是有相关性的,所以,如果加载ip_nat_ftp还得要加载ip_conntrack_ftp 才行。

我们还可以用modinfo查阅每个模块的信息:
范例一:由上个表格中,请列出8139too这个模块的相关信息
范例二:我有一个模块名称为a.ko,请问该模块的信息为?
12.核心模块的加载与移除:insmod,modprobe,rmmod
如果想自行手动加载模块,最好是使用modprobe来加载,因为它会主动地去搜寻modules.dep的内容,先克服了模块的相依性后,才决定需要加载的模块有哪些。

至于insmod则完全由使用者自行加载一个完整文件名的模块,并不会主动的分析模块相依性啊!
如果要移除这个模块,则
不过,如前所述,insmod实在不怎么人性化,建议直接使用modprobe来处理模块加载的问题,这个指令的用法是:
范例一:加载smbfs模块
13.核心模块的额外参数设定:/etc/modprobe.conf
如果想要修改某些模块的额外参数设定,就在这个档案内设定。

假设我的网上eth0是使用ne,但eth1同样也使用ne,为了避免同一模块会导致网络卡的错乱,因此,可以先找到eth0与eth1的I/O与IRQ,假设eth0:I/O (0x300)且IRQ=5,eth1:I/O (0x320)且IRQ=7。

则:
如此一来,Linux系统就不会捉错网卡的对应了。

14.Boot loader的功能与意义
我们系统能够使用的Boot loader必须要能够认识我们系统的filesystem才行。

但我们知道,
MBR是整个硬盘的第一个sector,其大小不可能超过512bytes,而loader的功能不可能只占不到512bytes的容量,而且某些情况下,设定档还会占用掉不少的容量呢!
为了解决这个问题,我们将Boot loader分成两个阶段来执行(stage):
Stage 1:第一阶段为Boot loader的主程序,它必须要被安装在开机区,亦即MBR或super block(first sector)。

因为MBR太小,所以,这个stage 1通常仅安装Boot loader的最小主程序,并没有安装loader的相关设定档;
Stage 2:第二阶段为加载Boot loader的所有设定档与相关的环境参数档案。

一般来说,设定档都在/boot底下。

Boot loader除了可以直接指定核心档案来开机外,也可指定某个super block当中的Boot loader接管开机的核心加载流程。

假设我在MBR安装了grub这个同时认识Windows与Linux的档案系统的Boot loader,同时我的/dev/hda2当中的super block也安装了Linux的核心档案放置在/dev/hda2里面的/boot/vmlinuz,那么我的MBR的grub至少可以做到这样:
●直接指定核心(在/dev/hda2的/boot/vmlinuz)来进行开机;
●将控制权交给/dev/hda2 super block当中的grub进行管理
●将控制权交给当中的Windows的loader来管理
值得注意的是,我们的Linux可以选择将Boot loader安装在MBR或者是super block 当中,但是Windows系统则几乎预设强制会同时安装在MBR与super block当中,这也是为什么【我们说要安装多重操作系统时,最好先安装Windows再安装Linux,因为若先安装Linux,则后续安装Windows时,会强制MBR的boot loader覆盖掉,如此我们将无法以Windows的boot loader进入Linux】。

但如果先安装Linux后才安装Windows的话,只要你安装类似spfdisk的软件在MBR 中,就可以用它来进入Linux了。

总之,只要你知道MBR /super block /boot loader之间的相关性,怎么切换都可能。

15.grub的设定档/boot/grub/menu.lst与安装类型
grub是较新的boot loader,它的优点很多,包括:
●认识较多的filesystem,并且可以使用grub的主程序直接在filesystem中搜寻核心;
●开机的时候,可以自行编辑与修改开机设定项目,类似bash的指令模式;
●可以动态搜寻设定文件,而不需要在修改设定档后重新安装grub。

就是我们只要修改
完/boot/grub/menu.lst里头的设定后,下次开机就生效了。

1)与硬盘的关系
既然grub主程序是安装在MBR(super block)中,并且动态去搜寻设定文件的信息,它必须要认识硬盘才行。

而grub对硬盘的代号设定与传统的Linux磁盘代号可完全是不同的,有点像(hd0,0)。

跟/dev/hda1风马牛不相干。

其实只要注意几个东西即可,就是:
●硬盘代号以小括号()包起来
●硬盘以hd表示,后面会接一组数字
●以【搜寻顺序】做为硬盘的编号,而不是依照硬盘排线的排序
●第一个搜寻到的硬盘为0号,第二个为1号,以此类推
●每颗硬盘的第一个partition代号为0,以此类推
在传统的主机板上,通常第一颗硬盘就会是/dev/had,我们可能会误会/dev/had就是(hd0),其实不是,这要看你的BIOS的设定值才行。

有的主机BIOS可以调整开机的硬盘搜寻顺序,因此要注意grub的硬盘代号可能会跟着改变。

整个硬盘代号为:
2)/boot/grub/menu.lst设定档
在title以前的前四行,都是属于grub的整体设定,包括预设的等待时间怀预设的开机项目,还有显示的画面特性等等项目。

至于title后面才是指定开机的核心档案或是boot loader控制权。

在整体设定方面的项目主要常见的有:
●default=0
这个必须要与title作为对照。

按照前后顺序来排列,第一个title代表的是0,第二个title代表的是1,以此类推。

如果开机过程中,没有选择其它的项目,就会用默认值(第一个title)来开机。

●timeout=5
这个是开机时,如果你在几秒内没有按下任何按键,就会用default那个设定值来进行开机!
●splashimage=(hd0,0) /boot/grub/splash.xpm.gz
这个splashimage是在选单上面显示的一些图片或者是相关的影像数据。

上面的设定说的是:在(hd0,0)那个partition内的/boot/grub/splash.xpm.gz档案为开机时显示的画面。

●hiddenmenu
这个是说开机时是否要显示选单。

目前FC4预设是不要显示选单。

整体的设定就是这样,而底下那个title则是显示开机的设定项目。

每个title后面接的是【该开机项目名称的显示】,开机时有两种选择:
1.直接指定核心开机
指定核心开机,要找到核心档案!可能还要用到initrd的RAM Disk设定档案。

我们必须要以grub的硬盘认识方式找出完整的kernel与initrd档名才行。

注意到:kernel后面其实只要接【核心档案文件名】与【根目录(/)的所在磁盘代号(用一般Linux磁盘代号)就可以了】。

以第二个方式来书写你的title的内容会比较好一点,不会造成两个root是啥意思的紊乱。

2.利用chain loader的方式
所谓的chain loader仅是在将控制权交给下一个boot loader而已,所以grub并不需要认识与找出kernel file,也就不需要去查验下一个boot loader的开机扇区。

一般来说,chain loader的设定只要两个就够了,一个是指定开机区的root partition,另一个则是设定chain loader在那个扇区上。

假设我的Windows扇区在/dev/hda1,且我又只有一颗硬盘,那么要grub将控制权交给windows的loader只要这样就够了:
那个root代表Windows的C盘,而chain loader则是加载boot loader的定义值,那个+1代表的是【第一个sector】也就是说成super block。

其它grub还可以隐藏某些partition。

假设我的/dev/hda5是Linux的磁盘系统,我想将它隐藏,并且把原先隐藏的/dev/hda2开启,并且不去检查/dev/hda1的开机区,会变成:
16.测试与安装grub
如果你的系统原来使用的并非grub,那么就需要来安装啦。

首先,你必须要使用grub-install将一些必要的档案复制到/boot/grub去:
范例一:将grub安装在目前系统的/底下,我的系统为/dev/hda
范例二:我的/dev/had挂载到/disk2下,如何安装grub到/dev/hdb?
17.忘记root密码的解决之道
因为FC4进入run level 1是不需要密码的,只要能够进入并且挂载/,然后修改一下/etc/shadow内的root密码栏(第二栏)重新开机后,root就不需要密码即可登入。

整个动作像这样:
●在开机时,按【e】进入详细设定,选择【kernel】那一项,再按【e】进入编修画面,
在最后面加上一个单一的数字【1】,回车后,按下【b】,就可进入run level 1了
●进入Linux后,不需要密码就会是root的身份,立刻vi /etc/shadow,将root所在那
一行的第二个字段给它全部清除,储存后,重新开机。

●重新开机后,以root登入,然后立即设定root新密码。

18.因设定错误而无法开机
通常是/etc/fstab这个档案,尤其是使用者在实作quota时,最容易写错参数,又没有
经过mount –a来测试挂载,重新开机后导致无法开机成功。

我们利用run level 1的方法进行单人模式后,然后利用【mount –n –o remount,rw /】重新挂载根目录,将刚刚设定错误的地方修改一下,就可以重新开机了。

但万一是因为不正常关机,导致开机进行fsck无法成功,而出现类似的几行字:
这表示你的filesystem可能有扇区错乱的情况,一般来说,这样的错误应该不是实体硬盘错误,比较可能是由于不正常关机造成filesystem的不一致所造成的。

我们必须输入root的密码,进行run level 1,然后以fsck /dev/hd[a-d][1-16]来修复磁盘。

这个过程可能会很长,且如果你的partition上面的filesystem有过多的数据损毁时,即使fsck完成后,可能因为伤到系统盘,导致某些关键系统档案数据的损毁,那么依旧无法进入Linux的。

此时,最好将系统中的重要数据复制出来,然后重新安装,并且检验一下,是否实体硬盘有损伤的现象。

不过一般来说,不太可能会这样。

相关文档
最新文档