u-boot一旦引導到內核,操做權限就會交給內核,那麼全部的事情就和u-boot沒有關係了,除了u-boot傳遞給內核的參數。
基地址+100 u-boot給內核的參數
基地址+4000 映射列表
基地址+8000 內核函數
內核的執行流程:
整個內核的入口:根據lds文件和編譯到內核的源碼文件共同決定。
arch/arm/kernel/head.s
safe_svcmode_maskall r9 確保處在SVC模式
mrc p15, 0, r9, c0, c0 讀取cpu id cpu id在協處理器內部
bl __lookup_processor_type 判斷內核是否支持本cpuoop
arch/arm/kernel/head-common.S
__lookup_processor_type:
adr r3, __lookup_processor_type_data 基於pc
154 ldmia r3, {r4 - r6}
155 sub r3, r3, r4 @ get offset between virt&phys 判斷實際運行地址和規劃地址的差值,爲了找cpuid在內存上
156 add r5, r5, r3 @ convert virt addresses to
157 add r6, r6, r3 @ physical address space
1: ldmia r5, {r3, r4} @ value, mask
159 and r4, r4, r9 @ mask wanted bits
160 teq r3, r4
161 beq 2f
162 add r5, r5, #PROC_INFO_SZ (8) @ sizeof(proc_info_list)
163 cmp r5, r6
164 blo 1b
165 mov r5, #0 @ unknown processor
166 2: mov pc, lrui
__lookup_processor_type_data
174 __lookup_processor_type_data:
175 .long . 利用一條語句,在不一樣地方(實際運行地址、鏈接規劃地址)的不一樣,來計算實際運行地址和規劃地址的差值
176 .long __proc_info_begin
177 .long __proc_info_end
178 .size __lookup_processor_type_data, . - __lookup_processor_type_data spa
bl __vet_atags 用來檢測參數。
128 bl __create_page_tables 穿件映射列表,映射列表是(虛擬地址和物理地址之間的轉換表)設計
ldr r13, =__mmap_switched 爲跳到下一個階段作準備
adr lr, BSYM(1f)
1: b __enable_mmu 打開mmu
b __turn_mmu_on
ENTRY(__turn_mmu_on)
464 mov r0, r0
465 instr_sync
466 mcr p15, 0, r0, c1, c0, 0 @ write control reg
467 mrc p15, 0, r3, c0, c0, 0 @ read id reg
468 instr_sync
469 mov r3, r3
470 mov r3, r13(=__mmap_switched )
471 mov pc, r3
pc ==__mmap_switched
472 __turn_mmu_on_end:指針
__mmap_switched :內核的第二階段調試
mov fp, #0 @ Clear BSS (and zero fp)
91 1: cmp r6, r7
92 strcc fp, [r6],#4
93 bcc 1b
94
95 ARM( ldmia r3, {r4, r5, r6, r7, sp}) 設置堆棧
473 ENDPROC(__turn_mmu_on)rest
跳轉到c語言:
stmneia r7, {r0, r4} @ Save control register values
104 b start_kernel日誌
init/main.c
start_kernel()進程
setup_arch(&command_line); 會解析u-boot傳遞的參數。
mdesc = setup_machine_fdt(__atags_pointer) 解析設備樹
mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); 檢測本內核是或否支持板子
command_line :制定根文件系統
rest_init();
382 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
if (execute_command) {判斷bootargs裏面有init=「?」,若是有則執行,若是沒有則去下面的路徑上運行
865 ret = run_init_process(execute_command);
866 if (!ret)
867 return 0;
868 pr_err("Failed to execute %s (error %d). Attempting defaults...\n",
869 execute_command, ret);
870 }
871 if (!try_to_run_init_process("/sbin/init") ||
872 !try_to_run_init_process("/etc/init") ||
873 !try_to_run_init_process("/bin/init") ||
874 !try_to_run_init_process("/bin/sh"))
init進程的調用流程:
init/main.c
start_kernel()-----》 rest_init();----》kernel_init();---》》》
if (execute_command) {判斷bootargs裏面有init=「?」,若是有則執行,若是沒有則去下面的路徑上運行
865 ret = run_init_process(execute_command);
866 if (!ret)
867 return 0;
868 pr_err("Failed to execute %s (error %d). Attempting defaults...\n",
869 execute_command, ret);
870 }
871 if (!try_to_run_init_process("/sbin/init") ||
872 !try_to_run_init_process("/etc/init") ||
873 !try_to_run_init_process("/bin/init") ||
874 !try_to_run_init_process("/bin/sh"))
printk內核打印函數:能夠分等級
內核調試:內核的錯誤有兩種
panic錯誤:內核運行到不能再運行的地方出錯,是內核設計者提早規定的一些錯誤點。現階段主要形成的緣由是,參數錯誤
oops錯誤:內核使用非法指針,會將錯誤的pc報出,能夠根據addr2line來查找錯誤點。
根文件系統:第一個被掛載的文件系統。sys(文件系統) 用來顯示全部的設備文件proc(文件系統) 又來顯示全部的內核信息tmp 基於內存的文件夾,主要用來進行記錄日誌dev 基於內存的文件夾,用來管理全部的設備節點