Fedora 启动顺序

fedora 系统加电或复位后,中央处理器将内存中的所有数据清零,并对内存进行校验。如果没有错误,则CS(Code Segment)寄存器中全部置1,而IP(Instruction Pointer)寄存器中全部置0。[CS]:[IP]地址单元中存储的指令是一条跳转指令,这条指令跳转到BIOS代码的首部。CPU就根据CS及IP 的值进入BIOS启动过程。

一、BIOS
  • 当微机接通电源后,系统将有一个对内部各个设备进行检查的过程,这是由一个通常称之为POST(Power On Self Test,上电自检)的程序来完成的。这也是BIOS的一个功能。BIOS系统设置程序 微机部件配置情况是放在一块可读写的CMOS RAM芯片中的,BIOS ROM将按照系统CMOS设置中的启动顺序搜寻软硬盘驱动器及CDROM、网络服务器等有效的启动驱动器,读入操作系统引导记录,然后将系统控制权交给引 导记录,由引导记录完成系统的启动。所以有时候启动机子起不来,声卡解压卡显示卡发生冲突;CD-ROM挂不上;不能正常运行一些在DOS、 Windows 3.x下运行得很好的程序,可能和BIOS有密切关系。
二、Boot Loader
  • BIOS 会记录可用來开机的裝置搜索顺序!所以,系統会开始去读取第一个开机裝置上面开机程序。首先第一个要读取的就是该硬盘的主要开机磁区 (Master Boot Record, MBR) 了,而系统可以由主要开机区所安裝的开机引导程序 (boot loader) 开始执行核心程序。 *简单地说,Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状 态,以便为最终调用操作系统内核准备好正确的环境。

通常,Boot Loader 是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的 Boot Loader 几乎是不可能的。不过它们仍有一些共性。

  • 怎么会执行先执行Boot Loader呢?
  • 系统加电或复位后,所有的CPU 通常都从某个由 CPU 制造商预先安排的地址上取指令, 取它的第一条指令(BIOS)。而基于CPU 构建的嵌入式系统通常都有某种类型的固态存储设备(比如:ROM、EEPROM 或 FLASH 等)被映射到这个预先安排的地址上。BIOS会将MBR的Boot Loader调至内存0x07C00处,检查 0x0000:7DEF 是不是等于0xAA55,如果不等于则去尝试其他启动介质,如果没有其他启动介质就显示"No ROM BASIC",然后死机。 CPU会读取内存0x07C00处代码,执行。因此在系统加电后,CPU 将执行Boot Loader 程序。
  • 硬盘的0磁道的第一个扇区称为MBR(Master Boot Recorder),它的大小是512字节。Boot Loader通常是一段汇编代码,存放在MBR中,作用是将系统启动代码读到内存中,目前主流的Boot loader有grub, lilo, 还有spfdisk.

下面系统要做的工作就是顺着启动的代码一步步执行。对于Linux源代码来说启动的代码流程如图1所示:

  • Bootsect.S用于装载核心系统和setup.S。 setup.S是用汇编语言写的程序代码。Setup.S对已调入内存内核代码进行检查,如果没有错误的话,它会通过BIOS中断获取内存容量信息、设置 显示器基本模式、获取硬盘信息,这些操作,都是在X86的实模式下进行的,这时操作系统就准备让CPU进入保护模式。进入保护模式的启动阶段的同时把控制 权交给head.S,head.S是段保护模式的汇编程序。Head.S进行页表初始化、检查CPU类型后,调用/init/main.c中的 start_kernel()。Start_kernel()用于和处理器、内存等最基本硬件相关部分的初始化、与中断有关的初始化、对Linux文件系 统进行初始化。
  • 内核映像一般都是经过压缩的,压缩以后的内核映像就像是一大块数据,跟引导扇区和引导辅助程序的映像拼接在一起,成为内核的“引导映 像”。解除压缩以后的内核映像总是放在地址为0x100000(1MB)的地方。Linux核心加载后,由init进程初始化硬件和设备驱动,然后在后台 运行init进程。init进程是系统的第一个进程,init进程运行时将用到两个重要的系统引导配置文件/etc/inittab和 /etc/rc.d。
