目录
1 前言
2 DLKM module获取cmdline参数两种方式:
2.1 通过module加载参数形式获取:
2.2 通过fdt形式获取
Android GKI2.0方案中屏蔽了boot_command_line变量及cmd_line相关API,因此非built-in的内核module不能容易的获取command_line参数,故一些通过commad line参数来实现设备兼容方案不在适用。
如果有DLKM module必须通过获取command line来实现部分功能时,应怎么处理、怎样实现command line参数的获取?
module_param 用来实现module参数,有如下特性:
a. 会形成sys/module/module name/parameters/param name参数节点
b. 该参数会被链接到_parm 内存段
c. 该参数有会store 和show函数
d. 若built-in的module会在kernel启动时设备驱动加载前通
startkernel/doinitcalllevel -> parse_args对该module param参数进行赋值;
若dlkm的module可通过在该module被加载时传入参数
(load_module -> parse_args)来对该module param进行赋值;
module_param 定义见内核代码 /include/linux/moduleparam.h 中#define module_param,此处不做展开。
对于dlkm module,如果将command line以加载参数的形式传递给module param
则module也就是实现了对commad line变量的访问。在Andriod系统中modprobe即实现
此功能,modprobe在进行dlkm module加载时会先从proc/command_line节点获取
command line参数并对其中module参数化进行解析,在对该module进行insomd时以
module加载参数的形式将该数据传递给module,内核在执行具体的module加载前会对传入
的module参数进行解析赋值给module_parm声明的变量。
modprobe从cammad line中解析module相关代码如下:
256 void Modprobe::ParseKernelCmdlineOptions(void) { 257 std::string cmdline = GetKernelCmdline(); //获取cmd_line数据 ... 267 for (int i = 0; i < cmdline.size(); i++) { ... 310 if (in_value && !in_quotes) { 311 value = cmdline.substr(start, cmdline.size() - start); 312 if (!module_name.empty() && !option_name.empty()) { 313 AddOption(module_name, option_name, value); //将解析到的module参数添加到 //module加载参数 314 } 315 } 316 }
需要重点注意的是:command_line中数据要成为module加载参数,则需要符合特性的参数规则即 module_name module_param_name=module_parm_value,此规则可以通过ParseKernelCmdlineOptions函数。
在Android GKI2.0方案中开放的kernel API中包含了大部分fdt接口函数,使得dlkm module也可以获取fdt root,如此为module获取所有fdt数据提供了便利,module可以解析非该module的fdt node 的数据。如果fdt中包含了module param所需的数据,则module就可以通过fdt相关的API接口获取解析fdt来获取module数据。
此方案亦有两种实现逻辑:
a. 在引导kernel启动的代码逻辑中(如uboot),为dlkm module添加需要的fdt node。
相关代码参考:uboo中fdt相关函数见 uboot/lib/libfdt 。
b. 最新的内核版本中commad line也是来自fdt,也可以通过在dlkm module代码逻辑
中直接解析fdt的command line数据进而获取module param。
相关代码实现:early_init_dt_scan_chosen \ of_scan_flat_dt
至此dlkm module从command line获取的module param两种方式:module加载参数 和 fdt形式介绍完毕。