主题 : 关于启动过程中向kernel传递参数的问题。 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 11414
精华: 0
发帖: 15
金钱: 85 两
威望: 23 点
综合积分: 30 分
注册时间: 2009-12-07
最后登录: 2010-03-10
楼主  发表于: 2010-02-11 17:04

 关于启动过程中向kernel传递参数的问题。

void __init setup_arch(char **cmdline_p)
{
....
    if (__atags_pointer)
        tags = phys_to_virt(__atags_pointer);
    else if (mdesc->boot_params)
        tags = phys_to_virt(mdesc->boot_params);
.....
}

也就是说,如果bootloader向内核传递参数的话,就使用这个传递过来的信息;否则,使用boot_params所指向的配置信息。
boot_params一般是SDRAM_PA + 0x100。

问题1:
boot_params所指向的空间内容是什么时候写进去的?我没找到呢?
问题2:
一般bootloader传递参数的话,这个参数的首地址是多少?也是SDRAM_PA + 0x100?

谢谢!
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2010-02-11 22:28
boot_params所指向的空间内容是什么时候写进去的?我没找到呢?

很显然,这块空间的内容不是内核在启动过程中去写的。空间的地址是预先定义好的,所以只可能是bootloader在启动内核之前写入的。事实上它的功能等同于目前bootloader所建立的ATAG list,只是ATAG list比它更灵活,地址是由bootloader动态传递给内核的(启动内核时存储在r2寄存器中,http://www.arm.linux.org.uk/developer/booting.php,"5. Calling the kernel image")。

一般bootloader传递参数的话,这个参数的首地址是多少?也是SDRAM_PA + 0x100?

参数的首地址不是固定的,根据ARM Linux的创始者Russell King的解释,只要满足"The tagged list must be placed in a region of memory where neither the kernel decompressor nor initrd 'bootp' program will overwrite it"这个条件(http://www.arm.linux.org.uk/developer/booting.php, "4. Setup the kernel tagged list")就可以。但作为惯例,通常会取SDRAM起始地址 + 0x100(16K)的偏移这个地址.
关于ARM Linux内核的启动,http://www.arm.linux.org.uk/developer/booting.php是最权威的解释,希望你能仔细参考阅读。
[ 此帖被kasim在2010-02-11 22:34重新编辑 ]
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 11414
精华: 0
发帖: 15
金钱: 85 两
威望: 23 点
综合积分: 30 分
注册时间: 2009-12-07
最后登录: 2010-03-10
2楼  发表于: 2010-02-20 15:57
多谢斑竹!
春节没来得及看回复,刚回来;十五还没到,给大家拜个晚年!

@斑竹,请看看我的理解是否还有不妥:

我目前的理解是这样的:
1、atag_list跟boot_param的结构是不一样的。(为什么说atag_list更灵活呢?一方面是atag_list的结构易于扩展,另一方面难道是因为atag_list的地址是由boot_loader决定的?)
2、atag_list的地址是由bootloader传递过来的(通过r2寄存器);kernel解析它之前,会经历对kernel解压缩的过程,必须保证list不会被overwrite;通常bootloader会选择SDRAM_base + 0x100作为list的首地址(地址只要在有效范围内即可)。
3、boot_param的地址是编译的时候写死的(这个地址是禁止mmu的情况下的一个地址,是一个物理地址)。我的代码中这个地址是SDRAM_PA + 0x100(碰巧跟atag_list的地址一致)。如果使用这个方式进行参数传递的话,那么bootloader必须协同kernel定义、使用这个空间的地址。
4、bootloader会选择二者之一进行参数传递。

谢谢!
[ 此帖被zwinger在2010-02-20 16:06重新编辑 ]