PID 1 中的飞溅

PID 1 中的飞溅

我刚刚开始学习 Linux 中的进程。

我遇到了这个名为 ps -ef(它将显示所有正在运行的进程)的命令。

我得到这样的输出

UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root         1     0     1  0    1 Apr17 ?        00:00:18 /sbin/init splash

什么是代表这里?我知道init这是我们启动计算机时运行的第一个进程。但什么是splash?它有什么作用?

另外,谁能告诉我为什么init称为第一个运行的进程,但它是我们启动计算机时首先运行的 BIOS 或 UEFI 程序。那么为什么我们将 init 称为第一个进程,而不是 BIOS 或 UEFI 呢?

答案1

这里的splash代表什么?我知道init是我们启动计算机时运行的第一个进程。但什么是飞溅呢?它有什么作用 ?

首先,您正在运行使用 的 ubuntu systemd,它允许您在启动过程中显示启动屏幕,这就是它具有splash 参数的原因。请参阅飞溅.c源代码。

[编辑] 你的计算机正在运行 systemd,因为,据我所知,systemd 是我所知道的唯一支持启动参数的 init - 可能还有其他参数,但由于它也是 Ubuntu 上的默认设置,我认为这是一个安全的猜测。在 Ubuntu 上,默认情况下,/sbin/init是一个到 的符号链接/usr/lib/systemd/systemd,即加载的内核/sbin/init splashps这里使用进程的命令行,这将是/sbin/init splash,这就是您所看到的。

也有人可以告诉我 init 被称为第一个要运行的进程,但它是我们启动计算机时首先运行的 BIOS 或 UFEI 程序。那么为什么我们将 init 称为第一个进程而不是 BIOS 或 UFEI 呢?

好吧,为了简单起见,BIOS/UEFI 是在启动时加载的程序,它们包含用于进一步启动系统的配置数据。它们最终将找到下一个要启动的程序,例如启动管理器(例如grub),它又将允许您启动内核。我在这里尽量保持简单,但你可以阅读一下。在linux和unix系统上,init是内核生成的第一个程序,因此获得PID 1。

您可以阅读更多内容这里,实际上,那篇文章已经很老了。我并不声称以下内容 100% 准确。

要引导 x86 计算机,您要做的第一件事就是按下电源按钮。您的电源为主板供电,并等待来自 SMPS(开关模式电源)的信号,以提供足够的电力。例如,它会检查您的 PCIe 显卡是否有足够的电量、CPU 和 RAM 是否存在。

英特尔管理引擎(我)/AMD 安全技术从这一点开始,IME 是一个单独的 Intel CPU,带有模糊的 minix 3 操作系统,AMD 等效项使用嵌入在中央 CPU 上的 ARM 内核;关于这两个人,我们知之甚少。

一旦主板收到 SMPS,它就会停止不断重置 CPU,CPU 现在读取 ROM 中的地址,这通常是FFFF:0000h;它包含固件代码的跳转(如快捷方式)。

该固件曾经是一个称为 BIOS 的单片代码块,只能与键盘一起使用。和UEFI,这现在已经成为一个带有迷你文件系统的完整操作系统。今天,跳转点指向一些解压缩 UEFI 的引导代码(可能称为 BIOS)。 UEFI 就像迷你操作系统一样,可能具有鼠标支持、网络启动、SCSI、RAID、磁盘和/或内存检查器以及许多其他功能。

UEFI 加载后,会执行开机自检 (POST),检查所有硬件是否正常。

完整的 POST 检查许多设备,例如 CMOS、视频 ROM、控制器、DMA(允许设备直接访问 RAM)、CPU、内存和其他设备。当您重置 PC 时,即按下重置按钮或执行重新启动命令时,会执行简单的 POST,而不会注意到 CMOS 是否存在问题等问题。 CMOS 是主板上的一个小芯片,包含易失性内存(切断电源,内存就会丢失)和时钟,它由一块小电池供电,包含 UEFI 的所有设置。

UEFI 读取这些设置,对系统进行所需的任何更改,然后继续进一步引导系统。 UEFI 可以通过在驱动器上查找引导记录来执行传统引导,也可以使用更现代的 UEFI 引导方法。这需要一个 FAT32 格式的分区,其中包含可以加载的 UEFI 引导代码Linux内核,启动管理器(Windows) 或引导加载程序,例如grub.

