本文介紹arm linux啓動的第二部分,C語言編寫,主要講述start_kernel到1號進程的建立。主要講述大概過程,之後再對子函數進行講解。linux
1、start_kernel數據結構
start_kernel位於init/main.c,主要完成linux一些子系統的初始化。架構
1)smp_setup_processor_id() 單CPU位爲空。異步
2)lock_kernel() 鎖CPU,linux是支持搶佔的,多CPU時調用這個函數防止其餘CPU搶佔。
3)tick_init() 時間相關初始化
4)boot_cpu_init() 肯定有多少個CPU可用。如今以單CPU講述。
5)page_address_init() 初始化高端內存。linux內核空間爲1G,對應最大能支持的物理內存也是1G。爲了可以支持超過1G的內存,使用高端內存(128M)來進行映射處理。函數
6)setup_arch(&command_line),位於arch/arm/kernel/setup.c 這個函數比較重要。ui
i setup_processor 初始化CPU體系架構, setup_machine初始化平臺數據結構spa
ii init_mm 初始化1號進程的task_struct命令行
iii parse_cmdline(cmdline_p, from) 獲取default啓動參數,取得相關的啓動命令信息。線程
iv paging_init(&meminfo, mdesc); 建立正式頁表rest
v request_standard_resources(&meminfo, mdesc); 申請IO資源
vi 相關全局變量賦值 init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
7)mm_init_owner 初始化init的內存,arm體系爲空
8)setup_command_line(command_line)獲取uboot中的bootargs參數,取得相關的啓動命令信息
9) setup_nr_cpu_ids();setup_per_cpu_areas();smp_prepare_boot_cpu() 多CPU函數
10)build_all_zonelists() 初始化全部內存管理節點列表,以便後面進行內存管理初始化。
11)page_alloc_init() 物理內存分配初始化。
12)parse_early_param() 獲取命令行early最先執行部分的參數。
13) vfs_caches_init_early() vfs cache子系統初始化
14)mm_init() 內存管理初始化
15)sched_init() 調度管理初始化
16)rcu_init() 初始化直接讀拷貝更新的鎖機制
17)init_IRQ 中斷初始化
18)timer初始化,高精度time初始化
19)軟中斷初始化
20)local_irq_enable 開中斷
21)console_init 初始化控制檯,初始化以後之後prink就能夠輸出了,以前是輸出到緩衝裏面。
22)頁表cache初始化
23)thread cache初始化
24)IPC初始化
25)異步信號初始化
26)還有一些其餘多CPU相關的初始化。
27)rest_init 建立1號進程。
2、rest_init
1) kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); 建立1號進程init
2)建立kthreadd線程,它是內核線程之父,管理調度其它的內核線程,內核線程列表由kthread_create_list全局鏈表管理。
3) 建立idle線程消耗空CPU時間。
接下來,就是第三部分的kernel_init運行,即1號進程。