我刚刚开始学习 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 splash
,ps
这里使用进程的命令行,这将是/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] 及其子进程如何获得括号的!我只是想知道为什么可以显示“对论点的修改”。