Linux 命令行参数

作者:Jeff Tranter

考虑以下情况

场景 1:您正在从 CDROM 安装 Linux,但是内核没有使用 CD-ROM 驱动器的正确 I/O 地址。您可以通过重新编译内核来纠正此问题,但是要构建内核,您首先需要从 CD-ROM 安装 Linux...

场景 2:您对系统启动脚本 rc.local 进行了更改,现在您的系统在启动时挂起。如何在不重新安装 Linux 的情况下修复错误?

场景 3:您想尝试各种可用的 VGA 控制台视频模式,而无需每次都重新编译内核。

场景 4:您刚刚编写了一个大型应用程序,该应用程序在您的系统上运行良好。它在朋友的机器上运行得如何,该机器只有 4MB 的 RAM 并且没有浮点协处理器?

Linux 及其向内核传递命令行参数的能力为解决这些问题中的每一个提供了一种方案。不幸的是,这些选项没有得到很好的文档记录(一些 HOWTO 文档顺便提到了某些选项,例如,SCSI HOWTO 文档提到了某些 SCSI 相关选项),并且其中许多选项是最近才添加的。我们将在本文中探讨它们。

Linux 启动

为了理解命令行参数如何融入到整个方案中,让我们简要地了解一下 Linux 启动时发生的事情。

对于那些不怕查看内核源代码的人,我将提到一些相关文件。给出的文件名相对于您安装内核源代码的位置,通常是 /usr/src/linux。因此,对文件 boot/bootsect.S 的引用应该在 /usr/src/linux/boot/bootsect.S 中找到。此信息对于 Linux 内核版本 1.2 有效。

从开机开始,PC ROM BIOS 例程从软盘或硬盘加载启动代码。如果从硬盘启动,这通常是由 LILO 安装的引导加载程序。如果从软盘启动,则是文件 boot/bootsect.S 中的代码。这反过来又加载文件 boot/setup.S 中的代码并运行它。此模块从 BIOS 读取一些信息(VGA 模式、内存量等),并记录下来以供以后使用。稍后将需要它,因为一旦内核启动,BIOS 例程将(通常)不再使用。

设置代码接下来切换到保护模式(32 位),然后加载并运行文件 boot/head.S 中的代码。(实际上,对于压缩内核,这在最近的内核中总是如此,内核本身首先使用 zBoot/head.S 中的代码解压缩)。这设置了更多的 32 位环境,获取命令行参数(通常来自 LILO),并将它们传递给例程 start_kernel

到目前为止,一切都是用汇编语言编写的。此时,我们现在切换到函数 start_kernel,用 C 语言编写,位于文件 init/main.c 中。这是执行大部分选项解析的代码,将许多内核特定参数的信息保存在全局变量中,以便内核在需要时可以使用它们。

作为“名称=值”对给出的任何其他参数都作为参数和环境变量传递给下一个进程。

第一个内核进程现在为多任务处理设置了一些东西,并首次调用 fork 系统调用,创建一个新进程;我们现在正在进行多任务处理。原始(父)进程成为“空闲进程”,只要没有进程准备好运行,就会执行该进程。子进程(进程 ID 为 1)调用程序 init。(它实际上在许多位置查找,包括 /etc/init/bin/init/sbin/init/etc/rc,最后是 /bin/sh。)然后,init 程序启动所有初始系统进程,例如 getty 和其他守护进程,不久之后我们在控制台上得到了登录提示符。

在内核编译时设置参数

在编译 Linux 内核时,可以设置许多重要的选项。这些选项包括根设备、交换设备和 VGA 视频模式。顶层 Makefile 允许设置大多数这些选项。

此方法的缺点是重新编译内核有些耗时(至少在我的机器上是这样;您有 100MHz Pentium 吗?)。您还必须修改标准 Makefile,并记住在升级到较新的内核时继续这样做。

使用 rdev 设置参数

rdev 命令很久以前就被编写出来,以便更容易地设置一些重要的内核选项,而无需重新编译。该程序直接修补内核映像中的相应变量。这些变量位于固定地址(在 boot/bootsect.S 中定义)。

虽然使用 rdev 速度很快,但仍然有些不方便,因为您必须记住在构建每个内核后运行它。它还限制了可以更改的选项。我们可以做得更好。

使用 LILO 设置参数

如果您使用 LILO(LInux LOader)程序启动 Linux(通常从硬盘启动),那么您可以在启动时将命令行选项传递给内核。通常,这些选项在配置文件 /etc/lilo.conf 中设置。

这是最灵活的方法。它允许您,例如,启动不同的内核或使用不同的选项启动相同的内核。

大多数选项由 LILO 传递给内核;一个有用的选项由 LILO 本身解析和处理。VGA 显示器的控制台视频模式可以使用以下形式的命令行选项设置

vga=mode

其中 mode 可以是以下之一

  • “normal”表示默认的 80 列 x 24 行显示,

  • “extended”或“ext”表示 80 列 x 50 行,

  • “ask”表示在启动时提示用户输入要使用的模式,或者

  • 一个十进制数字,用于选择各种其他模式,具体取决于 VGA 卡的类型(例如,在我的 Trident VGA 卡上,模式 6 是 132x30)。

内核特定参数

现在让我们看看 Linux 内核支持的特定选项。这些选项影响内核自身的行为,并且不会传递给 init 程序。

其中一些选项接受数值,由 strtoul 库函数的简化版本解析。值可以以十进制(例如,1234)、八进制(例如,01234)或十六进制(例如,0x1234)给出,并且应以空格分隔。现在让我们检查每个选项。

root=device

例如,root=/dev/hda

