linux 用户空间的启动

本文介绍了Linux用户空间的启动过程,包括init的不同实现(SystemVinit、systemd和Upstart),以及它们在启动时的职责和依赖关系。重点讲解了systemd的特性,如单元和单元类型,以及依赖关系管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux 用户空间的启动


内核启动第一个用户空间进程是由init开始的。这个点 很关键,不仅仅因为此时内存和CPU已经准备就绪,而且你 还能看到系统的其余部分是怎样启动运行的。在此之前,内 核执行的是受到严格控制的程序序列,由一小撮程序员开发 和定义。而用户空间更加模块化,我们容易观察到其中进程的启动和运行过程。对于好奇心强的用户来说,用户空间的启动也更容易修改,
不需要底层编程知识即可做到。

init介绍

init是Linux上的一个用户空间程序。和其他系统程序一样,你可以在/sbin目录下找到它。它 主要负责启动和终止系统中的基础服务进程,但其较新的版本功能更多一些。

Linux系统中,init有以下三种主要的实现版本。

  • System V init:传统的顺序init(Sys V,读作“sys-five”),为Red Hat Enterprise Linux和其他的Linux发行版使用。
  • systemd:新出现的init。很多Linux发行版已经或者正在计划转向systemd。
  • Upstart:Ubuntu上的init。不过在本书编写时,Ubuntu也已经计划转向systemd。

System-V运行级别

在Linux系统中,有一组进程自始至终都在运行(如crond和udevd)。System V init中把这个状 态叫作系统的运行级别,使用数字0~6来表示。系统几乎全程运行在单个运行级别中,但是当你 关闭系统的时候,init就会切换到另一个运行级别,有序地终止系统服务,并且通知内核停止。

你可以使用who -r命令来查看系统的运行级别。运行Upstart的系统会返回下面的结果

$ who -r
run-level 2 2015-09-06 08:37

识别你的init

在我们继续之前,你需要确定你系统中的init版本。如果你不确定,可以使用下面的方法查看。

  • 如果系统中有目录/usr/lib/systemd和/etc/systemd,说明你有systemd
  • 如果系统中有目录/etc/init,其中包含.conf文件,说明你的系统很可能是Upstart(除非你的系统是Debian 7,那说明你使用的是System V init)
  • 如果以上都不是,且你的系统有/etc/inittab文件,说明你可能使用的是System V init

systemd

systemd init是Linux上新出现的init实现之一。除了负责常规的启动过程,systemd还包含了一 系列的Unix标准服务,如cron和inetd。它借鉴了Apple公司的启动程序。这个init的一个重要特性 是:它可以延迟一些服务和操作系统功能的开启,直到需要它们时再开启。

systemd的特性很多,学习起来可能会没有头绪。下面我们列出systemd启动时的运行步骤:

  1. systemd加载配置信息;
  2. systemd判定启动目标,通常是default.target;
  3. systemd判定启动目标的所有依赖关系;
  4. systemd激活依赖的组件并启动目标;
  5. 启动之后,systemd开始响应系统消息(诸如uevent),并且激活其他组件。

systemd并没有一个严格的顺序来启动服务。和现在很多的init系统一样,systemd启动的顺序很灵活,大部分的systemd配置尽量避免需要严格按顺序启动,而是使用其他方法来解决强依赖性问题。

单元和单元类型

systemd最有特色的地方是它不仅仅负责处理进程和服务,还可以挂载文件系统、监控网络套接字和运行时系统等。这些功能我们称之为单元,它们的类别称为单元类型,开启一个单元称为激活。

Unix系统启动时需要使用到的单元类型。

  • 服务单元:控制Unix上的传统服务守护进程。
  • 挂载单元:控制文件系统的挂载。
  • 目标单元:控制其余的单元,通常是通过将它们分组的方式。

默认的启动目标通常是一个目标单元,它依赖并组织了一系列的服务和挂载单元。这样你能 够很清楚地了解启动过程的情况,还可以使用systemctl dot命令来创建一个依赖关系树形图。 你会发现这个树状图会很大,因为很多单元默认情况下并不会启动。