UNIX 系统上的内核加载所有需要的设备驱动程序,然后加载 init 进程。 Init 可以是systemd或任何其他程序,例如bash;您可以在内核参数中配置它。请注意,如果选择直接使用 UEFI 加载内核,则设置内核参数会困难得多。一旦加载,init 就会获取 PID 1,然后加载用户空间(系统 shell 和可选的图形用户界面)。

答案2

这里的splash代表什么?

它是启动的内核映像/文件的名称。或者只是内核命令行的第一个参数,正如您所得到的

cat /proc/cmdline

这通常给我三个论据:

[内核名称] [initrd=...] [root=...]

内核的默认名称是 vmlinuz。我猜splash一定是ubuntu内核的名字,它内置了一个启动屏幕。

这(显示“splash”)是一个 systemd 功能,对于 sysvinit,它只是“/sbin/init”。这很好,但有点作弊,因为 init 不是通过内核映像调用的,而是通过内核和剩余的引导参数调用的。

/sbin/init 是(在 systemd 下为 pid#1)到 systemd 二进制文件 /lib/systemd/systemd 的链接。

那么为什么我们将 init 称为第一个进程而不是 BIOS 或UFEI

[UEFI! UE-固件-接口]

“Init”只是第一个Linux进程。启动 /sbin/init 是内核所做的最后一件事。

请记住,Linux 最初的想法是利用 386-CPU 的保护模式。如果没有这种模式,就没有真正的流程。

在某种程度上,Linux内核本身只是建立了一个高效的进程生成系统。您如何使用它取决于您:您可以使用 init=/bin/bash 启动到只有一两个 MB 的系统。然后,您仍然可以在后台启动 bash 作业,或者启动一个按需要分叉的二进制文件。或者在第一个 bash 的“顶部”启动另一个 bash。但是在 shell 中“退出”太多,您会回到内核,内核会立即出现恐慌。

...或者您可以使用 sysvinit 作为第一个进程。这个经典的 init 为您定义的每个 tty 启动一个登录过程。在这里您可以使用 Alt 键从一个进程切换到另一个进程。然后,您可以从 tty 启动其他进程,并且可以将 /etc/inittab 配置为直接启动图形“shell”。

...或者您可以使用(自 2012 年起)systemd 作为“init”,并具有附加功能。大部分是由其他 systemd 二进制文件完成的。

因此,根据定义,init 是内核执行的第一个二进制文件:内核启动一个 init,然后该 init 启动一个或多个进程(登录、守护进程)。

早期的 CPU 活动,甚至导致 Visual UEFI-BIOS 和 UEFI-Shell(当然不是同时),不被称为进程,即使处理器正在处理代码:-)

@斯蒂芬:

有 initrd=、rdinit= 和 init= 启动参数。 initrd= 命名 ramdisk 的文件/映像,使用 rdinit= 您可以更改 /init(ramdisk 应首先执行的文件),使用 init= 您可以更改 /sbin/init。

我认为你在链接中混淆了这一点。可能是因为 initrd-fs 中的 /init 由 rdinit= 控制,而 sbin 中的 init 由 init= 控制

我最近经常使用这些选项 - 独立于任何发行版甚至引导加载程序。我从 UEFI-Shell 开始,它的作用就像引导加载程序,只不过您可以动态选择任何内核和 initrd - 只要它们位于 EFI 系统分区内。

所以:

fedora\vmlinuz root=/dev/sda2

我可以成功启动 fedora 29 的内核 - 无需 initrd。

我尝试过的所有其他内核都需要 initrd,因为它们缺少 sata/scsi 模块。

arch5\vmlinuz-linux initrd=arch5\initramfs-linux.img root=/dev/sda3 init=/usr/bin/sysvinit

这就是我启动现在所在系统的方式,但使用旧的 sysvinit 而不是 /sbin/init (这是 /lib/systemd/systemd 的链接)。这里是 archlinux 的 /init 使用 root= 将 root= switch_root 到 /dev/sda3 并使用 init= 启动除 /sbin/init 之外的其他东西。

我还通过操作 /init 来启动,重新归档它并进入。

arch\vmlinuz.4.20.6 initrd=arch\archsam.cpio

这里没有root=,因为我将根分区硬编码在/init中。

附:

[    0.000000] Linux version 5.1.12-arch1-1-ARCH (builduser@heftig-24809) (gcc version 9.1.0 (GCC)) #1 SMP PREEMPT Wed Jun 19 09:16:00 UTC 2019
[    0.000000] Command line: arch5\vmlinuz-linux initrd=arch5\initramfs-linux.img root=/dev/sda3

