linux默认内核参数位置,linux2.6内核,如何指定内核启动参数

}

这里的意思是从__setup_start开始处到__setup_end处中查找一个数据结构,这个数据结构中有str与setup_func这两个数据成员变量. 只要与这里面的str与输入的参数字符串相匹配,就会调用个这个字符串后面所指的内容,

比如

__setup("init=", init_setup);

表示在启动linux kernel 时如果有这么一个参数: "init=/bin/init",那么内核就会默认调用 init_setup 函数,以"/bin/init"作为参数进行执行。

那么我们有必要了解一下整个过程:

__setup() 是一个宏定义,在include/linux/init.h这个文件中,__setup 定义如下:

struct obs_kernel_param {

const char *str;

int (*setup_func)(char *);

int early;

};

#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)

上面有一个非常重要的字段:__section(.init.setup) 这个是与elf格式相关的一个内容,那么有必要看下 ld 链接器的脚本文件:

arch\mips\kernel\vmlinux.lds 片段:

.init.setup : {

__setup_start = .;

*(.init.setup)

__setup_end = .;

}

__setup_start是一个节的开始,而__setup_end是一个节的结束,这个节的名称是.init.setup

其中的内容就是一个数据结构,即一个str 及 setup_func ,2.6版本又增加了一个 early

那么就来看看生成的elf文件:

readelf -a vmlinux >>/home/vmlinux_elf生成一个描述elf结构的文件

[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

...

[15] .init.data        PROGBITS        804eba8c 4eba8c 0082ba 00  WA  0   0  4

[16] .init.setup       PROGBITS        804f3d50 4f3d50 000378 00  WA  0   0  4

[17] .initcall.init    PROGBITS        804f40c8 4f40c8 000354 00  WA  0   0  4

表明.init.setup 数据空间范围:0x804f3d50 - 0x804f40c8加载的的虚拟地址范围

0x4f3d50 - 0x4f40c8 在vmlinux实现数据空间地址范围

init_setup 映射的内存地址:

34: 804c903c    48 FUNC    LOCAL  DEFAULT   14 init_setup

前面的地址 804c903c 是其虚拟映射地址

使用命令:

od --address-radix=x -t x4 vmlinux |grep -A 20 4f3d50 |head -20 | grep 804c903c

4f3d60 804c903c 00000000 804f397e 804c90ac

表明其处理子符串内存地址是 804f397e

与前面得到的.init.data节在内存映射中的位置0x804eba8c 相减就是 0x7EF2,与.data.init在文件中的偏移量0x4eba8c相加就得到4F397E ,这样用

od --address-radix=x -a vmlinux-2.4.20-8 |grep -A 2 4F3970

其vmlinux内容如下所示:

43514929_1.gif

ok, init= 的值就在这里,不过这里是个 null 表明没有传递参数值而已。

=======================================================================

其实上面的一些分析都太无聊了,那么就列举下具体的解决问题方案吧:

文件系统mount失败

VFS: Cannot open root device "" or unknown-block(8,1)

Please append a correct "root=" boot option; here are the available partitions:

1f01          261120 mtdblock1 (driver?)

1f02            4096 mtdblock2 (driver?)

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,1)

根文件系统没有挂载成功,找找原因看看

解决方案:

由于cfe的参数无法传给kernel,导致启动参数为空。

Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024

Kernel command line:

PID hash table entries: 1024 (order: 10, 4096 bytes)

从这里也可以看出来,ok, 那么就将这些参数也写死好了,修改如下: arch/mips/kernel/setup.c (具体修改平台下的文件)

static void __init arch_mem_init(char **cmdline_p)

{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值