Linux启动过程详解.doc

上传人:sk****8 文档编号:2329758 上传时间:2019-05-06 格式:DOC 页数:48 大小:242.50KB
下载 相关 举报
Linux启动过程详解.doc_第1页
第1页 / 共48页
Linux启动过程详解.doc_第2页
第2页 / 共48页
Linux启动过程详解.doc_第3页
第3页 / 共48页
Linux启动过程详解.doc_第4页
第4页 / 共48页
Linux启动过程详解.doc_第5页
第5页 / 共48页
点击查看更多>>
资源描述

1、Linux 启动信息解析2目录Linux 启动信息解析 .1目录 .21.项目需求分析 .31.1 项目背景: .31.2 时间: .31.3 项目要求分析: .32Linux 启动过程 .42.1 Linux 下各个目录的作用 .42.2 Linux 启动过程 .42.2.1 Linux 的引导过程 .52.2.2 运行级别(run level) .52.2.3 /etc/rc.d/与/etc/rc.d/init.d 的关系 .53. /init/main.c 中 init()函数 .74. 启动信息 .1031.项目需求分析1.1 项目背景:在学习操作系统中,操作系统的如何启动是一个难点,

2、本文基于 Linux 开源操作系统,分析了从 BIOS 加载 BOOTLOAD,操作系统接管 CPU 后,init()函数所做的事情以及如何初始化系统的各种服务以及 SHELL。1.2 时间:开始时间: 2010-7-25 结束时间: 2010-7-25 1.3 项目要求分析:1) 介绍 Linux 启动所需的目录。2) Linux 启动过程。3) /etc/rc.d/与 /etc/rc.d/init.d 的关系。4) 分析 init/main.c 代码中 init()函数。42Linux 启动过程2.1 Linux 启动所需的目录init.d/ :各种服务器和程序的二进制文件存放目录。rcx

3、.d/: 各个启动级别的执行程序连接目录。里头的东西都是指向 init.d/的一些软连接。还有三个脚本:rc.sysinit, rc, rc.local 。/etc/rc.d/init.d/目录下的脚本就类似与 windows 中的注册表,在系统启动的时候某些指定脚本将被执行。在 Redhat 中, /etc/rc.d/rc.sysinit 主要做在各个运行模式中相同的初始化工作,包括:i. 调入 keymap 以及系统字体ii. 启动 swappingiii. 设置主机名iv. 设置 NIS 域名v. 检查(fsck )并 mount 文件系统vi. 打开 quotavii. 装载声卡模块v

4、iii. 设置系统时钟ix. 等等。2.2 Linux 启动过程redhat 的启动方式和执行次序是:i. 加载内核ii. 执行 init 程序iii. /etc/rc.d/rc.sysinit # 由 init 执行的第一个脚本iv. /etc/rc.d/rc $RUNLEVEL # $RUNLEVEL 为缺省的运行模式v. /etc/rc.d/rc.localvi. /sbin/mingetty # 等待用户登录init 在等待/etc/rc.d/rc 执行完毕之后(因为在 /etc/inittab 中/etc/rc.d/rc 的action 是 wait) ,将在指定的各个虚拟终端上运行

5、 /sbin/mingetty,等待用户的登录。至此,Linux 的启动结束。 52.2.1 Linux 的引导过程系统启动之后,在进入 init.d 之前,我们先来看看系统都做了什么工作.我们从比较高的角度去看开始引导的整个过程,比较清晰明了。系统加电之后,首先进行的硬件自检,然后是 bootloader 对系统的初始化,加载内核。内核被加载到内存中之后,就开始执行了。一旦内核启动运行,对硬件的检测就会决定需要对哪些设备驱动程序进行初始化。从这里开始,内核就能够挂装根文件系统(这个过程类似于 Windows 识别并存取 C 盘的过程) 。内核挂装了根文件系统,并已初始化所有的设备驱动程序和数

