1. 内核启动问题
2. 解决方案
2.1 ramdisk(比如initrd)
2.2 tmpfs(比如initramfs)
2.3 ramdisk vs ramfs
2.4 临时文件系统
2.4.1 观察tmpfs
2.4.2 Initramfs
2.4.3 查看initramfs
2.4.4 创建initramfs
2.5 Linux系统中的initramfs
2.6 cpio归档文件
3. 高级用户
3.1 制作自己的initramfs
3.2 Initramfs编程
3.3 使用更新的工具
用户程序存在于文件系统中,因此Linux内核必须找到并挂载第一个(或“根”)文件系统才能成功启动。
通常,可用的文件系统列在文件 /etc/fstab 中,通过 mount 程序可以找到它们。但是 /etc/fstab 本身就是一个存储在文件系统中的文件。
找到第一个文件系统是鸡和蛋的问题,为了解决这个问题,内核开发人员创建了内核命令行选项“root =”,以指定根文件系统所在的设备。
二十年前,“root =”很容易解释。它可能是软盘驱动器,也可能是硬盘驱动器上的分区。(可用硬件设备及文件系统非常少,很容易指定)
现在,根文件系统可以在几十种不同类型的硬件上,文件系统也有几十种,甚至可以在RAID中分布在其中的几种硬件上。压缩,加密,环回挂载,存在与网络上等等情况。
新的硬件,新的文件系统,新的压缩,加密方法还会越来越多。
到2.6版本时期,Linus在缓存周围写了一个名为“ramfs”的小包装器,Ramfs是一个非常简单的文件系统,它将Linux的磁盘缓存机制(页面缓存和dentry缓存)导出为可动态调整大小的基于RAM的文件系统。
ramfs的一个缺点是你可以继续写入数据直到你填满所有内存,而VM无法释放它,因为VM认为文件应该写入后备存储(而不是交换空间),但是ramfs没有任何后备存储。
因此,只允许root(或可信用户)对ramfs mount进行写访问。
其他内核开发人员创建了一个名为“tmpfs”的改进版本.tmpfs(以前称为shmfs)基于启动时使用的ramfs代码,,但与ramfs不同,它支持交换较少使用的页面以交换空间以及文件系统大小和inode限制以防止内存不足的情况(默认为物理RAM的一半和RAM页面的一半)。
(它可以将数据写入交换空间,并限制给定挂载点的大小,避免填满所有可用的内存)。Initramfs是tmpfs的一个实例。
可以允许普通用户对tmpfs挂载进行写访问。这些基于ram的文件系统会自动增长或缩小以适应它们包含的数据大小。物尽其用,不会浪费额外的空间,不需要模拟块设备操作的额外开销。
小结
ramdisk,模拟块设备,实例是initrd,前文描述的弊端,已很少使用。
tmpfs,临时文件系统,是ramfs的改进版本,实例是目前主流的initramfs,初始ram文件系统。
在某些Linux发行版(例如Debian,Ubuntu)上,/tmp是普通目录,但/dev/shm使用tmpfs。
以下是arch linux环境
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
dev 4072256 0 4072256 0% /dev
run 4079692 864 4078828 1% /run
/dev/sdb6 31364968 14256088 15492548 48% /
/dev/sdb7 34422400 7942172 24708608 25% /home
tmpfs 4079692 416068 3663624 11% /dev/shm
tmpfs 4079692 0 4079692 0% /sys/fs/cgroup
tmpfs 4079692 32 4079660 1% /tmp
tmpfs 815936 24 815912 1% /run/user/1001
initramfs只需要包含访问根文件系统所需的模块; 它不需要包含一个人们想要使用的每个模块。在init过程中,udev将在稍后加载大多数模块。
Arch Linux使用内置initramfs的空存档(这是构建Linux时的默认存档)。
第一个提取的initramfs是在内核构建期间嵌入在内核二进制文件中的initramfs,然后提取可能的外部initramfs文件。
因此,外部initramfs中的文件会覆盖嵌入式initramfs中具有相同名称的文件。然后内核执行/init(在rootfs中)作为第一个进程。
initramfs映像是一个SVR4 CPIO归档文件,通过find和bsdcpio命令生成,可选择使用内核理解的压缩方案进行压缩。
mkinitcpio包含一个名为的实用程序lsinitcpio,它将列出和/或提取initramfs图像的内容。
列出镜像中的文件:
$ lsinitcpio /boot/initramfs-linux.img
当前目录中提取:
$ lsinitcpio -x /boot/initramfs-linux.img
更加人性化的重要部分列表:
$ lsinitcpio -a /boot/initramfs-linux.img
mkinitcpio是一个用于创建初始ramdisk环境的Bash脚本。
默认情况下,mkinitcpio脚本在内核安装或升级后生成两个镜像:默认镜像和跳过自动检测挂钩的回退镜像,因此包含了大量不需要的模块。
这是通过大多数内核包安装的.preset文件的PRESETS指令来完成的(例如,对于linux包含)。
预设是如何创建initramfs镜像的预定义定义,而不是每次都指定配置文件和输出文件。
例如,以下将(重新)生成由...提供的预设/etc/mkinitcpio.d//etc/mkinitcpio.d/linux.presetPRESETS=('default' 'fallback')-p--presetlinux包:
# mkinitcpio -p linux
附加配置文件位于/etc/mkinitcpio.conf并用于指定所有预设的全局选项。
的-P/ --allpresets开关指定的所有预置应在后再生的initramfs时被利用mkinitcpio.conf的变化。
用户可以使用各种不同的配置创建任意数量的initramfs镜像。必须在相应的引导加载程序配置文件中指定所需的镜像。
警告: .preset文件用于在内核更新后自动重新生成initramfs; 编辑时要小心。
mkinitcpio的主要配置文件是/etc/mkinitcpio.conf。
另外,预设定义由/etc/mkinitcpio.d目录中的内核包提供(例如/etc/mkinitcpio.d/linux.preset)。
生成自定义手动initcpio
用户可以使用备用配置文件生成镜像。例如,以下内容将根据指示生成initramfs图像/etc/mkinitcpio-custom.conf并将其保存/boot/linux-custom.img。
# mkinitcpio -c /etc/mkinitcpio-custom.conf -g /boot/linux-custom.img
如果为当前正在运行的内核生成镜像,请将内核版本添加到命令行。您可以在中查看可用的内核版本/usr/lib/modules/。
# mkinitcpio -g /boot/linux-custom2.img -k 3.3.0-ARCH
用户可以修改配置文件中的六个变量:
MODULES 在运行任何引导挂钩之前加载的内核模块。
BINARIES 要包含在initramfs映像中的其他二进制文件。
FILES 要包含在initramfs映像中的其他文件。
HOOKS 挂钩是在初始ramdisk中执行的脚本。
COMPRESSION 用于压缩initramfs映像。
COMPRESSION_OPTIONS 传递给COMPRESSION程序的额外参数。强烈建议不要使用此设置。mkinitcpio将处理压缩机的特殊要求(例如传递--check=crc32给xz),并且误用很容易导致系统无法启动。
一些Linux的Live CD光盘文件里
cpio最初设计用于以连续,连续的方式在磁带设备上存储备份文件存档。它不压缩任何内容,但是通常使用gzip或其他外部压缩器压缩生成的归档。
档案创建
在使用-o命令行标志启动的复制操作期间创建存档时,cpio从其标准输入通道读取文件和目录路径名,并将生成的存档字节流写入其标准输出。
因此,Cpio通常与生成要归档的文件列表的其他实用程序一起使用,例如查找程序。
生成的cpio存档是一系列文件和目录,它们连接成一个存档,由带有文件元信息的标题部分分隔,例如文件名,inode编号,所有权,权限和时间戳。按照惯例,归档的文件名通常被赋予文件扩展名cpio。
此示例使用find实用程序生成从当前目录开始的路径名列表,以创建目录树的存档:
$ find . -depth -print | cpio -o > /path/archive.cpio
提取
在由命令行标志i启动的拷入操作期间,cpio从其标准输入读取存档,并在操作系统的文件系统中重新创建存档文件。
命令行标志d告诉cpio根据需要构造目录。标志v(详细)列出提取时的文件名。
$ cpio -i -vd < archive.cpio
$ cpio -i -d /etc/fstab < archive.cpio
清单
列出cpio存档中包含的文件:
$ cpio -t < archive.cpio
复制
此示例将从当前目录开始的目录树复制到文件系统中的另一个路径new-path,
保留文件修改时间(标志m),
根据需要创建目录(d),
无条件地替换任何现有文件(u),
同时生成标准输出的进度清单(v):
$ find . -depth -print | cpio -p -dumv new-path
使用mkinitcpio优化启动
在最简单的情况下,挂载根分区需要以下驱动程序:
存储总线(PATA,SATA,SCSI等)
块设备
文件系统
lsinitcpio很高兴地向你展示了图像上的确切内容。
'mkinitcpio -M'将扫描您的PCI总线并探测您的根文件系统,返回一个整洁的模块列表,没有依赖项。
https://wiki.archlinux.org/index.php/Minimal_initramfs
最小的initramfs
将一些可执行文件放入新的根文件系统。
使用mdev填充/dev
从rootfs切换到另一个根文件系统
dracut创建内核使用的初始映像,用于预加载访问根文件系统所需的块设备模块(例如IDE,SCSI或RAID)。这可能会在不久的将来取代Arch Linux中的mkinitcpio。
https://dracut.wiki.kernel.org/index.php/Main_Page
注意:阅读邮件列表公告,了解可能使用Dracut替换Mkinitcpio。
https://lists.archlinux.org/pipermail/arch-dev-public/2019-May/029570.html
[arch-dev-public] Mkinitcpio replacement with Dracut
Giancarlo Razzolini grazzolini at archlinux.org
Tue May 21 02:41:40 UTC 2019
Mkinitcpio替换为Dracut的信息。有兴趣有能力的人可以多加关注,参与其中。
更多相关信息
https://landley.net/writing/rootfs-intro.html
https://wiki.debian.org/InitrdReplacementOptions
https://en.wikipedia.org/wiki/Initial_ramdisk
https://en.wikipedia.org/wiki/Tmpfs
https://en.wikipedia.org/wiki/Linux_startup_process
https://en.wikipedia.org/wiki/Initial_ramdisk
https://www.kernel.org/doc/Documentation/early-userspace/README 最后更新:2004-12-20
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt 2005年10月17日
https://wiki.archlinux.org/index.php/Arch_boot_process#initramfs
https://wiki.archlinux.org/index.php/Mkinitcpio
2. 解决方案
2.1 ramdisk(比如initrd)
2.2 tmpfs(比如initramfs)
2.3 ramdisk vs ramfs
2.4 临时文件系统
2.4.1 观察tmpfs
2.4.2 Initramfs
2.4.3 查看initramfs
2.4.4 创建initramfs
2.5 Linux系统中的initramfs
2.6 cpio归档文件
3. 高级用户
3.1 制作自己的initramfs
3.2 Initramfs编程
3.3 使用更新的工具
1. 内核启动问题
当Linux内核引导系统时,它必须找到并运行第一个用户程序,通常称为“init”。(大多数较新的版本使用systemd作为默认init)用户程序存在于文件系统中,因此Linux内核必须找到并挂载第一个(或“根”)文件系统才能成功启动。
通常,可用的文件系统列在文件 /etc/fstab 中,通过 mount 程序可以找到它们。但是 /etc/fstab 本身就是一个存储在文件系统中的文件。
找到第一个文件系统是鸡和蛋的问题,为了解决这个问题,内核开发人员创建了内核命令行选项“root =”,以指定根文件系统所在的设备。
二十年前,“root =”很容易解释。它可能是软盘驱动器,也可能是硬盘驱动器上的分区。(可用硬件设备及文件系统非常少,很容易指定)
现在,根文件系统可以在几十种不同类型的硬件上,文件系统也有几十种,甚至可以在RAID中分布在其中的几种硬件上。压缩,加密,环回挂载,存在与网络上等等情况。
新的硬件,新的文件系统,新的压缩,加密方法还会越来越多。
2. 解决方案
为了避免将如此多的特殊情况硬编码到内核中,使用了具有临时根文件系统的初始启动阶段 - 现在称为早期用户空间。此根文件系统可以包含用户空间帮助程序,它们执行硬件检测,模块加载和设备发现,以便安装真正的根文件系统。2.1 ramdisk(比如initrd)
在2.4及更早版本上,主要使用ramdisk(比如initrd), 基于ram的块设备, 但由于模仿块设备,导致它是固定大小的内存块,需要像磁盘一样进行格式化和安装,(操作工具mke2fs,losetup)。需要文件系统驱动。这造成额外的开销,资源的浪费。固定的大小还不能扩展。2.2 tmpfs(比如initramfs)
Rootfs是ramfs(或tmpfs,如果已启用)的特殊实例,具体表现比如Initramfs文件。到2.6版本时期,Linus在缓存周围写了一个名为“ramfs”的小包装器,Ramfs是一个非常简单的文件系统,它将Linux的磁盘缓存机制(页面缓存和dentry缓存)导出为可动态调整大小的基于RAM的文件系统。
ramfs的一个缺点是你可以继续写入数据直到你填满所有内存,而VM无法释放它,因为VM认为文件应该写入后备存储(而不是交换空间),但是ramfs没有任何后备存储。
因此,只允许root(或可信用户)对ramfs mount进行写访问。
其他内核开发人员创建了一个名为“tmpfs”的改进版本.tmpfs(以前称为shmfs)基于启动时使用的ramfs代码,,但与ramfs不同,它支持交换较少使用的页面以交换空间以及文件系统大小和inode限制以防止内存不足的情况(默认为物理RAM的一半和RAM页面的一半)。
(它可以将数据写入交换空间,并限制给定挂载点的大小,避免填满所有可用的内存)。Initramfs是tmpfs的一个实例。
可以允许普通用户对tmpfs挂载进行写访问。这些基于ram的文件系统会自动增长或缩小以适应它们包含的数据大小。物尽其用,不会浪费额外的空间,不需要模拟块设备操作的额外开销。
2.3 ramdisk vs ramfs
2.4及更早版本使用 | 2.6以上版本 |
ramdisk | ramfs > tmpfs |
initrd | initramfs |
基于ram的块设备 | 基于ram的文件系统 |
固定大小的内存块 | 会自动增长或缩小以适应包含的数据大小 |
资源浪费,模拟块设备,额外的开销 | 物尽其用 |
旧的initrd始终是一个单独的文件 | 而initramfs存档链接到linux内核映像 |
initrd文件是一个gzip压缩的文件系统映像(在例如ext2,需要内置的驱动程序) | initramfs存档是一个gzip压缩的cpio存档(比如tar更简单) 内核的cpio提取代码非常小,而且还可以在启动过程中丢弃__init文本和数据。 |
旧的initrd(称为/initrd,而不是/init) 运行程序进行一些设置,然后返回到内核 |
而initramfs的init程序不会返回内核. 如果/init需要切换控制,它可以使用新的根设备进行超载/执行另一个init程序。 |
当切换另一个根设备时,initrd将pivot_root,然后卸载ramdisk。 | initramfs是rootfs,既不能使用pivot_root rootfs,也无法卸载。 而是删除rootfs中的所有内容以释放空间 (find -xdev / -exec rm '{}' ';'), 使用新根 (cd /newmount; mount --move . /; chroot .), 覆盖rootfs。 将 stdin/stdout/stderr 附加到新的 /dev/console, 并执行新的init。 |
ramdisk,模拟块设备,实例是initrd,前文描述的弊端,已很少使用。
tmpfs,临时文件系统,是ramfs的改进版本,实例是目前主流的initramfs,初始ram文件系统。
2.4 临时文件系统
2.4.1 观察tmpfs
tmpfs是许多类Unix操作系统上临时文件存储设施的通用名称。可以通过df观察到在某些Linux发行版(例如Debian,Ubuntu)上,/tmp是普通目录,但/dev/shm使用tmpfs。
以下是arch linux环境
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
dev 4072256 0 4072256 0% /dev
run 4079692 864 4078828 1% /run
/dev/sdb6 31364968 14256088 15492548 48% /
/dev/sdb7 34422400 7942172 24708608 25% /home
tmpfs 4079692 416068 3663624 11% /dev/shm
tmpfs 4079692 0 4079692 0% /sys/fs/cgroup
tmpfs 4079692 32 4079660 1% /tmp
tmpfs 815936 24 815912 1% /run/user/1001
2.4.2 Initramfs
初始ram文件系统,也称早期用户空间,典型用途是检测加载主用户空间文件系统所需的设备驱动程序,并从临时文件系统加载它们。initramfs只需要包含访问根文件系统所需的模块; 它不需要包含一个人们想要使用的每个模块。在init过程中,udev将在稍后加载大多数模块。
Arch Linux使用内置initramfs的空存档(这是构建Linux时的默认存档)。
第一个提取的initramfs是在内核构建期间嵌入在内核二进制文件中的initramfs,然后提取可能的外部initramfs文件。
因此,外部initramfs中的文件会覆盖嵌入式initramfs中具有相同名称的文件。然后内核执行/init(在rootfs中)作为第一个进程。
2.4.3 查看initramfs
如果您对initramfs映像中的内容感到好奇,可以将其解压缩并查看其中的文件。initramfs映像是一个SVR4 CPIO归档文件,通过find和bsdcpio命令生成,可选择使用内核理解的压缩方案进行压缩。
mkinitcpio包含一个名为的实用程序lsinitcpio,它将列出和/或提取initramfs图像的内容。
列出镜像中的文件:
$ lsinitcpio /boot/initramfs-linux.img
当前目录中提取:
$ lsinitcpio -x /boot/initramfs-linux.img
更加人性化的重要部分列表:
$ lsinitcpio -a /boot/initramfs-linux.img
2.4.4 创建initramfs
https://wiki.archlinux.org/index.php/Mkinitcpiomkinitcpio是一个用于创建初始ramdisk环境的Bash脚本。
默认情况下,mkinitcpio脚本在内核安装或升级后生成两个镜像:默认镜像和跳过自动检测挂钩的回退镜像,因此包含了大量不需要的模块。
这是通过大多数内核包安装的.preset文件的PRESETS指令来完成的(例如,对于linux包含)。
预设是如何创建initramfs镜像的预定义定义,而不是每次都指定配置文件和输出文件。
例如,以下将(重新)生成由...提供的预设/etc/mkinitcpio.d//etc/mkinitcpio.d/linux.presetPRESETS=('default' 'fallback')-p--presetlinux包:
# mkinitcpio -p linux
附加配置文件位于/etc/mkinitcpio.conf并用于指定所有预设的全局选项。
的-P/ --allpresets开关指定的所有预置应在后再生的initramfs时被利用mkinitcpio.conf的变化。
用户可以使用各种不同的配置创建任意数量的initramfs镜像。必须在相应的引导加载程序配置文件中指定所需的镜像。
警告: .preset文件用于在内核更新后自动重新生成initramfs; 编辑时要小心。
mkinitcpio的主要配置文件是/etc/mkinitcpio.conf。
另外,预设定义由/etc/mkinitcpio.d目录中的内核包提供(例如/etc/mkinitcpio.d/linux.preset)。
生成自定义手动initcpio
用户可以使用备用配置文件生成镜像。例如,以下内容将根据指示生成initramfs图像/etc/mkinitcpio-custom.conf并将其保存/boot/linux-custom.img。
# mkinitcpio -c /etc/mkinitcpio-custom.conf -g /boot/linux-custom.img
如果为当前正在运行的内核生成镜像,请将内核版本添加到命令行。您可以在中查看可用的内核版本/usr/lib/modules/。
# mkinitcpio -g /boot/linux-custom2.img -k 3.3.0-ARCH
用户可以修改配置文件中的六个变量:
MODULES 在运行任何引导挂钩之前加载的内核模块。
BINARIES 要包含在initramfs映像中的其他二进制文件。
FILES 要包含在initramfs映像中的其他文件。
HOOKS 挂钩是在初始ramdisk中执行的脚本。
COMPRESSION 用于压缩initramfs映像。
COMPRESSION_OPTIONS 传递给COMPRESSION程序的额外参数。强烈建议不要使用此设置。mkinitcpio将处理压缩机的特殊要求(例如传递--check=crc32给xz),并且误用很容易导致系统无法启动。
2.5 Linux系统中的initramfs
当前的Arch linux系统/boot/目录下name | type | size |
vmlinuz-linux | DOS/Windows executable | 5.8Mb |
Initramfs-linux.img | Raw disk image | 8.7Mb |
Initramfs-linux-fallback.img | Raw disk image | 29.3Mb |
一些Linux的Live CD光盘文件里
Linux | name | type | size |
manjaro | initramfs-x86_64.img | Raw disk image | 37Mb |
ubuntu18 | initrd | CPIO archive | 38Mb |
mint191 | initrd.lz initrd.lz 解压后 initrd |
Lzip archive CPIO archive |
35Mb 153Mb |
2.6 cpio归档文件
https://en.wikipedia.org/wiki/Cpiocpio最初设计用于以连续,连续的方式在磁带设备上存储备份文件存档。它不压缩任何内容,但是通常使用gzip或其他外部压缩器压缩生成的归档。
档案创建
在使用-o命令行标志启动的复制操作期间创建存档时,cpio从其标准输入通道读取文件和目录路径名,并将生成的存档字节流写入其标准输出。
因此,Cpio通常与生成要归档的文件列表的其他实用程序一起使用,例如查找程序。
生成的cpio存档是一系列文件和目录,它们连接成一个存档,由带有文件元信息的标题部分分隔,例如文件名,inode编号,所有权,权限和时间戳。按照惯例,归档的文件名通常被赋予文件扩展名cpio。
此示例使用find实用程序生成从当前目录开始的路径名列表,以创建目录树的存档:
$ find . -depth -print | cpio -o > /path/archive.cpio
提取
在由命令行标志i启动的拷入操作期间,cpio从其标准输入读取存档,并在操作系统的文件系统中重新创建存档文件。
命令行标志d告诉cpio根据需要构造目录。标志v(详细)列出提取时的文件名。
$ cpio -i -vd < archive.cpio
$ cpio -i -d /etc/fstab < archive.cpio
清单
列出cpio存档中包含的文件:
$ cpio -t < archive.cpio
复制
此示例将从当前目录开始的目录树复制到文件系统中的另一个路径new-path,
保留文件修改时间(标志m),
根据需要创建目录(d),
无条件地替换任何现有文件(u),
同时生成标准输出的进度清单(v):
$ find . -depth -print | cpio -p -dumv new-path
3. 高级用户
3.1 制作自己的initramfs
http://blog.falconindy.com/articles/optmizing-bootup-with-mkinitcpio.html使用mkinitcpio优化启动
在最简单的情况下,挂载根分区需要以下驱动程序:
存储总线(PATA,SATA,SCSI等)
块设备
文件系统
lsinitcpio很高兴地向你展示了图像上的确切内容。
'mkinitcpio -M'将扫描您的PCI总线并探测您的根文件系统,返回一个整洁的模块列表,没有依赖项。
https://wiki.archlinux.org/index.php/Minimal_initramfs
最小的initramfs
3.2 Initramfs编程
https://landley.net/writing/rootfs-programming.html将一些可执行文件放入新的根文件系统。
使用mdev填充/dev
从rootfs切换到另一个根文件系统
3.3 使用更新的工具
https://wiki.archlinux.org/index.php/Dracutdracut创建内核使用的初始映像,用于预加载访问根文件系统所需的块设备模块(例如IDE,SCSI或RAID)。这可能会在不久的将来取代Arch Linux中的mkinitcpio。
https://dracut.wiki.kernel.org/index.php/Main_Page
注意:阅读邮件列表公告,了解可能使用Dracut替换Mkinitcpio。
https://lists.archlinux.org/pipermail/arch-dev-public/2019-May/029570.html
[arch-dev-public] Mkinitcpio replacement with Dracut
Giancarlo Razzolini grazzolini at archlinux.org
Tue May 21 02:41:40 UTC 2019
Mkinitcpio替换为Dracut的信息。有兴趣有能力的人可以多加关注,参与其中。
更多相关信息
https://landley.net/writing/rootfs-intro.html
https://wiki.debian.org/InitrdReplacementOptions
https://en.wikipedia.org/wiki/Initial_ramdisk
https://en.wikipedia.org/wiki/Tmpfs
https://en.wikipedia.org/wiki/Linux_startup_process
https://en.wikipedia.org/wiki/Initial_ramdisk
https://www.kernel.org/doc/Documentation/early-userspace/README 最后更新:2004-12-20
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt 2005年10月17日
https://wiki.archlinux.org/index.php/Arch_boot_process#initramfs
https://wiki.archlinux.org/index.php/Mkinitcpio
sztom
osoft@qq.com
CC-BY-NC-SA