Linux 从 InitramFS“UserSpace”修改/添加内核命令行

Linux 从 InitramFS“UserSpace”修改/添加内核命令行

我正在开发一个嵌入式 Linux 设备。我已经成功创建了一个 InitramFS CPIO 存档,该存档在启动后可以快速运行。现在,我想更改初始内核命令行以包含“quiet”参数,这样我就可以更快地启动。

但是,一旦 InitramFS 中显示启动屏幕,我想删除内核的安静选项,以便引导的其余部分不安静。

我怎样才能实现这个目标?一旦到达 InitramFS,如何反转初始“安静”内核命令行选项?

谢谢。

答案1

您无法在启动后真正更改内核命令行,但是您可以所做的就是通过其他方式重现设置或取消设置命令行的效果quiet,这应该可以完成您想要在此处实现的目标。

简而言之,如果您不再需要增加详细程度quiet,可以使用以下命令:

# echo 7 >/proc/sys/kernel/printk

为了模拟它的quiet作用,您可以使用以下内容:

# echo 4 >/proc/sys/kernel/printk

这应该照顾内核方面的设置...但有时用户空间也会根据此内核选项更改行为。例如,systemd 将解析quiet内核命令行中的选项,并像ShowStatus=auto/etc/systemd/system.conf.如果您想恢复它(以强制执行默认值并忽略该quiet选项),请编辑该配置文件并取消注释ShowStatus=yes其中的行,这应该可以处理它。

用户空间中可能有其他系统查看此选项,因此您可能需要仔细查看这些系统以了解它们的行为以及如何重现(或撤消)内核命令行中存在的选项的行为。

以下是对源代码的深入研究,以解释quiet内核和 systemd 中选项的行为。


内核quiet通过调用来解析该选项quiet_kernel()初始化函数,它的作用是:

static int __init quiet_kernel(char *str)
{
    console_loglevel = CONSOLE_LOGLEVEL_QUIET;
    return 0;
}

early_param("quiet", quiet_kernel);

伪变量console_loglevel实际上是console_printk数组的第一个元素:

extern int console_printk[];

#define console_loglevel (console_printk[0])

日志级别“安静”被定义为 4:

#define CONSOLE_LOGLEVEL_QUIET   4 /* Shhh ..., when booted with "quiet" */

下面几行,默认日志级别通过内核配置定义:

/*
 * Default used to be hard-coded at 7, we're now allowing it to be set from
 * kernel config.
 */
#define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT

该内核配置是在Kconfig.debug中设置,仍然默认为7:

config CONSOLE_LOGLEVEL_DEFAULT
    int "Default console loglevel (1-15)"
    range 1 15
    default "7"

(您可能想检查您的内核是否使用默认配置,无论是在 中/boot/config-*还是在 中/proc/config.gz。)

有关使用的更多详细信息/proc/sys/printk,请参阅它的内核文档。但是,简而言之,可以只写入一个数字,在这种情况下,只有数组的第一个元素会被更新,这正是您想要的。


systemd 还将解析内核命令行,查找通常名为 的条目systemd.*,但事实证明systemd 还可以识别quiet内核命令行并用它来设置 ShowStatus:

    } else if (streq(key, "quiet") && !value) {

            if (arg_show_status == _SHOW_STATUS_UNSET)
                    arg_show_status = SHOW_STATUS_AUTO;

在这种情况下,仅当之前未设置时才会设置它 ( _SHOW_STATUS_UNSET),并将其设置为“自动”( SHOW_STATUS_AUTO。)

设置 ShowStatus 的另一种方法是通过配置文件:

            { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },

ShowStatus=该行描述了在[Manager]部分下命名的配置选项system.conf。这该选项的解析器采用“auto”字符串(在这种情况下将其设置为SHOW_STATUS_AUTO)或采用布尔值,可以是“yes”、“true”或“1”来启用它,也可以是“no”、“false”或“0” ”来禁用它。

系统文档--show-status=这里也很有帮助。它ShowStatus=也引用了配置(由于直接传递 systemd 命令行参数并不总是那么容易,因此更新配置文件绝对是配置此设置的更直接的方法。)


我希望您发现这很有帮助,并且它可以帮助您为您的特定用例实现正确的详细程度!

相关内容