6、据结构等之后,就通过启动一个叫 init 的用户级程序,完成引导进程。2.2.2 运行级别(run level)init 进程是系统启动之后的第一个用户进程,所以它的 pid(进程编号)始终为1。init 进程上来首先做的事是去读取/etc/目录下 inittab 文件中 initdefault id 值,这个值称为运行级别(run-level)。它决定了系统启动之后运行于什么级别。运行级别决定了系统启动的绝大部分行为和目的。这个级别从 0 到 6 ,具有不同的功能。不同的运行级定义如下:# 0 - 停机(千万别把 initdefault 设置为 0,否则系统永远无法启动)# 1 - 单用户模

7、式# 2 - 多用户,没有 NFS# 3 - 完全多用户模式(标准的运行级)# 4 系统保留的# 5 - X11 (x window)# 6 - 重新启动 (千万不要把 initdefault 设置为 6,否则将一直在重启)2.2.3 /etc/rc.d/与/etc/rc.d/init.d 的关系写到这里,应该差不多要进入 init.d 了,可是我觉得单写/etc/rc.d/init.d 的话不一定能说得清楚明白,就拿它跟/etc/rc.d 这个它上一级的目录一起来讨论,可能比较合适一些,因为他们之间有着千丝万缕的关系。在这里先解释一下 init.d 里面放的都是什么东西。这个目录存放的是一些

8、脚本,一般是 linux 以 rpm 包安装时设定的一些服务的启动脚本。系统在安装时装了好多 rpm 包,这里面就有很多对应的脚本。执行这些脚本可以用来启动,停止,重启这些服务。前面说到,/etc/rc.d/init.d 这个目录下的脚本就类似与 windows 中的注册表,在系统启动的时候执行。程序运行到这里(init 进程读取了运行级别),相信从命名的角度大家也能猜到该运行/etc/rc.d/init.d 里面的脚本了,不然它为什么也叫6init(.d)呢是吧。没错,是该运行 init.d 里的脚本了,但是并不是直接运行,而是有选择的因为系统并不需要启动所有的服务。那么,系统是如何选择哪些

9、需要启动哪些不要呢?这时刚才说的运行级别就起作用了。在决定了系统启动的 run level 之后, /etc/rc.d/rc 这个脚本先执行。在 RH9 和 FC7 的源码中它都是一上来就 check_runlevel()(虽然实现的代码不一样,也大同小异) ,知道了运行级别之后,对于每一个运行级别,在 rc.d 下都有一个子目录分别是 rc0.d,rc1.d . rc6.d。每个目录下都是到 init.d 目录的一部分脚本一些链接。每个级别要执行哪些服务就在相对应的目录下,比如级别5 要启动的服务就都放在 rc5.d 下,但是放在这个 rc5.d 下的都是一些链接文件,链接到 init.d

10、中相对应的文件,真正运行的是 init.d 里的脚本。到这里,估计大家可能都比较清楚了,我开始也以为是这样的。可是后来我仔细看过和比较这些链接文件和 init.d 里真正被执行的脚本的文件名之后,一直有几个问题没弄明白。借着写这个文章的机会,我做了一些功课,总算是大概解开了那些疑惑。1、这些链接文件前面为什么会带一个 Kxx 或者 Sxx 呢?是这样的,带 K 的表示停止(Kill)一个服务,S 表示开启(Start)的意思,凡是以 Kxx 开头的,都以 stop 为参数来调用;凡是以 Sxx 开头的,都以 start 为参数来调用。调用的顺序按 xx 从小到大来执行。例如,假设缺省的运行模式

11、是3,/etc/rc.d/rc 就会按上述方式调用/etc/rc.d/rc3.d/下的脚本。2、K 和 S 后面带的数字呢?干什么用的这个我开始的时候还以为是排列起来好看或者数数用呢。后来发现不是的。它的作用是用来排序,就是决定这些脚本执行的顺序,数值小的先执行,数值大的后执行。很多时候这些执行顺序是很重要的,比如要启动 Apache 服务,就必须先配置网络接口,不然一个没有 IP 的机子来启动 http 服务那岂不是很搞笑。 。3、无意中我发现同一个服务带 S 的和带 K 的链接到 init.d 之后是同一个脚本。我就纳闷了,为什么会是执行同一个脚本呢?这个时候真是 S 和 K 的妙用了,原

