linux 启动过程

       Linux 启动过程详解

     下面来详细了解一下 Linux 的启动过程。     Linux 的启动
过程包含了 Linux 工作原理的精髓,      而且在嵌入式的开发过程也非常需要这方面知识的积累。
    
     用户开机启动 Linux 过程总体上是这样的:
     首先当用户打开 PC 的电源时,CPU 将自动进入实模式,并从地址 0xFFFF0 开始自
动执行程序代码,这个地址通常是 ROM-BIOS 中的地址。这时 BIOS 进行开机自检,并
按 BIOS 中设置的启动设备(通常是硬盘)进行启动,接着启动设备上安装的引导程序
lilo 或 grub 开始引导 Linux(也就是启动设备的第一个扇区)        ,这时,Linux 才获得了启
动权。
     接下来的第二阶段,Linux 首先进行内核的引导,主要完成磁盘引导、读取机器系统数
据、实模式和保护模式的切换、加载数据段寄存器以及重置中断描述符表等。
     第三阶段执行 init 程序    (也就是系统初始化工作) init 程序调用了 rc.sysinit 和 rc 等程序                                      ,
而 rc.sysinit 和 rc 在完成系统初始化和运行服务的任务后,返回 init。
     之后的第四阶段,init 启动 mingetty,打开终端供用户登录系统,用户登录成功后进入了
Shell,这样就完成了从开机到登录的整个启动过程。
     Linux 启动总体流程图如图所示,  其中的 4 个阶段分别由同步棒隔开。            由于第一阶段
不涉及 Linux 自身的启动过程,因此,下面分别对第二和第三阶段进行详细讲解。

启动过程

               内核引导阶段
     2.2.2
     在 grub 或 lilo 等引导程序成功完成引导 Linux 系统的任务后,Linux 就从它们手中接管
了 CPU 的控制权。用户可以从 www.kernel.org 上下载最新版本的源码进行阅读,其目录为:
linux-2.6.*.*/arch/i386/boot。在这过程中主要用到该目录下的这几个文件:bootsect.S、setup.S
以及 compressed 目录下的 head.S 等。
     首先要介绍一下,Linux 的内核通常是压缩过后的,包括如上述提到的那几个重要的汇
编程序,它们都是在压缩内核 vmlinuz 中的。因为 Linux 中提供的内核包含了众多驱动和功
能,因而比较大,所以在采用压缩内核可以节省大量的空间。
    (1)bootsect 阶段
     当 grub 读入 vmlinuz 后,会根据 bootsect(正好 512bytes)把它自身和 setup 程序段读到
不大于 0x90000 开始的的内存里(注意:在以往的引导协议里是放在 0x90000,但现在有所
变化)   ,然后 grub 会跳过 bootsect 那 512bytes 的程序段,直接运行 setup 里的第一跳指令。就
是说 bzImage 里 bootsect 的程序没有再被执行了, bootsect.S 在完成了指令搬移以后就退出
                                            而
了。之后执行权就转到了 setup.S 的程序中。
                             华清远见<嵌入式 Linux 应用开发班>培训教材
                                《嵌入式 Linux 应用程序开发详解》——第 2 章、Linux 基础命令
   (2)setup 阶段
    setup.S 的主要功能就是利用 ROM BIOS 中断读取机器系统数据,              并将系统参数     (包括内
存、磁盘等)保存到 0x90000~0x901FF 开始的内存中位置。
    此外,setup.S 还将 video.S 中的代码包含进来,检测和设置显示器和显示模式。
    最后,它还会设置 CPU 的控制寄存器 CR0(也称机器状态字)                   ,从而进入 32 位保护模
式运行,并跳转到绝对地址为 0x100000(虚拟地址 0xC0000000+0x100000)处。当 CPU 跳
到 0x100000 时,将执行“arch/i386/kernel/head.S”中的 startup_32。
   (3)head.S 阶段
    当运行到 head.S 时,       系统已经运行在保护模式, head.S 完成的一个重要任务就是将内
                                              而
核解压。     就如本节前面提到的,            内核是通过压缩的方式放在内存中的,        head.S 通过调用 misc.c
中定义的 decompress_kernel()函数,将内核 vmlinuz 解压到 0x100000 的。
    接下来 head.S 程序完成完成寄存器、分页表的初始化工作,但要注意的是,这个 head.S
