内核启动命令行参数解析 设计方案

需求

提供类似Linux的内核启动命令行参数的解析支持,以便更灵活的让内核执行不同的行为。

Linux的行为

https://www.kernel.org/doc/html/v6.6/admin-guide/kernel-parameters.html

Linux的内核参数是以空格分开的一个字符串列表,通常具有如下形式:

name[=value_1][,value_2]…[,value_10]

“name”是关键字,内核用它来识别应该把“关键字”后面的值传递给谁,也就是如何处理这个值,是传递给处理例程还是作为环境变量或者抛给“init进程”。值的个数限制为10,你可以通过再次使用该关键字使用超过10个的参数。

首先,内核检查关键字是不是 root=',nfsroot=‘, nfsaddrs=', ro’, rw', debug’或 `init’,然后内核在bootsetups数组里搜索于该关键字相关联的已注册的处理函数,如果找到相关的已注册的处理函数,则调用这些函数并把关键字后面的值作为参数传递给这些函数。比如你在启动时设置参数name=a,b,c,d,内核搜索bootsetups数组,如果发现“name”已注册,则调用“name”的设置函数如name_setup(),并把a,b,c,d传递给name_setup()执行。

内核解析从内核命令行到“ --”的参数;如果它无法识别某个参数并且该参数不包含“.”,则该参数将传递给 init:带有“=”的参数进入 init 的环境,其他参数将作为命令行参数传递给 init。“ --”之后的所有内容都将作为参数传递给 init。

所有型如“name=value”参数,如果没有被上面所述的设置函数接收,将被解释为系统启动后的环境变量,比如“TERM=vt100”就会被作为一个启动时参数。

所有没有被内核设置函数接收也没又被设置成环境变量的参数都将作为命令行参数,留给init进程处理,比如“single”.

设计方案

参数类型

Arg类型

Arg类型的参数,在命令行中表现为只有name,没有value。

这种类型的参数,又分为以下两种类型:

  • ArgNormal:默认值为false,如果命令行中包含了这个值,那么会调用回调函数。

  • ArgInv:默认值为true,如果命令行中不包含这个值,则会调用回调函数。

KV类型

  • KV类型的参数,value按照逗号分隔。

  • 每次出现,都会调用回调函数,把字符串添加到参数字符串末尾。

  • 内核模块可提供参数的默认值,如果没有指定,那么默认值就是空字符串

  • 提供迭代器,把value解析为列表

Module标志

Module标志指的是类似这样的:usbprobe.xxxx

参数声明

  • 提供宏,声明内核命令行参数。

  • 提供一个trait,允许指定参数的回调函数

procfs支持

在/proc/cmdline下显示当前内核的启动命令行参数

1 个赞

PR链接:

TODO:

  • 支持在/proc/cmdline下面查看内核启动时的命令行参数。(现在没实现是因为procfs写的太大便了,不想再往上面拉一坨。打算在将来procfs重构的时候支持这个功能)
  • 支持回调函数,允许更加灵活的设置参数的值(目前用不到,就没写了)
1 个赞