1.开机流程
grub的过程:
MBR 使用 Linux 的 grub 这个开机管理程式,并且里面假设已经有了三个选单, 第一个选单可以直接指向 Linux 的核心档案并且直接载入核心来开机;第二个选单可以将开机管理程式控制权交给 Windows 来管理,此时 Windows 的 loader 会接管开机流程,这个时候他就能够启动 windows 了。第三个选单则是使用 Linux 在 boot sector 内的开机管理程式,此时就会跳出另一个 grub 的选单啦
2.载入核心
我们可以先看下/boot下面的重要文件
- [root@www ~]# ls --format=single-column -F /boot
- config-2.6.18-92.el5 <==此版本核心被编译时选择的功能与模组设定档
- grub/ <==就是开机管理程式 grub 相关资料目录
- initrd-2.6.18-92.el5.img <==虚拟档案系统档!
- System.map-2.6.18-92.el5 <==核心功能放置到记忆体位址的对应表
- vmlinuz-2.6.18-92.el5 <==就是核心档案啦!最重要者!
Linux 核心是可以透过动态载入核心模块的 (就请想成驱动程式即可),这些核心模块就放置在 /lib/modules/ 目录内,但问题是USB, SATA, SCSI... 等硬盘设备的驱动程序通常都是以模块的方式存在的,如果没有SATA的驱动,就无法识别硬盘挂载根目录,也就无法去读取驱动模块。那怎么办呢?可以透过虚拟文件系统来处理这个问题。
虚拟文件系统 (Initial RAM Disk) 一般使用的档名为 /boot/initrd ,这个文件的特色是,他也能够透过 boot loader 来载入到记忆体中, 然后这个文件会被解压缩并且在记忆体当中模拟成一个根目录, 且此模拟在内存当中的文件系统能够提供一支可执行的程序,透过该程序来载入开机过程中所最需要的核心模块, 通常这些模块就是 USB, RAID, LVM, SCSI 等文件系统与硬盘介面的驱动程序啦!等载入完成后, 会帮助核心重新呼叫 /sbin/init 来开始后续的正常开机流程
不过,如果用的是IDE硬盘,不需要initrd也可以开机。
当核心完整载入后,就要开始执行系统的第一支程序: /sbin/init
/sbin/init 最主要的功能就是准备软体执行的环境,包括系统的主机名称、网路设定、语系处理、档案系统格式及其他服务的启动等。 而所有的动作都会透过 init 的设定档,亦即是 /etc/inittab 来规划,而 inittab 内还有一个很重要的设定项目,那就是预设的 runlevel (开机执行等级)
run level 分为 7 个等级,分别是:
/etc/inittab 会使用 /etc/rc.d/rc.sysinit 进行系统初始化,
使用/etc/rc.d/rc N 这个命令来启动不同level下的服务,etc/rc.d/rc 这个文件:
/etc/rc5.d/[SK]xx 都是链接文件,其实就是 /etc/init.d/ 相对应的服务脚本
使用/etc/rc.d/rc.local来打开使用者自定义开机启动程序
开机过程中会使用到的配置文件
/etc/modprobe.conf, 关于模块的,系统自动产生,一般不需要手动修改
/etc/sysconfig/* ,里面有很多配置信息
Run level 的切换
3.核心与核心模块
在整个开机的过程当中,是否能够成功的驱动我们主机的硬体配备,是核心 (kernel) 的工作!而核心一般都是压缩档,因此在使用核心之前,就得要将他解压缩后, 才能载入主记忆体当中。
另外,为了应付日新月异的硬体,目前的核心都是具有‘可读取模块化驱动程序’的功能, 亦即是所谓的‘ modules (模块化)’的功能啦!所谓的模组化可以将他想成是一个‘外挂程式’, 该外挂程式可能由硬体开发厂商提供,也有可能我们的核心本来就支援~不过,较新的硬体, 通常都需要硬体开发商提供驱动程式模组啦!
那么核心与核心模块放在哪?
如果我有个新的硬体,偏偏我的操作系统不支援,该怎么办?很简单啊!
核心模组与相依性:
要处理核心模组,自然就得要了解我们核心提供的模块之间的相关性,核心模组的放置处是在 /lib/modules/$(uname -r)/kernel 当中,里面主要还分成几个目录:
- arch :与硬件平台有关的项目,例如 CPU 的等级等等;
- crypto :核心所支援的加密的技术,例如 md5 或者是 des 等等;
- drivers :一些硬体的驱动程式,例如显示卡、网路卡、PCI 相关硬体等等;
- fs :核心所支援的 filesystems ,例如 vfat, reiserfs, nfs 等等;
- lib :一些函式库;
- net :与网路有关的各项协定资料,还有防火墙模组 (net/ipv4/netfilter/*) 等等;
- sound :与音效有关的各项模组;
- [root@www ~]# modprobe [-lcfr] module_name
- 选项与参数:
- -c :列出目前系统所有的模组!(更详细的代号对应表)
- -l :列出目前在 /lib/modules/`uname -r`/kernel 当中的所有模组完整档名;
- -f :强制载入该模组;
- -r :类似 rmmod ,就是移除某个模组��~
- 范例一:载入 cifs 模组
- [root@www ~]# modprobe cifs
- # 很方便吧!不需要知道完整的模组档名,这是因为该完整档名已经记录到
- # /lib/modules/`uname -r`/modules.dep 当中的缘故啊!如果要移除的话:
- [root@www ~]# modprobe -r cifs
/lib/modules/$(uname -r)/modules.dep 这个档案记录了在核心支援的模组的各项相依性。利用 depmod 这个指令可以建立(更新)该档案
- [root@www ~]# depmod [-Ane]
- 选项与参数:
- -A :不加任何参数时, depmod 会主动的去分析目前核心的模组,并且重新写入
- /lib/modules/$(uname -r)/modules.dep 当中。若加入 -A 参数时,则 depmod
- 会去搜寻比 modules.dep 内还要新的模组,如果真找到新模组,才会更新。
- -n :不写入 modules.dep ,而是将结果输出到萤幕上(standard out);
- -e :显示出目前已载入的不可执行的模组名称
- 范例一:若我做好一个网路卡驱动程式,档名为 a.ko,该如何更新核心相依性?
- [root@www ~]# cp a.ko /lib/modules/$(uname -r)/kernel/drivers/net
- [root@www ~]# depmod
核心模块的观察:
查看目前核心载入了多少的模块 :lsmod
查看模块的详细信息
- [root@www ~]# modinfo [-adln] [module_name|filename]
- 选项与参数:
- -a :仅列出作者名称;
- -d :仅列出该 modules 的说明 (description);
- -l :仅列出授权 (license);
- -n :仅列出该模组的详细路径。
核心模块的载入与移除:
insmod和rmmod两个命令可以载入和移除,但是insmod不会分析模块的依赖关系,而且这两个命令必须要自行找到模组的完整档名才行,不是很方便。
- [root@www ~]# modprobe [-lcfr] module_name
- 选项与参数:
- -c :列出目前系统所有的模组!(更详细的代号对应表)
- -l :列出目前在 /lib/modules/`uname -r`/kernel 当中的所有模组完整档名;
- -f :强制载入该模组;
- -r :类似 rmmod ,就是移除某个模组��~
- 范例一:载入 cifs 模组
- [root@www ~]# modprobe cifs
- # 很方便吧!不需要知道完整的模组档名,这是因为该完整档名已经记录到
- # /lib/modules/`uname -r`/modules.dep 当中的缘故啊!如果要移除的话:
- [root@www ~]# modprobe -r cifs
因为他是直接去搜寻 modules.dep 的纪录, 所以可以克服模组的相依性问题,而且还不需要知道该模组的详细路径
4.Boot Loader: Grub
boot loader 是载入内核的重要工具,没有 boot loader 的话,那么 kernel 根本就没有办法被系统载入。grub是目前最流行的boot loader。
在 BIOS 读完信息后,接下来就是会到第一个开机装置的 MBR 去读取 boot loader 了。这个 boot loader 可以具有选单功能、直接载入核心档案以及控制权移交的功能等, 系统必须要有 loader 才有办法载入该作业系统的核心就是了。但是我们都知道, MBR 是整个硬盘的第一个 sector 内的一个区块,充其量整个大小也才 446 bytes 而已。 我们的 loader 功能这么强,光是程序代码与设定资料不可能只占不到 446 bytes 的容量吧?那如何安装?
为了解决这个问题,所以 Linux 将 boot loader 的程序执行与设定值载入分成两个阶段 (stage) 来执行:
initrd 的重要性与建立新 initrd 档案:
initrd的目的在于提供开机过程中所需要的最重要核心模组,以让系统开机过程可以顺利完成。 会需要 initrd 的原因,是因为核心模组放置于 /lib/modules/$(uname -r)/kernel/ 当中, 这些模组必须要根目录 (/) 被挂载时才能够被读取。但是如果核心本身不具备磁碟的驱动程式时, 当然无法挂载根目录,也就没有办法取得驱动程式,因此造成两难的地步。
initrd 可以将 /lib/modules/.... 内的‘开机过程当中一定需要的模组’包成一个档案 (档名就是 initrd), 然后在开机时透过主机的 INT 13 硬件功能将该档案读出来解压缩,并且 initrd 在记忆体内会模拟成为根目录。
如果��有特殊需要所以想重制 initrd 档案的话, 可以使用 mkinitrd 来处理的。
- [root@www ~]# mkinitrd [-v] [--with=模组名称] initrd档名 核心版本
- 选项与参数:
- -v :显示 mkinitrd 的运作过程
- --with=模组名称:模组名称指的是模组的名字而已,不需要填写档名。举例来说,
- 目前核心版本的 ext3 档案系统模组为底下的档名:
- /lib/modules/$(uname -r)/kernel/fs/ext3/ext3.ko
- 那��应该要写成: --with=ext3 就好了 (省略 .ko)
- initrd档名:��所要建立的 initrd 档名,尽量取有意义又好记的名字。
- 核心版本 :某一个核心的版本,如果是目前的核心则是‘ $(uname -r) ’