您的位置:首页 > 运维架构 > Linux

linux内核移植s3c2410,移植正式开始2

2010-03-18 14:49 453 查看
内核启动的现在已经是开始执行函数start_kernel函数了。start_kernel函数在init/main.c中定义。start_kernel函数只是完成

相应的结构的初始化任务。

printk(KERN_NOTICE);

printk(linux_banner);

setup_arch(&command_line);

在uboot的一直过程中,uboot传递给kernel的参数:预先存放在某个地方的tag和机器类型id,机器类型id在函数__look_up_machine

中已经使用,tag列表是在函数setup_arch中调用的。setup_arch函数是在arch/arm/kernel/setup.c中定义:

void __init setup_arch(char **cmdline_p)

{

....

setup_processor(); // 处理器相关的设置

mdesc = setup_machine(machine_arch_type); // 得到machine_desc结构

machine_name = mdesc->name;

...

if (mdesc->boot_params) // 定义了uboot的参数

tags = phys_to_virt(mdesc->boot_params); // 得到uboot参数tag地址

...

if (tags->hdr.tag == ATAG_CORE) {

if (meminfo.nr_banks != 0) // 在内核中定义了meminfo

squash_mem_tags(tags); // 忽略内存中的信息

parse_tags(tags); // 解析tag

}

...

memcpy(boot_command_line, from, COMMAND_LINE_SIZE);

boot_command_line[COMMAND_LINE_SIZE-1] = '\0';

parse_cmdline(cmdline_p, from); // 解析命令行

paging_init(&meminfo, mdesc); // 重新初始化页表

request_standard_resources(&meminfo, mdesc);

...

}

上面函数的疑问是if (mdesc->boot_params) // 定义了uboot的参数,uboot的参数是在那里定义的?答案就是在arch/arm/

mach-s3c2410/mach-smdk2410.c中定义:

MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch

...

.boot_params = S3C2410_SDRAM_PA + 0x100,

MACHINE_END

然后就是函数parse_tags的作用是什么?uboot在传递给kernenl的信息,在这里称之为tag,解析字符串tag,然后将得到的

信息保存到全局的变量中,在setup.c中定义如下:

unsigned int system_serial_low;

EXPORT_SYMBOL(system_serial_low);

...

static int __init parse_tag_serialnr(const struct tag *tag)

{

system_serial_low = tag->u.serialnr.low;

system_serial_high = tag->u.serialnr.high;

return 0;

}

...

/*

* Scan the tag table for this tag, and call its parse function.

* The tag table is built by the linker from all the __tagtable

* declarations.

*/

static int __init parse_tag(const struct tag *tag)

{

extern struct tagtable __tagtable_begin, __tagtable_end;

struct tagtable *t;

for (t = &__tagtable_begin; t < &__tagtable_end; t++)

if (tag->hdr.tag == t->tag) {

t->parse(tag);

break;

}

return t < &__tagtable_end;

}

...

/*

* Parse all tags in the list, checking both the global and architecture

* specific tag tables.

*/

static void __init parse_tags(const struct tag *t)

{

for (; t->hdr.size; t = tag_next(t))

if (!parse_tag(t))

printk(KERN_WARNING

"Ignoring unrecognised tag 0x%08x\n",

t->hdr.tag);

}

于是上面的函数调用是:在setup.c中调用函数parse_tags(tags);,在parse_tags(tags);函数中调用函数parse_tag,parse_tag

函数中根据不同的tag,调用 t->parse(tag)。

当然命令行的参数处理并不只是在setup_arch(,在start_kernel中同样还有,具体参见代码。

最后一个疑问是 paging_init(&meminfo, mdesc);完成了什么?该函数的调用形式:

paging_init(&meminfo, mdesc);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: