1加电到BIOShtml
系统加电,BIOS(基本输入输出设备)CMOS(ROM)芯片内代码装载入内存linux
步骤1:上电自检POST(Power-on self test),主要负责检测系统外围关键设备(如:CPU、内存、显卡、I/O、键盘鼠标等)是否正常shell
步骤2:步骤1成功后,便会执行一段小程序用来枚举本地设备并对其初始化。至此,BIOS的任务就完成了,此后将系统启动的控制权移交到MBR部分的代码。小程序
PS: 在我的电脑中,Linux的启动是从0xFFFF0地址开始的网络
BIOS中包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等等ide
2读取主引导设备MBR测试
系统找到BIOS所指定的主引导设备的MBR后,就会将其复制到0×7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到你的电脑,那就是lilo或者grub/spfdisk字体
硬盘的0柱面、0磁头、1扇区称为主引导扇区。它由三个部分组成,主引导程序(Bootloader 446byte)、 硬盘分区表DPT(Disk Partition table 64byte)和分区有效结束标志(55,AA 2byte)magic numberui
磁盘分区表包含如下三部分:spa
1)Partition ID (5:延伸 82:Swap 83:Linux 8e:LVM fd:RAID)
2)Partition起始磁柱
3)Partition的磁柱数量
3启动bootloader
Boot Loader 就是在操做系统内核运行以前运行的一段小程序。经过这段小程序,咱们能够初始化硬件设备、创建内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操做系统内核作好一切准备。
Boot Loader有若干种,其中Grub、Lilo和spfdisk是常见的Loader。
一般状况下,诸如lilo、grub这些常见的引导程序都直接安装在MBR中。咱们以grub为例来分析这个引导过程。
grub引导也分为两个阶段stage1阶段和stage2阶段(有些较新的grub又定义了stage1.5阶段)。
1)stage1:stage1是直接被写入到MBR中去的,这样机器一启动检测完硬件后,就将控制权交给了GRUB的代码。也就是上图所看到的前446个字节空间中存放的是stage1的代码。BIOS将stage1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务很是单纯,仅仅是将硬盘0头0道2扇区读入内存。而0头0道2扇区内容是源代码中的/stage2/start.S,编译后512字节,它是stage2或者stage1_5的入口。而此时,stage1是没有识别文件系统的能力的
[carl@localhost grub]$ hexdump stage1
0000000 48eb 0090 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000030 0000 0000 0000 0000 0000 0000 0000 0203
0000040 00ff 8000 0001 0000 0800 ebfa f607 80c2
0000050 0275 80b2 59ea 007c 3100 8ec0 8ed8 bcd0
0000060 2000 a0fb 7c40 ff3c 0274 c288 f652 80c2
0000070 5474 41b4 aabb cd55 5a13 7252 8149 55fb
0000080 75aa a043 7c41 c084 0575 e183 7401 6637
0000090 4c8b be10 7c05 44c6 01ff 8b66 441e c77c
00000a0 1004 c700 0244 0001 8966 085c 44c7 0006
00000b0 6670 c031 4489 6604 4489 b40c cd42 7213
00000c0 bb05 7000 7deb 08b4 13cd 0a73 c2f6 0f80
00000d0 f084 e900 008d 05be c67c ff44 6600 c031
00000e0 f088 6640 4489 3104 88d2 c1ca 02e2 e888
00000f0 f488 8940 0844 c031 d088 e8c0 6602 0489
0000100 a166 7c44 3166 66d2 34f7 5488 660a d231
0000110 f766 0474 5488 890b 0c44 443b 7d08 8a3c
0000120 0d54 e2c0 8a06 0a4c c1fe d108 6c8a 5a0c
0000130 748a bb0b 7000 c38e db31 01b8 cd02 7213
0000140 8c2a 8ec3 4806 607c b91e 0100 db8e f631
0000150 ff31 f3fc 1fa5 ff61 4226 be7c 7d7f 40e8
0000160 eb00 be0e 7d84 38e8 eb00 be06 7d8e 30e8
0000170 be00 7d93 2ae8 eb00 47fe 5552 2042 4700
0000180 6f65 006d 6148 6472 4420 7369 006b 6552
0000190 6461 2000 7245 6f72 0072 01bb b400 cd0e
00001a0 ac10 003c f475 00c3 0000 0000 0000 0000
00001b0 0000 0000 0000 0000 0000 0000 0000 1224
00001c0 090f be00 7dbd c031 13cd 8a46 800c 00f9
00001d0 0f75 dabe e87d ffc9 97eb 6c46 706f 7970
00001e0 bb00 7000 01b8 b502 b600 cd00 7213 b6d7
00001f0 b501 e94f fee0 0000 0000 0000 0000 aa55
0000200
【外传】定位硬盘的0头0道2扇区的过程:
BIOS将stage1载入内存0x7c00处并执行,而后调用BIOS INIT13中断,将硬盘0头0道2扇区内容载入内存0x7000处,而后调用copy_buffer将其转移到内存0x8000处.在定位0头0道2扇区时一般有两种寻址方式:LBA和CHS
2)、stage2:严格来讲这里还应该再区分个stage1.5的
start.S加载stage1.5:stage1.5它存放在硬盘0头0道3扇区向后的位置,stage1_5做为stage1和stage2中间的桥梁,stage1_5有识别文件系统的能力,此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行
start.S加载stage2:一样,这个stage2也不是/boot分区/boot/grub目录下的stage2,这个时候start.S读取的是存放在/boot分区Boot Sector的stage2。这种状况下就有一个限制:由于start.S经过BIOS中断方式直接对硬盘寻址(而非经过访问具体的文件系统),其寻址范围有限,限制在8GB之内。所以这种状况须要将/boot分区分在硬盘8GB寻址空间以前。
假如是情形2,咱们将/boot/grub目录下的内容清空,依然能成功启动grub;假如是情形1,将/boot/grub目录下stage2删除后,则系统启动过程当中grub会启动失败。
4加载内核
当stage2被载入内存执行时,它首先会去解析grub的配置文件/boot/grub/grub.conf,而后加载内核镜像到内存中,并将控制权转交给内核。而内核会当即初始化系统中各设备并作相关的配置工做,其中包括CPU、I/O、存储设备等。
Linux的内核镜像仅是包含了基本的硬件驱动,在系统安装过程当中会检测系统硬件信息,根据安装信息和系统硬件信息将一部分设备驱动写入 initrd 。这样在之后启动系统时,一部分设备驱动就放在initrd中来加载。
关于Linux的设备驱动程序的加载,有一部分驱动程序直接被编译进内核镜像中,另外一部分驱动程序则是以模块的形式放在initrd(ramdisk)中。
一部分设备驱动就放在initrd中来加载,bootloader initialized RAM disk,就是由 boot loader 初始化的内存盘。
initramfs 是在 kernel 2.5中引入的技术,实际上它的含义就是:在内核镜像中附加一个cpio包,这个cpio包中包含了一个小型的文件系统,当内核启动时,内核将这个 cpio包解开,而且将其中包含的文件系统释放到rootfs中,内核中的一部分初始化代码会放到这个文件系统中,做为用户层进程来执行。这样带来的明显的好处是精简了内核的初始化代码,并且使得内核的初始化过程更容易定制。亲自验证4.7内核采用initramfs,2.6内核两种都有,具体哪种是默认启用的没验证过。
简单浏览一下init脚本的内容,发现它也主要是加载各类存储介质相关的设备驱动程序。当所需的驱动程序加载完后,会建立一个根设备,而后将根文件系统rootfs以只读的方式挂载。这一步结束后,释放未使用的内存,转换到真正的根文件系统上面去,同时运行/sbin/init程序,执行系统的1号进程。此后系统的控制权就全权交给/sbin/init进程了。
5初始化系统
通过千辛万苦的跋涉,咱们终于接近黎明的曙光了。接下来就是最后一步了:初始化系统。/sbin/init进程是系统其余全部进程的父进程,当它接管了系统的控制权先以后,它首先会去读取/etc/inittab文件来执行相应的脚本进行系统初始化,如设置键盘、字体,装载模块,设置网络等.
Linux的运行等级设定以下:
0:关机
1:单用户模式
2:无网络支持的多用户模式
3:有网络支持的多用户模式
4:保留,未使用
5:有网络支持有X-Window支持的多用户模式
6:从新引导系统,即重启
主要包括如下工做:
1)、执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,到此系统算是基本运行起来了,后面须要进行运行级别的肯定及相应服务的启动。rc.sysinit所作的事情(不一样的Linux发行版,该文件可能有些差别)以下:
(1)获取网络环境与主机类型。首先会读取网络环境设置文件"/etc/sysconfig/network",获取主机名称与默认网关等网络环境。
(2)测试与载入内存设备/proc及usb设备/sys。除了/proc外,系统会主动检测是否有usb设备,并主动加载usb驱动,尝试载入usb文件系统。
(3)决定是否启动SELinux。
(4)接口设备的检测与即插即用(pnp)参数的测试。
(5)用户自定义模块的加载。用户能够再"/etc/sysconfig/modules/*.modules"加入自定义的模块,此时会加载到系统中。
(6)加载核心的相关设置。按"/etc/sysctl.conf"这个文件的设置值配置功能。
(7)设置系统时间(clock)。
(8)设置终端的控制台的字形。
(9)设置raid及LVM等硬盘功能。
(10)以方式查看检验磁盘文件系统。
(11)进行磁盘配额quota的转换。
(12)从新以读取模式载入系统磁盘。
(13)启动quota功能。
(14)启动系统随机数设备(产生随机数功能)。
(15)清楚启动过程当中的临时文件。
(16)将启动信息加载到"/var/log/dmesg"文件中。
2)、执行/etc/rc.d/rc脚本。该文件定义了服务启动的顺序是先K后S,而具体的每一个运行级别的服务状态是放在/etc/rc.d/rc*.d(*=0~6)目录下,全部的文件均是指向/etc/init.d下相应文件的符号连接。rc.sysinit经过分析/etc/inittab文件来肯定系统的启动级别,而后才去执行/etc/rc.d/rc*.d下的文件。
/etc/init.d-> /etc/rc.d/init.d
/etc/rc ->/etc/rc.d/rc
/etc/rc*.d ->/etc/rc.d/rc*.d
/etc/rc.local-> /etc/rc.d/rc.local
/etc/rc.sysinit-> /etc/rc.d/rc.sysinit
也就是说,/etc目录下的init.d、rc、rc*.d、rc.local和rc.sysinit均是指向/etc/rc.d目录下相应文件和文件夹的符号连接。咱们以启动级别3为例来简要说明一下。
/etc/rc.d/rc3.d目录,该目录下的内容所有都是以 S 或 K 开头的连接文件,都连接到"/etc/rc.d/init.d"目录下的各类shell脚本。S表示的是启动时须要start的服务内容,K表示关机时须要关闭的服务内容。/etc/rc.d/rc*.d中的系统服务会在系统后台启动,若是要对某个运行级别中的服务进行更具体的定制,经过chkconfig命令来操做,或者经过setup、ntsys、system-config-services来进行定制。若是咱们须要本身增长启动的内容,能够在init.d目录中增长相关的shell脚本,而后在rc*.d目录中创建连接文件指向该shell脚本。这些shell脚本的启动或结束顺序是由S或K字母后面的数字决定,数字越小的脚本越先执行。例如,/etc/rc.d/rc3.d /S01sysstat就比/etc/rc.d/rc3.d /S99local先执行。
3)、执行用户自定义引导程序/etc/rc.d/rc.local。其实当执行/etc/rc.d/rc3.d/S99local时,它就是在执行/etc/rc.d/
rc.local。S99local是指向rc.local的符号连接。就是通常来讲,自定义的程序不须要执行上面所说的繁琐的创建shell增长连接文件的步骤,只须要将命令放在rc.local里面就能够了,这个shell脚本就是保留给用户自定义启动内容的。
4)、完成了系统全部的启动任务后,linux会启动终端或X-Window来等待用户登陆。tty1,tty2,tty3...这表示在运行等级1,2,3,4的时候,都会执行"/sbin/mingetty",并且执行了6个,因此linux会有6个纯文本终端,mingetty就是启动终端的命令。
除了这6个以外还会执行"/etc/X11/prefdm-nodaemon"这个主要启动X-Window
6执行/bin/login程序,进入登陆状态
抛出command line interface,等待用户登陆
至此,系统就启动完毕了。以上分析不到的地方还请各位大虾不吝指正。
参考博文:
http://blog.csdn.net/miss_acha/article/details/50004717
http://blog.chinaunix.net/uid-30565002-id-5540367.html