此选项设置根设备;用作根(“/”)文件系统的设备;启动时。它接受来自硬编码的常用设备列表中的值:/dev/hda..b(IDE 硬盘)、/dev/sda..e(SCSI 磁盘)、/dev/fd(软盘)和 /dev/xda..b(XT 硬盘)。这些映射到相应的主设备号和次设备号。

此选项指示根文件系统应以只读方式挂载。通常这样做是为了在启动时运行 fsck

rw

此选项与前一个选项相反,指示根文件系统应以读写方式挂载,这是一旦 Linux 系统启动后的正常情况。

debug

此选项将内核日志记录级别设置为 10,而不是默认值 7。它设置全局变量“console_loglevel”。目前,这没有明显的区别;显然没有内核代码以高于 7 的级别显示消息。

no-hlt

这将全局变量“hlt_works_ok”设置为 0。当 Linux 空闲时,它在一个循环中运行前面提到的空闲进程(在 kernel/sys.c 中找到)。让空闲进程定期执行 hlt(halt)指令可以降低某些机器(尤其是笔记本电脑)的功耗。但是,一些用户报告说在某些机器上使用 kilt 指令时出现问题,因此可以使用此选项禁用它。

顺便说一句,我在我的台式机系统上经常使用此选项;我发现它可以显着降低我的声卡上拾取的总线噪声水平。

no387

此选项将全局变量“hard_math”设置为 0。它强制内核使用协处理器仿真,即使安装了协处理器。如果您怀疑协处理器存在硬件问题,或者如果您想在没有数学芯片的情况下测量性能,这可能很有用。

mem=bytes

例如,mem=4000000

此选项指定内核要使用的最高内存地址(以字节为单位指定)。通常,Linux 使用所有可用内存。此功能对于模拟内存较少的机器或调试具有大量内存的机器上的缓存问题很有用。作为实验,尝试使用较少的内存(例如 2MB)启动您的机器,以突出显示内存带来的差异。作为另一个实验,看看如果您撒谎并告诉 Linux 您拥有的内存多于实际安装的内存会发生什么...

reserve=port, size. . .

例如,reserve=Ox320,0x20

此选项保留 I/O 端口;它将它们标记为已使用,以便设备驱动程序不会探测它们进行自动探测。在某些具有不寻常硬件或设备冲突的系统上可能需要这样做。

ramdisk=size

例如,ramdisk=2000000

此选项设置 RAM 磁盘的大小,以字节为单位。

设备驱动程序特定参数

下一组选项特定于各个内核设备驱动程序。我不会详细描述它们中的每一个,因为其中一些选项相当专业,并且在其他地方有文档记录。

ether=a,b,c,d,e

此选项用于设置以太网接口。它允许设置中断请求号和基地址等参数。参数的含义在某种程度上取决于接口卡的类型。《以太网 HOWTO》文档详细描述了这些内容。

max_scsi_luns=number

此选项设置要用于 SCSI 设备的最高逻辑单元号。有效值为 1 到 S。如果 SCSI 总线的自动探测在您的系统上引起问题,则可能需要这样做。

hd=cylinders, heads, sectors

此选项设置 SCSI 或 IDE 硬盘的硬盘几何结构。通常,Linux 从 BIOS 获取这些信息;如果这些信息不正确,可以使用命令行选项覆盖它们。

st=buffer size,write_threshold,tape_buffers

此选项用于设置 SCSI 磁带驱动程序参数。文件 drivers/scsi/README.st 详细描述了这些内容。

bmouse=irq

此选项设置要用于总线鼠标驱动程序的中断请求线。

stOx=parameters
tmc8xx=parameters
stOx=parameters
tl28=parameters
pasl6=parameters
ncr5380=parameters
ncr5380=parameters
ahal52x=parameters

这些都是用于设置 Linux 内核支持的各种 SCSI 主机适配器的选项。有关更多信息,请参见《SCSI HOWTO》。

xd=type, irq,i/o base_address,dma_channel

此选项设置 XT 硬盘驱动程序参数。有关更多信息,请参见文件 drivers/block/xd.c 中的注释。

mcd=port, irq, workaround_bug

这设置了 Mitsumi CD-ROM 接口。前两个参数是控制器和中断请求的基 I/O 地址。第三个选项设置一个延迟值,用于解决某些 Mitsumi 驱动器的问题。

sound=parml, parm2,...

这些选项设置声音驱动程序。文件 drivers/sound/Readme.linux 中解释了参数编码。

sbpcd=address, type

例如,stpod=Ox230,SoundBlaster

此命令设置 SoundBlaster/Panasonic CD-ROM 驱动程序的参数。有关详细信息,请参见文件 drivers/block/README.stpod。

传递给 init 的参数

任何其他选项都以其 argv 数组和环境变量的形式传递给 init。例如,如果系统在没有手动输入的命令行的情况下启动,则 LILO 会传递参数“auto”。命令“single”将指示 init 在单用户模式下启动 Linux。

以下是如何查看传递给 init 的选项的方法

% ps -awww | grep init
        1 con S 0:03 init auto

proc 文件系统还允许您查看传递给 init 的环境,init 的进程 ID 始终为 1

% cat /proc/l/environ | tr t'\O'' "\n"
        HOME=/
        TERM=conl32x30
最终评论

一位同事建议添加一个缺失的内核选项:“help”。虽然这尚未实现,但希望本文已使您确信还有许多其他有用的选项值得探索。

(Jeff.Tranter@Software.Mitel.com) 是加拿大渥太华一家电信公司的软件设计师。他使用 Linux 已超过两年,并且是《Linux Sound and CD-ROMs》和多个 Linux 实用程序的作者。

加载 Disqus 评论