匯編啟動流程
先從整體分析匯編做的事情,有個大體框架。
路徑:arch/riscv/kernel/head.S
,入口是ENTRY(_start_kernel)
從ENTRY(_start_kernel)
開始進行啟動前的一些初始化,建立頁表前的主要工作:
- 關(guān)閉所有中斷
/* 關(guān)閉所有中斷 */
csrw CSR_IE, zero
csrw CSR_IP, zero
- 加載全局指針gp
/* 加載全局指針gp */
.option push
.option norelax
la gp, __global_pointer$
.option pop
- disable FPU
/* 禁用 FPU 以檢測內(nèi)核空間中浮點的非法使用*/
li t0, SR_FS
csrc CSR_STATUS, t0
- 選擇一個核啟動
/* 選擇一個核啟動 */
la a3, hart_lottery
li a2, 1
amoadd.w a3, a2, (a3)
bnez a3, .Lsecondary_start
- 清楚bss段
/* 清除bss */
la a3, __bss_start
la a4, __bss_stop
ble a4, a3, clear_bss_done
- 保存hart id和dtb地址
/* 保存hatr id和dtb地址,hart id保存到a0,dtb地址保存到a1 */
mv s0, a0
mv s1, a1
la a2, boot_cpu_hartid
- 設(shè)置sp指針
la sp, init_thread_union + THREAD_SIZE
- 上述工作完成,會開始臨時頁表的創(chuàng)建,跳轉(zhuǎn)到C函數(shù)setup_vm建立臨時頁表
mv a0, s1
call setup_vm // 跳轉(zhuǎn)到C函數(shù)setup_vm,setup_vm會創(chuàng)建臨時頁表
- 重定向
#ifdef CONFIG_MMU
la a0, early_pg_dir
call relocate //重定向,實際就是開啟MMU
#endif
- 設(shè)置異常向量地址,重載C環(huán)境
call setup_trap_vector
/* 重載C環(huán)境 */
la tp, init_task
sw zero, TASK_TI_CPU(tp)
la sp, init_thread_union + THREAD_SIZE
- 最后跳轉(zhuǎn)到C函數(shù)start_kernel,開始C語言部分初始化,匯編部分執(zhí)行完畢
tail start_kernel
完整_start_kernel匯編代碼:
ENTRY(_start_kernel)
/* 關(guān)閉所有中斷 */
csrw CSR_IE, zero
csrw CSR_IP, zero
/* 在源碼中,這里有一個M模式處理的宏,這里沒有用到,直接跳過*/
/* 加載全局指針gp */
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* 禁用 FPU 以檢測內(nèi)核空間中浮點的非法使用*/
li t0, SR_FS
csrc CSR_STATUS, t0
#ifdef CONFIG_SMP
li t0, CONFIG_NR_CPUS
blt a0, t0, .Lgood_cores
tail .Lsecondary_park
.Lgood_cores:
#endif
/* 選擇一個核啟動 */
la a3, hart_lottery
li a2, 1
amoadd.w a3, a2, (a3)
bnez a3, .Lsecondary_start
/* 清除bss */
la a3, __bss_start
la a4, __bss_stop
ble a4, a3, clear_bss_done
clear_bss:
REG_S zero, (a3)
add a3, a3, RISCV_SZPTR
blt a3, a4, clear_bss
clear_bss_done:
/* 保存hatr id和dtb地址,hart id保存到a0,dtb地址保存到a1 */
mv s0, a0
mv s1, a1
la a2, boot_cpu_hartid
REG_S a0, (a2)
/* 初始化頁表,然后重定向到虛擬地址 */
la sp, init_thread_union + THREAD_SIZE
mv a0, s1
call setup_vm // 跳轉(zhuǎn)到C函數(shù)setup_vm,setup_vm會創(chuàng)建臨時頁表
#ifdef CONFIG_MMU
la a0, early_pg_dir
call relocate //重定向,實際就是開啟MMU
#endif /* CONFIG_MMU */
call setup_trap_vector
/* 重載C環(huán)境 */
la tp, init_task
sw zero, TASK_TI_CPU(tp)
la sp, init_thread_union + THREAD_SIZE
#ifdef CONFIG_KASAN
call kasan_early_init
#endif
/* Start the kernel */
call soc_early_init
tail start_kernel //跳轉(zhuǎn)到C函數(shù)start_kernel,開始C語言部分初始化
匯編中非常重要的一個部分就是頁表的創(chuàng)建,關(guān)乎著后面的程序能不能繼續(xù)往下跑。setup_vm創(chuàng)建頁表后就會開始執(zhí)行relocate重定向,這個重定向主要開啟mmu,下面分析relocate的匯編。
-
Linux
+關(guān)注
關(guān)注
87文章
11420瀏覽量
212319 -
指針
+關(guān)注
關(guān)注
1文章
484瀏覽量
70905 -
匯編
+關(guān)注
關(guān)注
2文章
214瀏覽量
26343
發(fā)布評論請先 登錄
相關(guān)推薦
Linux的啟動流程是怎樣的
詳細分析嵌入式Linux系統(tǒng)啟動流程
Linux文件系統(tǒng)啟動流程
linux內(nèi)核啟動流程

詳解bootloader的執(zhí)行流程與ARM Linux啟動過程分析

嵌入式 Linux 啟動流程和 bootloader 介紹

嵌入式Linux專題(一)——嵌入式Linux系統(tǒng)構(gòu)成及啟動流程

Linux內(nèi)核啟動流程(上)

Linux啟動流程中console_init分析

評論