歡迎您光臨本站 登入註冊首頁

arm linux演藝(八)

admin @ 2014-03-25 , reply:0

概述

長篇連載--armlinux演藝---第八回------------------------------------------------------------------------------……

長篇連載--arm linux演藝---第八回
--------------------------------------------------------------------------------

上回我們講到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 待續。。。。。


[admin via 研發互助社區 ] arm linux演藝(八)已經有2878次圍觀

http://cocdig.com/docs/show-post-42758.html