说明:本文以 Ubuntu 18.04 为基础进行探讨。

很多普通用户对 Linux 操作系统可能有些陌生,他们平时使用最多的就是购买电脑时已经完成装机的 Windows 或 macOS 操作系统了。对于那些需要用到 Linux 操作系统的开发者来说,他们中的大多数也并不会专门购置一台预装了 Linux 操作系统的个人电脑,通常他们会采用以下两种做法其一来获取一个 Linux 开发环境:

  1. 硬盘安装某个 Linux 发行版,实现 Windows / Linux 或 macOS / Linux 双系统;
  2. 在现有电脑上通过软件安装 Linux 虚拟机。

为了便于下文的叙述,这里附注一张硬盘安装 Linux 的流程图来引入引导管理器(BootLoader)的概念:

有关更多硬盘安装 Linux 操作系统的细节可参考以下链接:

内核引导

说明:本文只讨论从引导阶段开始的 Linux 操作系统层面的相关工作,有关发生在早期的计算机的启动流程可参考阮一峰的网络日志:计算机是如何启动的?

我们可以把上文提到的引导管理器(BootLoader)看作是电脑的系统管理器,它对于安装了多个操作系统的电脑给用户提供了选择启动哪一个操作系统的机会。

这里需要注意是,在以硬盘方式安装多个操作系统时,最后安装的那个系统自带的 BootLoader 会覆盖之前的。又因为 Grub(目前比较主流的是 Grub2) 支持 Windows 系统,而 Windows 的引导加载程序不支持 Linux,所以通常不建议在安装 Linux 之后再来安装 Windows 。

经过 Grub 这一步,计算机的控制权就被转交给了操作系统。当我们通过 Grub 选择了要启动 Linux 操作系统,操作系统首先读取 /boot 目录下的相关文件进行内核引导,当内核启动后,它就开始探测设备并初始化它们。

当内核引导工作完成后,内核就会启动自己的第一个用户空间进程了,它就是 PID 为 1 的 init 进程。这是第一个调用的使用标准 C 库编译的程序。在此之前,还没有执行任何标准的 C 应用程序。这里需要说明的是,虽然 init 进程父进程 ID 是 0 ,但是它并不属于内核进程。

运行级别

init 进程提供了众多的初始化功能,其中一个就是定义了一系列的运行级别,不同的运行级别下应该运行哪些进程都是不一样的。

Linux 的 init 进程总共支持 10 个运行级,但实际定义的运行级只有 7 个。下表显示了这些运行级及其对应的系统状态:

运行级 系统状态
0 系统关闭
1 或 S 单用户模式
2 功能受限的多用户模式
3 完整的多用户模式
4 一般不用,留作用户自己定义
5 多用户模式,运行 X 窗口系统
6 重新启动

一般桌面端的 Linux 发行版默认启动至运行级别 5 ,而服务器版的默认启动至运行级别 3 ,我们可以通过命令 runlevel 查看当前运行级别。

运行相应级别下守护进程

不同的发行版可能有不同的指定默认运行级别以及处理开机自启服务的方式(使用 init 命令可以切换运行级别),目前有三种方式,分别是

  1. sysvinit - 即传统的 init 进程根据 /etc/inittab 配置文件的方式
  2. upstart
  3. systemd

对于这三种方式的细节可以参考:IBM Developer 系列文章:浅析 Linux 初始化 init 系统

用户登录

鉴于不同的运行级别,用户登录进系统的方式也有所不同。总体来说,一共有三种登录方式:

运行窗口系统的图形终端登录

交互式命令行登录

当默认的运行级别不是 5 时,系统将在引导完成和启动脚本正确运行完成后,在文本终端中提示你输入用户名和密码。

如上图所示⤴,这个 tty1 终端就是控制台。此外,Ubuntu 还提供了其他 5 个虚拟终端,我们可以使用快捷键 Alt+F1~F6 在它们之间进行切换。

网络登录

网络登录一般指的是使用 ssh 等的远程登录。

用户登录后

当用户是使用交互式命令行或者网络登录时,控制台选择使用的 shell 称为登录 shell 。

区分是否是登录 shell 有个小技巧:通过 exit 命令可以退出登录 shell 或非登录 shell ,但是 logout 命令只能退出登录 shell 。

Ubuntu 的默认登录 shell 是 bash ,对于登录 shell ,它会依次加载以下文件:

  • /etc/profile
  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile

注意:虽然通过运行窗口系统的图形终端登录后手动打开的终端使用的 shell 也是 bash ,但是它并不是登录 shell 。

参考链接