Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2891017
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2010-03-31 08:39:51

 

上回我们讲到arm靠初始化完成了,打开了cache,到此为止,汇编部分的初始化代码就差不多了,最后还有几件事情做:

1。初始化BSS段,全部清零,BSS是全局变量区域。
2。保存与系统相关的信息:如
.long SYMBOL_NAME(compat)
.long SYMBOL_NAME(__bss_start)
.long SYMBOL_NAME(_end)
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(__machine_arch_type)
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
不用讲,大家一看就明白意思

3。重新设置堆栈指针,指向init_task的堆栈。init_task是系统的第一个任务,init_task的堆栈在task structure的后8K,我们后面会看到。

4。最后就要跳到C代码的start_kernel。
b SYMBOL_NAME(start_kernel)

现在让我们来回忆一下目前的系统状态:
临时页表已经建立,在0X08004000处,映射了4M,虚地址0XC000000被映射到0X08000000.
CACHE,MMU都已经打开。
堆栈用的是任务init_task的堆栈。

如果以为到了c代码可以松一口气的话,就大错特措了,linux的c也不比汇编好懂多少,相反到掩盖了汇编的一些和机器相关的部分,有时候更难懂。其实作为编写操作系统的c代码,只不过是汇编的另一种写法,和机器代码的联系是很紧密的。

start_kernel在 /linux/init/main.c中定义:

asmlinkage void __init start_kernel(void)
{
char * command_line;
unsigned long mempages;
extern char saved_command_line[];
lock_kernel();
printk(linux_banner);
setup_arch(&command_line); //arm/kernel/setup.c
printk("Kernel command line: %s
", saved_command_line);
parse_options(command_line);

trap_init(); // arm/kernle/traps.c install
。。。。。。。。。

start_kernel中的函数个个都是重量级的,首先用printk(linux_banner);打出系统版本号,这里面就大有文章,系统才 刚开张,你让他打印到哪里去呢?先给大家交个底,以后到console的部分自然清楚,printk和printf不同,他首先输出到系统的一个缓冲区 内,大约4k,如果登记了 console,则调用console->wirte函数输出,否则就一直在buffer里呆着。所以,用printk输出的信息,如果超出了 4k,会冲掉前面的。在系统引导起来后,用dmesg看的也就是这个buffer中的东东。

arm linux 待续。。。。。

阅读(527) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~