armlinux演艺---第八回
上回我们讲到arm靠初始化完成了,打开了cache,
%A 到此为止,汇编部分的初始化代码就差不多了,最后还有几件事情做:
%A
%A 1。初始化BSS段,全部清零,BSS是全局变量区域。
%A 2。保存与系统相关的信息:如
%A .long SYMBOL_NAME(compat)
%A .long SYMBOL_NAME(__bss_start)
%A .long SYMBOL_NAME(_end)
%A .long SYMBOL_NAME(processor_id)
%A .long SYMBOL_NAME(__machine_arch_type)
%A .long SYMBOL_NAME(cr_alignment)
%A .long SYMBOL_NAME(init_task_union)+8192
%A 不用讲,大家一看就明白意思
%A
%A 3。重新设置堆栈指针,指向init_task的堆栈。init_task是系统的第一个任务,init_task的堆栈在task structure的后8K,我们后面会看到。
%A
%A 4。最后就要跳到C代码的start_kernel。
%A b SYMBOL_NAME(start_kernel)
%A
%A 现在让我们来回忆一下目前的系统状态:
%A 临时页表已经建立,在0X08004000处,映射了4M,虚地址0XC000000被映射到0X08000000.
%A CACHE,MMU都已经打开。
%A 堆栈用的是任务init_task的堆栈。
%A
%A 如果以为到了c代码可以松一口气的话,就大错特措了,linux的c也不比汇编好懂多少,相反到掩盖了汇编的一些和机器相关的部分,有时候更难懂。其实作为编写操作系统的c代码,只不过是汇编的另一种写法,和机器代码的联系是很紧密的。
%A
%A start_kernel在 /linux/init/main.c中定义:
%A
%A asmlinkage void __init start_kernel(void)
%A {
%A char * command_line;
%A unsigned long mempages;
%A extern char saved_command_line[];
%A lock_kernel();
%A printk(linux_banner);
%A setup_arch(&command_line); //arm/kernel/setup.c
%A printk("Kernel command line: %s
%A ", saved_command_line);
%A parse_options(command_line);
%A
%A trap_init(); // arm/kernle/traps.c install
%A 。。。。。。。。。
%A
%A start_kernel中的函数个个都是重量级的,首先用printk(linux_banner);打出
%A 系统版本号,这里面就大有文章,系统才刚开张,你让他打印到哪里去呢?
%A 先给大家交个底,以后到console的部分自然清楚,printk和printf不同,他首先输出到系统的一个缓冲区内,大约4k,如果登记了console,则调用console->wirte函数输出,否则就一直在buffer里呆着。所以,用printk输出的信息,如果超出了4k,会冲掉前面的。在系统引导起来后,用dmesg看的也就是这个buffer中的东东。
%A
%A 待续。。。。。
%A
%A%A
%A
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。