12、来 S 和 K 并不止是用来看起来分的清楚而已。S 给和 K 还分别给 init.d 下面的脚本传递了 start 和 stop 的参数。哦,是这样的( 焕然大悟的样子,呵呵)!这时我才想起来原来曾经无数用过的/etc/rc.d/init.d/network restart 命令。原来传 S 时相当于执行了/etc/rc.d/init.d/xxx start 这条命令,当然 K 就相当于 /etc/rc.d/init.d/xxx stop 了.73. /init/main.c 中 init()函数init()函数的功能可分为 4 个部分:安装根文件系统; 显示系统信息;运行系统初始资源配置文件

13、 rc 中的命令;执行用户登录 shell 程序。代码首先调用系统调用 setup(),用来收集硬盘设备分区表信息并安装根文件系统。在安装根文件系统之前,系统会先判断是否需要先建立虚拟盘若编译内核时设置了虚拟盘的人小,并在前面内核初始化过程中已经开辟了一块内存用作虛拟盘,则内核就会首先尝试把根文件系统加载到内存的虚拟盘区中然后 init()打开一个终端设备 tty0,并复制其文件描述符以产生标准输入stdin、标准输出 stdout 和错误输出 stderr 设备。内核随后利用这些描述符在终端上显示一些系统信息,例如高速缓冲区中缓冲块总数、主内存区空闲内存总字节数等。接着 init()又新建了

14、一个进程(进程 2),并在其中为建立用户交互使用环境而执行一些初始配置操作,即在用户可以使用 shell 命令行环境之前,内核调用/bin/sh 程序运行了配置文件/etc/rc 中设置的命令。 rc 文件的作用与 DOS 系统根目录上的 AUTOEXEC.BAT 文件类似。这段代码首先通过关闭文件描述符 0,并立刻打开文件/etc/rc,从而把标准输入 stdin 定向到/etc/rc 文件上。这样,所有的标准输入数据都将从该文件中读取。然后内核以非交互形式执行/bin/sh,从而实现执行/etc/rc 文件中的命令。当该文件中的命令执行完毕后,/bin/sh 就会立刻退出。因此进程 2 也

15、就随之结束。init()函数的最后一部份用于在新建进程中为用户建立一个新的会话,并运行用户登录 shell 程序/bin.sh在系统执行进程 2 中的程序时,父进程(init 进程)一直等待着它的结束。随着进程 2 的退出,父进程就进入到一个无限循环中。在该循环中,父进程会再次生成一个新进程,然后在该进程中创建一个新的会话。并以登录 shell 方式再次执行程序/bin/sh,以创建用户交互 shell 环境。然后父进程继续等待该于进程。登录 shell 虽然与前而的非交互式 shell 是同一个程序/bin/sh,但是所使用的命令行参数(argv)不同。登录 shell 的第 0 个命令行参

16、数的第 1 个字符一定是一个减号-。这个特定的标志会在/bin/sh 执行时通知它这不是一次普通的运行,而是作为登录 shell 运行/bin/sh 的。从这时开始,用户就可以正常使用 Linux 命令行环境了,而父进程随之又进入等待状态此后若用户在命令行上执行了 exit 或 logout 命令,那么在显示一条当前登录 shell 退出的信息后,系统就会在这个无限循环中再次重复以上创建登录 shell 进程的过程。以下是 init/main.c 中的关于 init()函数的源代码:8void init(void)int pid,i;setup(void *) sprintf(term, “T

17、ERM=con%dx%d“, ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);(void) open(“/dev/tty1“,O_RDWR,0);(void) dup(0);(void) dup(0);execve(“/etc/init“,argv_init,envp_init);execve(“/bin/init“,argv_init,envp_init);execve(“/sbin/init“,argv_init,envp_init);/* if this fails, fall through to original stuff */if (!(pid=fork() close(0);if (open(“/etc/rc“,O_RDONLY,0)_exit(1);execve(“/bin/sh“,argv_rc,envp_rc);_exit(2);if (pid0)while (pid != wait(while (1) if (pid = fork() (reserved)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育教学资料库 > 精品笔记

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。