配合Linux裝置驅動程式之開發詳解一書3.4章節閱讀
必備工具知識:vim,ctags使用,vim中可使用"/"來搜尋字串,並用"n"來搜尋下一個字串
i386中
1.bzImage被呼叫時,從/arch/i386/boot/setup.S的start:開始執行,並進行一些基本硬體設定
start: jmp trampoline # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature
2.接著呼叫/arch/i386/boot/compressed/head.S
# jump to startup_32 in arch/i386/boot/compressed/head.S3./arch/i386/boot/compressed/head.S之中有個startup_32常式,其主要功能為設定基本的執行環境,如堆疊,之後清除BSS段,並呼叫/arch/i386/boot/compressed/misc.c的decompress_kernel()解壓縮核心到記憶體,再跳到新的kernel
(/arch/i386/boot/compressed/head.S)
.globl startup_32 startup_32: cld cli movl $(__BOOT_DS),%eax movl %eax,%ds /* * Clear BSS */ xorl %eax,%eax movl $_edata,%edi movl $_end,%ecx subl %edi,%ecx cld rep stosb ...... /* * Do the decompression, and jump to the new kernel.. */ ...... call decompress_kernel (/arch/i386/boot/compressed/misc.c) asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; if (RM_SCREEN_INFO.orig_video_mode == 7) { vidmem = (char *) 0xb0000; vidport = 0x3b4; } else { vidmem = (char *) 0xb8000; vidport = 0x3d4; } lines = RM_SCREEN_INFO.orig_video_lines; cols = RM_SCREEN_INFO.orig_video_cols; if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); else setup_output_buffer_if_we_run_high(mv); makecrc(); putstr("Uncompressing Linux... "); gunzip(); putstr("Ok, booting the kernel.\n"); if (high_loaded) close_output_buffer_if_we_run_high(mv); return high_loaded; }4.核心被解壓縮到記憶體後,會再呼叫/arch/i386/kernel/head.S的startup_32常式,會初始化page table,並啟用記憶體分頁機制
ENTRY(startup_32)5.而上述做完之後,/init/main.c的start_kernel()被呼叫,進入和平台架構無關的linux核心部份,此時呼叫一堆初始化函式來設定中斷,和進一步的記憶體設定
/* * Activate the first processor. */ asmlinkage void __init start_kernel(void) {6.而/arch/i386/kernel/process.c中kernel_thread()啟動第一個核心thread,此執行緒執行init(),再來呼叫cpu_idle()等待排程 ?????? 7./init/main.c此時為核心執行緒,完成週邊設備和其driver的載入和初始化,和掛載根目錄,他會搜索檔案系統裡面的init程式,並使用execve()系統呼叫來執行init程式,順序為如下:
run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh");ps.多數情況下,嵌入式系統可以給核心傳入一個簡單的shell命令搞(script)來啟動必須的嵌入式應用程式 到目前為止,慢長得LInux核心初始化和啟動過程就結束了,而init()對應的,和由start_kernel()創見的第一個執行緒也進入使用者模式
沒有留言:
張貼留言