三、Initrd
  • 为什么要单独把initrd拿出来当成单独的一步呢?呵呵,因为initrd相当的重要,没有这个或者有点错误就无法启动文件系统 同时在上面的过程中会借助Boot loader来载入initrd ,用 initrd来制作虚拟硬盘(RAM Disk)并且利用linuxrc这支程序来进行模组的载入。 linuxrc 主要的特性是:
  • 必须是 linuxrc 这个档名;
  • 必须放置在 initrd 所建立的虚拟磁碟的最顶层目录;
  • 必须要可以被核心所执行。
  • initrd(boot loader initialized RAM disk)在 linux内核启动前, boot loader 会将存储介质中的 initrd 文件加载到内存,内核启动时会在访问真正的根文件系统前先访问该内存中的 initrd 文件系统。在 boot loader 配置了 initrd 的情况下,内核启动被分成了两个阶段,第一阶段先执行 initrd 文件系统中的"某个文件",完成加载驱动模块等任务,第二阶段才会执行真正的根文件系统中的 /sbin/init 进程。
    2.4版的initrd和2.6版的initrd是不一样的:
  • 为了使读者清晰的了解Linux2.6内核initrd机制的变化,在重点介绍Linux2.6内核initrd之前,先对 linux2.4内核的 initrd进行一个简单的介绍。Linux2.4内核的initrd的格式是文件系统镜像文件,本文将其称为image-initrd,以区别后面介绍 的linux2.6内核的cpio格式的initrd。 linux2.4内核对initrd的处理流程如下:
    • 1. boot loader把内核以及/dev/initrd的内容加载到内存,/dev/initrd是由boot loader初始化的设备,存储着initrd。
    • 2. 在内核初始化过程中,内核把 /dev/initrd 设备的内容解压缩并拷贝到 /dev/ram0 设备上。
    • 3. 内核以可读写的方式把 /dev/ram0 设备挂载为原始的根文件系统。
    • 4. 如果 /dev/ram0 被指定为真正的根文件系统,那么内核跳至最后一步正常启动。
    • 5. 执行 initrd 上的 /linuxrc 文件,linuxrc 通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动, 以及加载根文件系统。
    • 6. /linuxrc 执行完毕,真正的根文件系统被挂载。
    • 7. 如果真正的根文件系统存在 /initrd 目录,那么 /dev/ram0 将从 / 移动到 /initrd。否则如果 /initrd 目录不存在, /dev/ram0 将被卸载。
    • 8. 在真正的根文件系统上进行正常启动过程 ,执行 /sbin/init。 linux2.4 内核的 initrd 的执行是作为内核启动的一个中间阶段,也就是说 initrd 的 /linuxrc 执行以后,内核会继续执行初始化代码,我们后面会看到这是 linux2.4 内核同 2.6 内核的 initrd 处理流程的一个显著区别。
  • Linux2.6 内核对 Initrd 的处理流程
  • linux2.6 内核支持两种格式的 initrd,一种是前面第 3 部分介绍的 linux2.4 内核那种传统格式的文件系统镜像-image-initrd,它的制作方法同 Linux2.4 内核的 initrd 一样,其核心文件就是 /linuxrc。另外一种格式的 initrd 是 cpio 格式的,这种格式的 initrd 从 linux2.5 起开始引入,使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init,本文将这种 initrd 称为 cpio-initrd。尽管 linux2.6 内核对 cpio-initrd和 image-initrd 这两种格式的 initrd 均支持,但对其处理流程有着显著的区别,下面分别介绍 linux2.6 内核对这两种 initrd 的处理流程。 cpio-initrd 的处理流程
    • 1. boot loader 把内核以及 initrd 文件加载到内存的特定位置。
    • 2.内核判断initrd的文件格式,如果是cpio格式。
    • 3. 将initrd的内容释放到rootfs中。
    • 4. 执行initrd中的/init文件,执行到这一点,内核的工作全部结束,完全交给/init文件处理。
  • image-initrd的处理流程
    • 1. boot loader把内核以及initrd文件加载到内存的特定位置。
    • 2. 内核判断initrd的文件格式,如果不是cpio格式,将其作为image-initrd处理。
    • 3. 内核将initrd的内容保存在rootfs下的/initrd.image文件中。
    • 4. 内核将/initrd.image的内容读入/dev/ram0设备中,也就是读入了一个内存盘中。
    • 5. 接着内核以可读写的方式把/dev/ram0设备挂载为原始的根文件系统。
    • 6. .如果/dev/ram0被指定为真正的根文件系统,那么内核跳至最后一步正常启动。
    • 7. 执行initrd上的/linuxrc文件,linuxrc通常是一个脚本文件,负责加载内核访问根文件系统必须的驱动, 以及加载根文件系统。
    • 8. /linuxrc执行完毕,常规根文件系统被挂载
    • 9. 如果常规根文件系统存在/initrd目录,那么/dev/ram0将从/移动到/initrd。否则如果/initrd目录不存在, /dev/ram0将被卸载。
    • 10. 在常规根文件系统上进行正常启动过程 ,执行/sbin/init,init程序执行后,它会成为所有启动程序的父进程,而后执行一连串的程序及Script。 通过上面的流程介绍可知,Linux2.6内核对image-initrd的处理流程同linux2.4内核相比并没有显著的变化, cpio-initrd的处理流程相比于image-initrd的处理流程却有很大的区别,流程非常简单,在后面的源代码分析中,读者更能体会到处理的 简捷

