Linux系统启动流程

        我们从按下电脑电源键开始说起。

        (1) 首先是主板BIOS通电自检。按照《微机原理》课本上的说法,CS寄存器被置为0xFFFF,其它寄存器清零,因此CPU从FFFF:0000H处开始执行,这里保存的是跳转指令,跳转到固化在ROM中的自检程序处。于是对系统硬件包括内存进行自检。

        当BIOS检查到硬件正常并且与CMOS的设置相符后,按照CMOS 中对启动设备的设置顺序检测可用的启动设备。

        (2) 假设从硬盘启动,BIOS首先将硬盘的MBR区读入内存,检查MBR结束标记,如果为0x55AA表示找到有效的MBR信息(如果不为0x55AA就检查下一个启动设备),在硬盘MBR区找到系统引导程序执行。

        MBR指Master Boot Record,它在硬盘的三维地址(柱面,磁头,扇区) == (0, 0, 1)。一般硬盘1个扇区为512字节。MBR区开头440个字节是代码区,保存的是第1阶段引导代码,主要作用是检查硬盘分区表是否正确并在完成硬件自检后将控制权交给硬盘上的系统引导程序如GRUB(Windows是nt-loader)。

        然后是标准MBR硬盘分区表,占64个字节,每个主分区表信息占用16Byte,包括可引导标志、文件系统格式、分区开始和结束的磁头号扇区号柱面号、总的扇区数等。因此最多只能划分4个主分区,为了支持更多的分区,于是有了扩展分区和逻辑分区的概念,一个扩展分区可以再分为多个逻辑分区。扩展分区的入口占用MBR区16Byte也就是顶替了1个主分区,扩展分区的入口放着逻辑分区表,其中保存每个逻辑分区的入口。综上,扩展分区最多1个而且要再划分逻辑分区才可以使用,主分区 + 扩展分区最多4个,一个扩展分区中可以划分N多个逻辑分区(上限貌似是64,一般用不了这么多)。

        最后是结束标记字,如果是0x55AA表示MBR信息有效。

        (3) MBR中的引导程序将控制权交给GRUB后,GRUB引导Linux内核,然后启动init进程。

        GRUB完成引导任务后,CPU控制权交给Linux,开始执行LInux的核心映象代码,开始了Linux启动过程。这会用到Linux源码树中arch/i386/boot/下的几个文件。

        因为Linux内核提供了众多的驱动显得比较大,所以在内核编译中常使用"makebzImage"选项生成压缩的内核vmlinuz。在Linux引导过程中由arch/i386/boot/compressed/下的head.S将内核镜像vmlinuz解压到0x100000。

        arch/i386/boot/下的setup.S将BIOS中的内存、磁盘等系统参数拷贝到内存中,以便这些参数后面被保护模式的代码读取,然后setup.S将系统切换到保护模式并跳转到0x100000即vmlinuz的入口。然后CPU跳转init/main.c中的start_kernel(),该函数调用一系列的初始化函数完成kernel本身的设置,建立Linux核心环境。start_kernel()最后调用init(),系统创建第一个核心线程。

        核心线程init()调用do_basic_setup(),该函数完成外设及其驱动程序的加载和初始化,并完成文件系统初始化和root文件系统的安装。之后init()打开/dev/console设备,重定向stdin, stdout, stderr到控制台。最后,核心线程init()搜索文件系统中的init程序,并使用execve()系统调用加载执行init程序。至此init()函数结束,内核引导部分也结束了。

        (4) init调用rc.sysinit和rc。rc.sysinit和rc完成系统初始化和启动各种服务的任务后返回init。

        init进程号为1,是系统所有进程的起点。init进程读取配置文件/etc/inittab,该文件指定了系统启动时默认的运行级别以及init进程要调用的初始化脚本。

        init进程首先执行/etc/rc.d/rc.sysinit。该脚本是每个运行级别都要首先运行的重要脚本,完成一些系统初始化工作:激活swap交换分区,检查磁盘,加载硬件模块等。

        然后init进程以运行级别为参数执行/etc/rc.d/rc脚本。假设当前运行级别为5 : X11,rc脚本会执行/etc/rc.d/rc5.d/下所有的rc启动脚本,这些脚本实际上都是符号链接,指向/etc/rc.d/init.d/中的启动脚本。/etc/rc.d/rc5.d/中的rc启动脚本通常是K或S开头的链接文件。对于以以S开头的启动脚本,将以start参数来运行;而如果发现K打头的链接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。

        此时基本的系统环境已经设置好,各种守护进程也已经启动。

        (5) 建立终端,登陆系统。

        按照/etc/inittab文件,下一步init能在2、3、4、5四个运行级别下以respawn方式运行mingetty程序打开6个终端,同时mingetty程序还会显示一个文本登陆界面。

        runlevel 5 : X11下显示的是图形登陆界面,登陆成功后进入GNOME窗口管理器。下面还是以文本登陆方式讲解。

        Linux的帐号验证程序是login,login接收从mingetty传来的用户名作为用户名参数,在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其它信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,将默认为根目录;如果没有指定shell,将默认为/bin/bash。

        login程序成功后,会向对应的终端输出最近一次登录的信息(在/var/log/lastlog中有记录),并检查用户是否有新邮件(在/usr/spool/mail/用户名目录下)。然后开始设置各种环境变量:对bash而言,系统首先查找/etc/profile脚本并执行之,然后在用户的主目录下查找.bash_profile文件,如果有就执行它。在这两个脚本可能还调用了其他配置文件,所有的配置文件执行完之后,各种环境变量也设好了,这时会出现大家熟悉的commandline prompt。

        到此整个启动过程就结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值