Linux kernel mips early_param

 

Linux kernel mips early_param

 

宏定义 early_param 用来注册处理内核参数。

 

例如:early_param("mem", early_parse_mem);用函数early_parse_mem来处理参数mem

<linux/init.h>

#define __setup_param(str, unique_id, fn, early) \

static const char __setup_str_##unique_id[] __initconst \

__aligned(1) = str; \

static struct obs_kernel_param __setup_##unique_id \

__used __section(.init.setup) \

__attribute__((aligned((sizeof(long))))) \

= { __setup_str_##unique_id, fn, early }

#define __setup(str, fn) \

__setup_param(str, fn, fn, 0)

/* NOTE: fn is as per module_param, not __setup!  Emits warning if fn

 * returns non-zero. */

#define early_param(str, fn) \

__setup_param(str, fn, fn, 1)

 

“##”字符是说明将前后两个字符串连接在一起。__setup_param的意思就是将结构struct obs_kernel_param添加到初始化段中(.init.setup

 

 

在连接脚本中<arch/mips/kernel/vmlinux.lds.S>可以找到答案。

Linux的内存布局中最后一个段_edata _end之间是存放的内核的启动的初始化数据。比如所有的_init_开头的函数。这些数据在初始化之后内存是要被释放的,通过kdb调试可以看出这段内存中的数据已经是乱了。

vmlinux.lds.S中,

/* will be freed after init */

. = ALIGN(PAGE_SIZE); /* Init code and data */

__init_begin = .;

INIT_TEXT_SECTION(PAGE_SIZE)

INIT_DATA_SECTION(16)

/* .exit.text is discarded at runtime, not link time, to deal with references from .rodata*/

.exit.text : {

EXIT_TEXT

}

.exit.data : {

EXIT_DATA

}

PERCPU(PAGE_SIZE)

. = ALIGN(PAGE_SIZE);

__init_end = .;

/* freed after init ends here */

<linux/include/asm-generic/vmlinux.lds.h>

#define INIT_DATA_SECTION(initsetup_align) \

.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { \

INIT_DATA \

INIT_SETUP(initsetup_align) \

INIT_CALLS \

CON_INITCALL \

SECURITY_INITCALL \

INIT_RAM_FS \

}

 

#define INIT_SETUP(initsetup_align) \

. = ALIGN(initsetup_align); \

VMLINUX_SYMBOL(__setup_start) = .; \

*(.init.setup) \

VMLINUX_SYMBOL(__setup_end) = .;

INIT_DATA_SECTION ---->INIT_SETUP

其中红色的部分是我们所需要关注的,其中__setup_start指向了段.init.setup的开始,__setup_end指向了段的结束。

函数do_early_param负责遍历这部分内存区域

static int __init do_early_param(char *param, char *val)

{

struct obs_kernel_param *p;

 

for (p = __setup_start; p < __setup_end; p++) {

if ((p->early && strcmp(param, p->str) == 0) ||

    (strcmp(param, "console") == 0 &&

     strcmp(p->str, "earlycon") == 0)

) {

if (p->setup_func(val) != 0)

printk(KERN_WARNING"Malformed early option '%s'\n", param);

}

}/* We accept everything at this stage. */

return 0;

}

在这个函数中会遍历内核的初始化区域,并且根据传递的参数来执行相应的内核参数处理函数。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值