这是我的前两个内核消息行。再次注意 arch5\vmlinuz-linux 中的反斜杠!

ps axf 给了我这个(没有内核线程 2 到大约 200):

    1 ?        Ss     0:01 /sbin/init arch5\vmlinuz-linux
  291 ?        Ss     0:00 /usr/lib/systemd/systemd-journald
  304 ?        Ss     0:00 /usr/bin/lvmetad -f
  315 ?        Ss     0:00 /usr/lib/systemd/systemd-udevd
  321 ?        Ss     0:00 /usr/lib/systemd/systemd-networkd
  453 ?        Ssl    0:00 /usr/lib/systemd/systemd-timesyncd
  456 ?        Ss     0:05 /usr/lib/systemd/systemd-resolved
  466 ?        Ss     0:02 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
  467 ?        Ss     0:00 /usr/lib/systemd/systemd-logind
  469 ?        Ss     0:00 login -- root
  484 tty1     Ss     0:00  \_ -bash
  922 tty1     S+     0:00      \_ xinit fvwm
  923 tty2     S<sl+   8:08          \_ /usr/lib/Xorg :0
  930 tty1     S      0:00          \_ xterm -geometry +1+1 -n login fvwm
  932 pts/0    Ss+    0:08              \_ fvwm
  937 pts/0    S+     0:00                  \_ /usr/lib/fvwm/2.6.8/FvwmButtons 9 4 none 0 8 RightPanel
  938 pts/0    S+     0:00                  \_ /usr/lib/fvwm/2.6.8/FvwmEvent 11 4 none 0 8 EventNewDesk
  939 pts/0    S+     0:00                  \_ /usr/lib/fvwm/2.6.8/FvwmPager 13 4 none 0 8 *
  940 pts/0    S+     0:01                  \_ /usr/lib/fvwm/2.6.8/FvwmIconMan 15 4 none 0 8
  941 pts/0    S+     0:04                  \_ /usr/lib/fvwm/2.6.8/FvwmScript 17 4 none 0 8 FvwmScript-DateTime
  955 pts/0    Sl    22:28                  \_ /usr/lib/firefox/firefox
 1049 pts/0    Sl    18:08                  |   \_ /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 179366 -parentBuildID 20190620195126 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 955 true tab
 1129 pts/0    Sl     0:46                  |   \_ /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 5850 -prefMapSize 179366 -parentBuildID 20190620195126 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 955 true tab
 8411 pts/0    Sl     0:24                  |   \_ /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 7065 -prefMapSize 179366 -parentBuildID 20190620195126 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 955 true tab
31147 pts/0    Sl     0:00                  |   \_ /usr/lib/firefox/firefox -contentproc -childID 10 -isForBrowser -prefsLen 9059 -prefMapSize 179366 -parentBuildID 20190620195126 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 955 true tab
32497 pts/0    Sl     0:04                  |   \_ /usr/lib/firefox/firefox -contentproc -childID 11 -isForBrowser -prefsLen 9059 -prefMapSize 179366 -parentBuildID 20190620195126 -greomni /usr/lib/firefox/omni.ja -appomni /usr/lib/firefox/browser/omni.ja -appdir /usr/lib/firefox/browser 955 true tab
11810 pts/0    S      0:00                  \_ xterm
11812 pts/1    Ss     0:00                      \_ bash
  406 pts/1    R+     0:00                          \_ ps axf

我检查了ubuntu和splash...splash是一个grub参数,给它们带来了一些问题。大部头书

/sbin/init 启动选项

没有意义,但是

/sbin/init cmd 行的第一部分

确实有道理。

顺便说一句,你知道 init/main.c 中关于 LILO 以某种方式将“auto”传递到命令行的注释吗?通过 bootloader、kernel、initrd/init 和 /sbin/init(对于运行级别或 systemd-target)进行的命令行解析并不那么简单。

添加:

“男人 ps” 说:

   args        COMMAND   command with all its arguments as a string.
                         Modifications to the arguments may be shown.
                         The output in this column may contain spaces.
                         A process marked <defunct> is partly dead,
                         waiting to be fully destroyed by its parent.
                         Sometimes the process args will be unavailable;
                         when this happens, ps will instead print the
                         executable name in brackets.

这就是 pid 2 的 [kthreadd] 及其子进程如何获得括号的!我只是想知道为什么可以显示“对论点的修改”。

相关内容