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

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