systemd中的依赖关系

systemd提供了大量的依赖类型和形式。我们在此按照关键字 列出这些类型,但是会在6.4.3节中再详细介绍。基本类型有以下几个。

  • Requires:表示不可缺少的依赖关系。如果一个单元有此类型的依赖关系,systemd会尝试 激活被依赖的单元,如果失败,systemd会关闭被依赖的单元。
  • Wants:表示只用于激活的依赖关系。单元被激活时,它的Wants类型的依赖关系也会被 systemd激活,但是systemd不关心激活成功与否。
  • Requisite:表示必须在激活单元前激活依赖关系。systemd会在激活单元前检查其Requisite 类型依赖关系的状态。如果依赖关系还没有被激活,单元的启动也会失败。
  • Conflicts:反向依赖关系。如果一个单元有Conflict类型的依赖关系,且它们已经被激活, systemd会自动关闭它们。同时启动两个有反向依赖关系的单元会导致失败。

Wants是一种很重要的依赖关系,它不会将启动错误扩散给其他单元。systemd文档鼓 励我们尽可能使用这种依赖关系。原因显而易见:它让系统容错性更强,有点像传统 的init。

只要你指定一个依赖关系的类型,如Wants或Requires,就可以使用systemctl命令来查看单 元的依赖关系:

$ systemctl show -p type unit
你可以使用下面的依赖关键字来设定顺序。
  • Before:当前单元会在Before中列出的单元之前启动。例如,如果Before=bar.target出现在foo.target中,systemd会先启动foo.target,然后是bar.target。
  • After:当前单元在After中列出的单元之后启动。

下面我们列出一些systemd中没有使用,但是其他系统使用的依赖条件关键字。

  • ConditionPathExists=p: 如果文件路径p存在,则返回true。
  • ConditionPathIsDirectory=p: 如果p是一个目录,则返回true。
  • ConditionFileNotEmpty=p: 如果p是一个非空的文件,则返回true。

详细信息参考精通linux(第二版)

Upstart

init的Upstart版本主要涉及任务和事件。任务是启动和运行时Upstart执行的操作(如系统服 务和配置),事件是Upstart从自身或者其他进程(如udevd)接收到的消息。Upstart通过启动任务 的方式来响应消息。

为了理解它的工作原理,我们来看看启动udevd守护进程的udev任务。它的配置文件通常是 /etc/init/udev.conf,其中包含下面的内容:

start on virtual-filesystems 
stop on runlevel [06]

System-V-init

Linux上的System V init实现要追溯到Linux的早期版本,它根本目的是为了为系统提供合理 的启动顺序,支持不同的运行级别。虽然现在System V已经不太常见,不过在Red Hat Enterprise Linux和一些路由器和电话的Linux嵌入系统中还是能够看到System V init。

关闭系统

init控制系统的启动和关闭。关闭系统的命令在所有init版本中都是一样的。关闭Linux系统最 好的方式是使用shutdown命令。

shutdown命令有两种使用方法,一是使用-h可选项关闭系统,并且使其一直保持关闭状态。 下面的命令能够立即关闭系统:

shutdown -h now

在大部分系统中,-h代表切断机器电源。另外还可以使用-r来重启系统。 系统的关闭过程会持续几秒钟,在此过程中请不要重置或切断电源。 上例中的now是时间,是一个必须的参数。设置时间的方法有很多种。例如,如果你想让系统在将来某一时间关闭,可以使用+n。n以分钟为单位,系统会在n分钟后执行关闭命令。(可以 在shutdown(8)帮助手册中查看更多相关选项。)

下面的命令在10分钟后重启系统:

shutdown -r +10

initramfs

Linux启动过程很简单。但是其中的一个组件总是让人一头雾水,那就是initramfs,或称为初 始RAM文件系统。可以把它看作是一个用户空间的楔子,在用户空间启动前出现。

参考

[精通linux(第二版)](

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值