四、Init

  • 1 .执行/etc/inittab.  init会根据设定档运行不同的run level,根据不同的run level会在开机时启动不同的服务.
    在inittab里的格式是这样的:
    id:runlevels:action:process

有以下几种run level:

# 0 - 停机(千万不能把initdefault 设置为0 )

# 1 - 单用户模式

# 2 - 多用户,没有 NFS

# 3 - 完全多用户模式(标准的运行级)

# 4 - 预设保留

# 5- X11 (xwindow)

# 6 - 重新启动 (千万不要把initdefault 设置为6 )

常用的是3 和5 模式 其中3 是文字模式,含有网络功能,2 模式比3少了网络功能,5 是桌面模式,也是最常用的,跟windows的桌面模式很像,如果习惯了windows的用户,建议使用这种模式。

init启动时,它会在/etc/inittab内查找一个代码行,这一行指定了默认的运行级别:

id : 5 : initdefault : 这一行指出了默认情况下是启动5模式

根据inittab里的设定资料,会启动相应的服务,最先运行的服务是放在/etc/rc.d 目录下的文件。在大多数的Linux 发行版本中,启动脚本都是位于 /etc/rc.d/init.d中的。这些脚本被用ln 命令连接到 /etc/rc.d/rc*.d 目录。(这里的* 就是运行级0-6)

有关设定档inittab 内的具体内容可以查相关资料,这里不做解释

  • 2.接下来init 执行 /etc/rc.d/rc.sysinit 档案,这个档案主要是为我们设定好系统环境,例如环境变量,设置系统时间,设定终端字形,清楚开机过程中的暂存档,载入模组等,做的事情还是挺多的。

  • 3.服务,一般是放在/etc/init.d/下,也有的放在/etc/xinetd.d,放在这俩个目录下去的区别是,在 /etc/init.d/下的是一直存在于内存中,也就是说开机就启动的,在 /etc/xinet.d/下的是用的时候才启动的,其设定档为/etc/xinetd.conf。
    • 现在来了解一下在/etc/init.d/下的服务,这里面就保存了所有的开机启动服务,不管是在什么模式下,每个模式下开机所启动的 服务是不一样的,比如是5模式,我们就到/etc/rc.d/rc5.d/查看,里面的脚本的名字都有点怪,都是K(S)**name,不适以K开头就是 以S开头,以S开头的表示开机时要启动的服务,K开头的是表示开机时不启动的服务,后面接的两位数字表示,开机时服务执行的顺序,跟nice值有点像,都 是越小越先被执行。
    • 为什么以S开头就要被执行,以K开头的服务将不被启动呢?
    • 在inittab里有类似这样一句
    • l5:5:wait:/etc/rc.d/rc 5
    • 当然还有几句和它类似,上面这句表示在5模式执行:"/etc/rc.d/rc 5"这样一条命令,脚本rc里有两个for循环分别指出了要启动以S开头的服务,要关闭以K开头的服务,因为这时还没有启动登录界面,所以刚启动的服务就 变成了开机启动服务了。rc里的内容可以自己去参考一下。
    • 如果要想开机启动自定义程序,可以去修改/etc/rc.d/rc.local,因为这个是shell登录界面启动前的最后执行的脚本。这样即使你开始忘了在哪个脚本里关闭了某个程序,使它在开机时无法运行,你可以在这里面写,因为它是最后被执行的。
    • 如果你自己写了一个程序,要想在开机时也像/etc/rc.d/rc.d/下的服务一样,用那种方法启动它,你可以用chkconfig这个指令。也可以用man chkconfig参考一下用法
    • 最重要的一点,比如你写了一个脚本liuwenhan,那里面的格式要像下面的格式
      #!/bin/bash
      # chkconfig:35 80 70
      #接下来就是写你所需要的内容
    • 注意上面的第二行是很重要的,必须按上面的格式写一下, 在#和chkconfig之间是至少隔一个空格键,且要把写好的脚本放在/etc/init.d/下,这一行代表代表仅在3和5模式下启动该程序,且在 /etc/rc.d/rc3.d/和/etc/rc.d/rc5.d/下的名字为S80liuwenhan。在其他目录下为K70liuwenhan
    • 怎么用chkconfig添加,删除自定义程序,请参考man chkconfig或者info chkconfig
  • 4.启动登录界面,输入用户名和密码登录。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值