匯編啟動流程
先從整體分析匯編做的事情,有個大體框架。
路徑:arch/riscv/kernel/head.S,入口是ENTRY(_start_kernel)

從ENTRY(_start_kernel)開始進行啟動前的一些初始化,建立頁表前的主要工作:
- 關閉所有中斷
/* 關閉所有中斷 */
csrw CSR_IE, zero
csrw CSR_IP, zero
- 加載全局指針gp
/* 加載全局指針gp */
.option push
.option norelax
la gp, __global_pointer$
.option pop
- disable FPU
/* 禁用 FPU 以檢測內核空間中浮點的非法使用*/
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
- 設置sp指針
la sp, init_thread_union + THREAD_SIZE
- 上述工作完成,會開始臨時頁表的創(chuàng)建,跳轉到C函數(shù)setup_vm建立臨時頁表
mv a0, s1
call setup_vm // 跳轉到C函數(shù)setup_vm,setup_vm會創(chuàng)建臨時頁表
- 重定向
#ifdef CONFIG_MMU
la a0, early_pg_dir
call relocate //重定向,實際就是開啟MMU
#endif
- 設置異常向量地址,重載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
- 最后跳轉到C函數(shù)start_kernel,開始C語言部分初始化,匯編部分執(zhí)行完畢
tail start_kernel
完整_start_kernel匯編代碼:
ENTRY(_start_kernel)
/* 關閉所有中斷 */
csrw CSR_IE, zero
csrw CSR_IP, zero
/* 在源碼中,這里有一個M模式處理的宏,這里沒有用到,直接跳過*/
/* 加載全局指針gp */
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* 禁用 FPU 以檢測內核空間中浮點的非法使用*/
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 // 跳轉到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 //跳轉到C函數(shù)start_kernel,開始C語言部分初始化
匯編中非常重要的一個部分就是頁表的創(chuàng)建,關乎著后面的程序能不能繼續(xù)往下跑。setup_vm創(chuàng)建頁表后就會開始執(zhí)行relocate重定向,這個重定向主要開啟mmu,下面分析relocate的匯編。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
Linux
+關注
關注
88文章
11628瀏覽量
217980 -
指針
+關注
關注
1文章
484瀏覽量
71676 -
匯編
+關注
關注
2文章
214瀏覽量
27154
發(fā)布評論請先 登錄
相關推薦
熱點推薦
詳細分析嵌入式Linux系統(tǒng)啟動流程
在嵌入式Linux專題(一)中已經對嵌入式Linux系統(tǒng)的架構及啟動流程有了初步的介紹,本文將詳細分析嵌入式
發(fā)表于 11-05 09:25
Linux文件系統(tǒng)啟動流程
與 Linux 命令的結合使用Linux 文件系統(tǒng)啟動流程sysvinit服務的管理與裁剪systemd服務的管理與裁剪了解 qt4、qt5 的移植了解 yocto構建文件系統(tǒng)常規(guī)
發(fā)表于 12-17 06:00
linux內核啟動流程
Linux的啟動代碼真的挺大,從匯編到C,從Makefile到LDS文件,需要理解的東西很多。畢竟Linux內核是由很多人,花費了巨大的時間和精力寫出來的。而且直到現(xiàn)在,這個世界上仍然
發(fā)表于 11-14 16:19
?4605次閱讀
詳解bootloader的執(zhí)行流程與ARM Linux啟動過程分析
S3C2410 ARM處理器為例,詳細分析了系統(tǒng)上電后 bootloader的執(zhí)行流程及 ARM Linux的啟動過程。
嵌入式 Linux 啟動流程和 bootloader 介紹
目錄嵌入式 Linux 啟動流程簡介啟動流程Bootloader 簡介市面上可見的 bootloader入式
發(fā)表于 11-01 16:32
?11次下載
嵌入式Linux專題(一)——嵌入式Linux系統(tǒng)構成及啟動流程
本文簡單的介紹了什么是嵌入式系統(tǒng),以及嵌入式Linux的系統(tǒng)結構,并且簡單的介紹了Linux的啟動流程
發(fā)表于 11-02 12:36
?15次下載
Linux內核啟動流程(上)
本文先講解上篇,大家看到匯編不用擔心看不懂,在內核啟動階段,沒有特別復雜的流程,都是順序執(zhí)行,只需一句一句閱讀代碼即可。
發(fā)表于 06-23 14:07
?2438次閱讀
Linux啟動流程中console_init分析
console_init 分析 Linux 啟動函數(shù) start_kernel 會調用 console_init 函數(shù)。 linux4.14/kernel/printk/printk.

Linux整體匯編啟動流程分析
評論