Linux kernel cmdline,_setup宏和core_param代码分析

本文深入分析了Linux内核启动过程中cmdline参数的处理,探讨了gcc的内存对齐规则,并详细解释了_setup宏和core_param在配置参数传递给内核过程中的作用。通过代码解析,展示了从dts到内核初始化函数的过程,涉及的关键结构体、函数和宏的使用。

cmdline代码分析

先介绍gcc的两个属性__attribute__aligned
1. __attribute__ 为修饰对象的属性以及改变其类型;aligned(m),为m字节对齐。
sizeof(int) = 4sizeof(char) = 1sizeof (char *) = 8

 	struct stu {
   
   
    char name[5];
    int length;
    //char *sex;                                                                                                                                                  
};//__attribute__((aligned(8)));

上述sizeof(stu) = 12,结构体储存有一条规则是按照成员变量最大的对齐,由于int为4字节,因此4个char储存为4个字节,另外一个char也要储存为4个字节(即其它3个字节padding)。

 	struct stu {
   
   
    char name[5];
    int length;
    //char *sex;                                                                                                                                                  
} __attribute__((aligned(8)));

上述sizeof(stu) = 16

 	struct stu {
   
   
    char name[13];
    int length;
    //char *sex;                                                                                                                                                  
} __attribute__((aligned(8)));

上述sizeof(stu) = 24

2.cmdline代码分析
下面是以kernel 4.14版本进行分析,在现有的版本cmdline都是在kernel CONFIG里面配置,比如:
CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/nfs nfsroot=192.168.0.1:/home/rootfs"
那么这个参数,怎么传递给kernel呢?
先上几个常见的宏:

#define __init		__section(.init.text) __cold notrace
#define __initdata	__section(.init.data)
#define __initconst	__section(.init.rodata)
#define __exitdata	__section(.exit.data)
#define __exit_call	__used __section(.exitcall.exit)

init/main.c中定义了一个全局变量char __initdata boot_command_line[COMMAND_LINE_SIZE];,该变量储存在section中的.init.data数据段中,COMMAND_LINE_SIZE =2048,这个boot_command_line会在init/main.c里面去解析,做出相应的load函数。
而在解析dtb的源文件中的drivers/of/fdt.c,可以找到boot_command_line该变量;然后改变量可以得到dts里面的CONFIG_CMDLINE字符串值。
代码分析如下:

#ifdef CONFIG_CMDLINE
static const char *config_cmdline = CONFIG_CMDLINE;
### cmdline_append用法 `cmdline_append` 用于向内核命令行追加额外的参数。一般在代码中调用该函数来动态添加参数。例如在嵌入式系统开发中: ```c #include <linux/kernel.h> #include <linux/module.h> static int __init my_module_init(void) { char *new_param = "myparam=value"; cmdline_append(new_param); return 0; } static void __exit my_module_exit(void) { // 模块退出处理 } module_init(my_module_init); module_exit(my_module_exit); MODULE_LICENSE("GPL"); ``` ### module_param_string用法 `module_param_string` 用于在模块中定义一个字符串类型的参数,允许用户在加载模块时传递字符串值。示例如下: ```c #include <linux/init.h> #include <linux/module.h> static char my_string[256]; module_param_string(my_string, my_string, sizeof(my_string), 0644); static int __init my_module_init(void) { printk(KERN_INFO "My string parameter: %s\n", my_string); return 0; } static void __exit my_module_exit(void) { printk(KERN_INFO "Module exiting\n"); } module_init(my_module_init); module_exit(my_module_exit); MODULE_LICENSE("GPL"); ``` 加载模块时可以使用如下命令传递参数: ```bash insmod my_module.ko my_string="Hello, World!" ``` ### 区别 - **作用对象**:`cmdline_append` 是针对内核命令行,为整个内核启动过程添加参数;而 `module_param_string` 是针对内核模块,为特定的模块传递参数[^2]。 - **生效时间**:`cmdline_append` 一般在运行时动态追加,影响内核后续的行为;`module_param_string` 在模块加载时传递参数,仅对该模块起作用。 - **参数传递方式**:`cmdline_append` 是在代码中调用函数追加参数;`module_param_string` 是在加载模块的命令行中传递参数。 ### 应用场景 - **cmdline_append应用场景**:常用于调试测试,可在不重启系统的情况下快速修改内核参数;也可用于动态配置,根据系统运行时的条件调整内核行为。 - **module_param_string应用场景**:适用于模块需要根据用户输入的不同字符串值来改变自身行为的情况,比如模块需要根据用户传递的配置文件路径来加载不同的配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值