开机加载简介
开机过程指的是从打开计算机电源直到LINUX显示用户登录画面的全过程。分析LINUX开机过程也是深入了解LINUX核心工作原理的一个很好的途径。
常规加载流程
1、加载BIOS
打开计算机电源,首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息等等。
之后,计算机就知道应该去读取哪个硬件设备了。在BIOS将系统的控制权交给硬盘第一个扇区之后,就开始由Linux来控制系统了
2、读取MBR
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,大小是512字节,可里面却存放了预启动信息、分区表信息。
可分为两部分:第一部分为引导(PRE- BOOT)区,占了446个字节;第二部分为分区表(PARTITION PABLE),共有66个字节,记录硬盘的分区信息。预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。
系统找到BIOS所指定的硬盘的MBR后,就会将其复制到0×7c00地址所在的物理内存中。被复制到物理内存的内容就是Boot Loader,到计算机系统层面那就是lilo或者grub了。
3、boot loader
Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好准备。
grub做为引导系统的最常用的程序之一,我们有必要去了解一下,下面是我们AX3 SP3的grub引导文件
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/hda2
initrd /initrd-version.img
#boot=/dev/hda
default=0 #此项为默认以启动第一个title
timeout=5 #等待五秒
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Asianux Server 3 (Quartet SP4) (2.6.18-194.13.AXS3)
root (hd0,0) #指定系统的根在hd0,0 即(第一块设备的第一个分区)
kernel /vmlinuz-2.6.18-194.13.AXS3 ro root=LABEL=/ #指定kernel文件
initrd /initrd-2.6.18-194.13.AXS3.img #指定initrd文件
4、加载内核
init依据inittab文件来设定运行等级
核心加载之后,由核心执行的第一个程序就是 /sbin/init,而这个程序第一个目标当然就是确定主机是要以怎样的情况登入!这个就必须要以 /sbin/init 来加载 /etc/inittab 的信息!
/etc/inittab有下面一段内容,说明了各个终端的作用,以及默认进入的终端方式
Default runlevel. The runlevels used by RHS are:
0 - halt (Do NOT set initdefault to this)
1 - Single user mode
2 - Multiuser, without NFS (The same as 3, if you do not have networking)
3 - Full multiuser mode
4 - unused
5 - X11
6 - reboot (Do NOT set initdefault to this)
id:3:initdefault:
根据上面的信息我们了解到:
0:关机
1:单用户登陆模式
2:多用户登陆,跟3相仿,但是没有网络
3,多用户登陆字符模式
4,暂不被使用
5,进入X11 图形界面
6,重启系统
"id:3:initdefault:" 此项设置为系统默认进入的终端模式,不要设置0和6模式,否则系统将不能启动或者一直重启
init进程执行rc.sysinit
在设定了运行等级后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。
/etc/rc.d/rc.sysinit大致做了以下内容:
-
设定预设路径:( PATH )
-
设定网络状态:系统会读取 /etc/sysconfig/network
-
启动swap交换分区
-
检查文件系统:系统会去检查一些可能会存在的目录,例如 /fsckoptions 与 /forcfsck 及 /fastboot
等等的目录,当系统有不正常关机的现象时(例如突然的断电等等),那么 Linux 将会自动的强制
去检查 root 的档案系统 ( checking root filesystems )。
-
清除 /etc/mtab ;
-
mount root 及 /proc 档案系统
7.检查档案系统 :与前面相同的,当前面的 /fastboot 检查的,就会以 fsck 检查你的其它扇区 ( 使用 fsck )
8.挂上其它档案系统
9.设定 console 字型
10.打开 quota
11.清除不必要的档案, 如 lock, pid
12.设定 clock
13.serial port 初始化
14.将开机讯息经由 dmesg 放入 /var/log/dmesg 中
5、启动内核模块
执行不同运行级别的脚本程序
当系统执行完/etc/rc.d/rc.sysinit之后,/etc/inittab会指引系统去运行rc0.d到rc6.d中的相应的脚本程序
进入/etc/rc.d/rc3.d/目录下,我们会发现很多K或者S开头的链接到../init.d/的脚本文件,实际我们执行的是/etc/rc.d/init.d里的脚本文件
执行 ls -l输出结果为:
lrwxrwxrwx 1 root root 15 2011-11-02 S05kudzu -> ../init.d/kudzu
需要注意的是:S为开机需要加载执行的脚本文件,K为开机不需要加载执行的脚本文件,数字为优先级,优先级越小,越先执行.
我们可以用chkconfig来管理它的运行状态.
执行/etc/rc.d/rc.local
你如果打开了此文件,里面有一句话,读过之后,你就会对此命令的作用一目了然:
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.
rc.local就是在一切初始化工作后,Linux留给用户进行个性化的地方。你可以把你想设置和启动的东西放到这里。
执行/bin/login程序,进入登录状态
此时,系统已经进入到了等待用户输入username和password的时候了,你已经可以用自己的帐号登入系统了。
6、环境变量加载
加载顺序说明
在刚登录Linux时,首先启动 /etc/profile 文件,然后再启动用户目录下的 ~/.bash_profile 如果 ~/.bash_profile文件存在的话,因为在 ~/.bash_profile文件中一般会有下面的代码:
if [ -f ~/.bashrc ] ; then
. ./bashrc
fi
所以会执行 ~/.bashrc文件。 并且~/.bashrc中,一般还会有以下代码:
if [ -f /etc/bashrc ] ; then
. /bashrc
fi
所以,~/.bashrc会调用 /etc/bashrc文件。最后,在退出shell时,还会执行 ~/.bash_logout文件。
执行顺序为:/etc/profile -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc -> ~/.bash_logout
关于各个文件的作用域,在网上找到了以下说明:
(1)/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置。
(2)/etc/bashrc: 为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取。
(3)~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件。
(4)~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。
(5)~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件. 另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承 /etc/profile中的变量,他们是"父子"关系。
(6)~/.bash_profile 是交互式、login 方式进入 bash 运行的~/.bashrc 是交互式 non-login 方式进入 bash 运行的通常二者设置大致相同,所以通常前者会调用后者