Skip to content

Latest commit

 

History

History
42 lines (33 loc) · 1.97 KB

2015-01-13 为 Linux 添加自定义内核参数.md

File metadata and controls

42 lines (33 loc) · 1.97 KB
  • tags: linux
  • date: 2015-01-13

为 Linux 添加自定义内核参数

系统内核开发通常需要频繁的编译内核,即使是做一些非常微小的调整。然而在有些情况下为内核添加一个启动参数并结合更加普适的内核代码是非常方便的,比如需要调整启动时的预留内存大小,通过添加启动参数的办法即可以重启完成原来需要编译内核的任务。

我们可是使用 early_param 宏或者 __setup 宏来注册一个新的启动参数,并把这个启动参数解析的过程映射到一个特定的函数上。

early_param 的原理是通过 __section 宏,编译器会将参数信息放置在 .init.setup section 中,当需要解析参数的时候调用 parse_early_param 其中遍历 .init.setup 段中的 struct obs_kernel_param 变量。如果 p->early 为真且为对应的选项字符串,则调用注册的处理函数 p->setup_func 。

函数调用流程为:
start_kernel -> parse_early_param -> parse_early_options -> parse_args -> do_early_param

struct {
        unsigned long long start;
        unsigned long long size;
} nodes_offset[MAX_NUMNODES];
static int __init get_nodes_offset(char *str)
{
        char *endptr, *ptr; int i;
        ptr = str;
        for(i = 0; i < MAX_NUMNODES; i++) {
                nodes_offset[i].start = 0;
                nodes_offset[i].size = 0;
        }
        for(i = 0; i < MAX_NUMNODES; i++) {
                nodes_offset[i].start = memparse(ptr, &endptr);
                ptr = ++endptr;
                nodes_offset[i].size = memparse(ptr, &endptr);
                if ((*endptr) == '\0') break;
                ptr = ++endptr;
        }
        return 0;
}
early_param("nodes_offset", get_nodes_offset);

上面的例子中将参数 nodes_offset 的解析关联到 get_nodes_offset 函数

__setup 与 early_param 的区别在于 __setup 注册的函数在 parse_args 中解析,这通常会比 early_param 更晚一些