程序与完成解压缩工作的 head.S 程序是不同的,它在源代码中的位置是 arch/i386/kernel/head.S。
    在完成了初始化之后,head.S 就跳转到 start_kernel()函数中去了。
   (4)main.c 阶段
    start_kernel()是“init/main.c”中的定义的函数,start kernel()调用了一系列初始化函数,
进行内核的初始化工作。要注意的是,在初始化之前系统中断仍然是被屏蔽的,另外内核也
处于被锁定状态,以保证只有一个 CPU 用于 Linux 系统的启动。
    在 start_kernel()的最后,调用了 init()函数,也就是下面要讲述的 INIT 阶段。
    2.2.3 init 阶段
    在加载了内核之后,           由内核执行引导的第一个进程就是 INIT 进程,         该进程号始终是     “1” 。
INIT 进程根据其配置文件“/etc/inittab”主要完成系统的一系列初始化的任务。由于该配置
文件是 INIT 进程执行的惟一依据,因此先对它的格式进行统一讲解。
    inittab 文件中除了注释行外,每一行都有如下格式:
    id:runlevels:action:process
   (1)id
    id 是配置记录标识符,由 1~4 个字符组成,对于 getty 或 mingetty 等其他 login 程序项,
要求 id 与 tty 的编号相同,否则 getty 程序将不能正常工作。
   (2)runlevels
    runlevels 是运行级别记录符,一般使用 0~6 以及 S 和 s。其中,0、1、6 运行级别为系
统保留:0 作为 shutdown 动作,1 作为重启至单用户模式,6 为重启;S 和 s 意义相同,表示
单用户模式,且无需 inittab 文件,因此也不在 inittab 中出现。7~9 级别也是可以使用的,传
统的 UNIX 系统没有定义这几个级别。
    runlevel 可以是并列的多个值,对大多数 action 来说,仅当 runlevel 与当前运行级别匹配
成功才会执行。
   (3)action
    action 字段用于描述系统执行的特定操作,它的常见设置有:initdefault、sysinit、boot、
                            华清远见<嵌入式 Linux 应用开发班>培训教材
                    华清远见——嵌入式培训专家          http://www.farsight.com.cn
bootwait、respawn 等。
     initdefault 用于标识系统缺省的启动级别。当 init 由内核激活以后,它将读取 inittab 中的
initdefault 项,取得其中的 runlevel,并作为当前的运行级别。如果没有 inittab 文件,或者其
中没有 initdefault 项,init 将在控制台上请求输入 runlevel。
     sysinit、boot、bootwait 等 action 将在系统启动时无条件运行,忽略其中的 runlevel。
     respawn 字段表示该类进程在结束后会重新启动运行。
    (4)process
     process 字段设置启动进程所执行的命令。
     以下结合笔者系统中的 inittab 配置文件详细讲解该配置文件完成的功能:
     1.确定用户登录模式
     在“/etc/inittab”中列出了如下所示的登录模式,主要有单人维护模式、多用户无网络模
式、文字界面多用户模式、X-Windows 多用户模式等。其中的单人维护模式(run level 为 1)
是类似于 Windows 中的“安全模式”               ,在这种情况下,系统不加载复杂的模式从而使系统能
够正常启动。        在这些模式中最为常见的是 3 或 5,           其中本系统中默认的为 5,             也就是 X-Windows
多用户模式。
     # 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:5:initdefault:
     2.执行内容/etc/rc.d/rc.sysinit
     在确定了登录模式之后,就要开始将 Linux 的主机信息读入 Linux 系统,其内容就是文
件“/etc/rc.d/rc.sysinit”中的。查看此文件可以看出,在这里确定了默认路径、主机名称、
“/etc/sysconfig/network”中所记录的网络信息等。
     # System initialization.
     si::sysinit:/etc/rc.d/rc.sysinit
     3.启动内核的外挂模块及各运行级的脚本
     在此,主要是选择模块的型态以进行驱动程序的加载。接下来会根据不同的运行级(run
level)加载不同的模块,启动系统服务。
     l0:0:wait:/etc/rc.d/rc 0
     l1:1:wait:/etc/rc.d/rc 1
                           华清远见<嵌入式 Linux 应用开发班>培训教材
                        《嵌入式 Linux 应用程序开发详解》——第 2 章、Linux 基础命令
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值