最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

一篇分析RISC-V Linux匯編啟動(dòng)過程

2023-03-22 14:48 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

RISC-V Linux的匯編啟動(dòng)部分比較簡(jiǎn)單,不算復(fù)雜。有兩個(gè)部分比較核心:頁(yè)表創(chuàng)建和重定向。頁(yè)表創(chuàng)建是用C語(yǔ)言寫的,今天先分析匯編部分,先帶大家分析整體匯編啟動(dòng)流程,然后分析重定向。

注意:本文基于linux5.10.111內(nèi)核

匯編啟動(dòng)流程

先從整體分析匯編做的事情,有個(gè)大體框架。

路徑:arch/riscv/kernel/head.S,入口是ENTRY(_start_kernel)

ENTRY(_start_kernel)開始進(jìn)行啟動(dòng)前的一些初始化,建立頁(yè)表前的主要工作:

  • 關(guān)閉所有中斷

  • 加載全局指針gp

  • disable FPU

  • 選擇一個(gè)核啟動(dòng)

  • 清楚bss段

  • 保存hart id和dtb地址

  • 設(shè)置sp指針

  • 上述工作完成,會(huì)開始臨時(shí)頁(yè)表的創(chuàng)建,跳轉(zhuǎn)到C函數(shù)setup_vm建立臨時(shí)頁(yè)表

  • 重定向

  • 設(shè)置異常向量地址,重載C環(huán)境

  • 最后跳轉(zhuǎn)到C函數(shù)start_kernel,開始C語(yǔ)言部分初始化,匯編部分執(zhí)行完畢

  • 完整_start_kernel匯編代碼:

匯編中非常重要的一個(gè)部分就是頁(yè)表的創(chuàng)建,關(guān)乎著后面的程序能不能繼續(xù)往下跑。setup_vm創(chuàng)建頁(yè)表后就會(huì)開始執(zhí)行relocate重定向,這個(gè)重定向主要開啟mmu,下面分析relocate的匯編。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)??

relocate

relocate重定向,就是在開啟mmu。開啟mmu的操作就是將一級(jí)頁(yè)表的地址以及權(quán)限寫到satp寄存器中,這就算開啟mmu了。

relocate有兩次開啟mmu的操作,第一次開啟mmu使用的是setup_vm()建立的trampoline_gd_dir頁(yè)表,這頁(yè)表保存的是kernel的前2M內(nèi)存。第二次開啟MMU使用的是early_pg_dir頁(yè)表,這個(gè)頁(yè)表映射了整個(gè)kernel內(nèi)存以及dtb的4M空間。

如果trampoline_pg_dir或者early_pg_dir這兩個(gè)頁(yè)表的映射沒弄好的話,開啟MMU的時(shí)候就會(huì)失敗,所以頁(yè)表的建立十分關(guān)鍵。頁(yè)表創(chuàng)建后續(xù)再深究,下面分析relocate匯編代碼。

  • 計(jì)算返回地址

    返回地址就是ra加上虛擬地址和物理地址之間的偏移量,這個(gè)是固定偏移量。PAGE_OFFSETkernel入口地址對(duì)應(yīng)的虛擬地址,_start就是kernel入口地址的虛擬地址,PAGE_OFFSET?-?_start就得到它們之間的偏移,然后再和ra相加,就是返回地址。

將異常入口1f的虛擬地址寫入stvec寄存器

因?yàn)橐坏╅_啟MMU,地址都變成了虛擬地址,原來(lái)訪問的都是物理地址,開啟MMU時(shí),地址發(fā)生了改變,VA != PA,從而進(jìn)入異常,所以要先設(shè)置異常入口地址,此時(shí)的異常入口為1f。

  • 提前計(jì)算切換到early_pg_dir頁(yè)表要寫入satp的值

再進(jìn)入relocate之前,就已經(jīng)把early_pg_dir賦值給a0了,所以a0是early_pg_dir。srl是邏輯右移,mmu使用的是sv39,虛擬地址39位,物理地址56位:

低12位是偏移量,所以PAGE_SHIFT等于12,將early_pg_dir地址右移12位存到a2。根據(jù)satp寄存器定義:

MODE等于0x8代表使用sv39 mmu,0x0代表不進(jìn)行地址翻譯,即不開啟MMU。這里STAP_MODEsv39,即0x8。將early_pg_dir地址和SATP_MODE進(jìn)行或運(yùn)算后,即可得到寫入satp寄存器的值,最后保存到a2。

  • 第一次開啟MMU,使用trampoline_pg_dir頁(yè)表

satp值的計(jì)算和上述是一樣的。開啟MMU之前,通過sfence.vma命令先刷新TLB。此時(shí)開啟MMU,就會(huì)進(jìn)入下面的標(biāo)號(hào)為1的匯編段

進(jìn)入異常1f段,重新設(shè)置異常入口為.Lsecondary_park,然后切換到early_pg_dir頁(yè)表,相當(dāng)于第二次開啟MMU。此時(shí),如果之前建立的early_pg_dir頁(yè)表不對(duì),則會(huì)就進(jìn)入.Lsecondary_park.Lsecondary_park里面是個(gè)wfi指令,是個(gè)死循環(huán)。

完整relocate匯編代碼:

總結(jié)

以上就是RISC-V Linux的匯編啟動(dòng)流程,雖說RISC-V的指令不復(fù)雜,但要理解這個(gè)匯編啟動(dòng)的部分,還是需要一點(diǎn)基礎(chǔ)和時(shí)間。另外,大多數(shù)人工作中基本用不上匯編,只有真正用上了理解才會(huì)比較深。希望本文能夠幫助到有需要的人。

原文作者:嵌入式Linux充電站



一篇分析RISC-V Linux匯編啟動(dòng)過程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
龙江县| 德安县| 保康县| 成都市| 柏乡县| 绥化市| 枣强县| 桐梓县| 普兰店市| 当雄县| 靖远县| 中江县| 桂林市| 柳河县| 凌云县| 保定市| 海南省| 承德县| 榆社县| 永仁县| 襄汾县| 双城市| 衡山县| 于都县| 斗六市| 渭源县| 山西省| 集贤县| 阜阳市| 南城县| 德钦县| 旬邑县| 宜川县| 策勒县| 和硕县| 行唐县| 芮城县| 古交市| 新疆| 三门峡市| 衡水市|