aarch64系統(tǒng)級(jí)體系架構(gòu)之異常級(jí)別
掃描二維碼
隨時(shí)隨地手機(jī)看文章
aarch64系統(tǒng)級(jí)體系架構(gòu)之異常級(jí)別
-
1.簡(jiǎn)述
-
2.樹莓派啟動(dòng)深度解析
-
3.不同異常級(jí)別需要注意的問題
1.簡(jiǎn)述
系統(tǒng)的異常級(jí)別對(duì)于arm芯片來說非常的重要,對(duì)于操作系統(tǒng)層面上來說,理解芯片的體系架構(gòu),將很容易的進(jìn)入狀態(tài),隨心所欲的去玩轉(zhuǎn)芯片,對(duì)于做應(yīng)用來說,熟悉芯片的體系架構(gòu),可以解決非常棘手的問題,比如系統(tǒng)的安全還有就是實(shí)時(shí)性響應(yīng)問題。比如我們的手機(jī)指紋加密數(shù)據(jù),實(shí)際上是在安全模式下的,此時(shí)對(duì)于運(yùn)行在非安全模式下的操作系統(tǒng),其實(shí)是獲取不到指紋的數(shù)據(jù)的,只是處理安全模式下發(fā)送過來的結(jié)果,類似的還有支付安全。
對(duì)于armv8異常級(jí)別,其實(shí)是一個(gè)很大的話題,但是深入理解之后,就會(huì)發(fā)現(xiàn)這時(shí)一個(gè)很有意思的東西??催^盜夢(mèng)空間的電影都知道,夢(mèng)有好多層,但是那一層是真實(shí)的,那一層是夢(mèng)境,真實(shí)到夢(mèng)境如何切換,夢(mèng)境到真實(shí)如何切換,這真的是不識(shí)廬山真面目,只緣生在此山中。
本文簡(jiǎn)單介紹一下樹莓派啟動(dòng)的異常級(jí)別,如何從不同的exception level進(jìn)行切換,同時(shí)啟動(dòng)的時(shí)候如何指定exception level,大體上去理解異常級(jí)別。
2.樹莓派啟動(dòng)深度解析
樹莓派的啟動(dòng)流程,我想簡(jiǎn)單敘述一下,就是上電之后,啟動(dòng)了GPU,然后通過GPU去啟動(dòng)arm的核,然后就是讀取配置文件,設(shè)置ddr等等。如果sd卡里有kernel8.img文件,那這個(gè)就是Linux內(nèi)核執(zhí)行的程序。此時(shí),Linux就執(zhí)行起來了。
對(duì)于rt-thread來說,情況是一樣的,可以在config.txt里寫下如此的文件
kernel=kernel8.img kernel_addr=0x80000 enable_uart=1
這就告訴樹莓派,需要啟動(dòng)的固件名字是kernel8.img,入口地址0x80000。
其實(shí)這并不是芯片上電后執(zhí)行的第一個(gè)程序,還運(yùn)行了一個(gè)叫start.elf的文件,該文件會(huì)加載kernel8.img。通過測(cè)試得知,樹莓派其實(shí)在kernel8.img的入口的第一條指令是在el2下的。關(guān)于el3,el2,el1,el0可以看下面的圖進(jìn)行理解。
應(yīng)用程序運(yùn)行在EL0上,此時(shí)可以訪問的寄存器很有限,比如我們安卓手機(jī)安裝的app,其實(shí)都是運(yùn)行在EL0的。而EL1是運(yùn)行Kernel的,比如Linux的或者是rt-thread。
到了EL2就是提供了虛擬化的實(shí)現(xiàn),這一層涉及到虛擬化,在服務(wù)器上用的比較多。
然后就是EL3,這個(gè)比較厲害,權(quán)限比較大,基本上可以訪問所有寄存器,而且電源管理,也在里面。另外這個(gè)就類似于一個(gè)電梯,打通了安全與非安全的通道。
樹莓派啟動(dòng)內(nèi)核在EL2里面,那么我們知道操作系統(tǒng)運(yùn)行在EL1的非安全模式下,安全模式是對(duì)于安全應(yīng)用場(chǎng)景的,這里不做考慮,但是如果要訪問GIC的組,一般是在安全模式。
目的就是從EL2->EL1。
// enable AArch64 in EL1 mov x0, #(1 << 31) // AArch64 orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 msr hcr_el2, x0 mrs x0, hcr_el2 // change execution level to EL1 mov x2, #0x3c4 msr spsr_el2, x2 // 1111000100 adr x2, .L__in_el1 msr elr_el2, x2 eret // exception return. from EL2. continue from .L__in_el1
主要就是使能el1在64位模式下運(yùn)行,然后配置系統(tǒng)從EL2->>EL1,采用的是eret指令,該指令會(huì)將pc指針指向elr_el2對(duì)應(yīng)的地址。
如果我們想要樹莓派在el3上運(yùn)行,可以采用MVC指令進(jìn)行模式切換。
svc,hvc,smc指令切換,對(duì)EL1~3有三種不同的中斷向量。
不想進(jìn)行指令切換,最簡(jiǎn)單的辦法,就是編譯一個(gè)鏈接地址為0的固件,在config.txt中寫下
armstub=kernel8.img
此時(shí),系統(tǒng)從el3運(yùn)行,并且起始地址為0。和芯片上電執(zhí)行第一條指令模式類似。
3.不同異常級(jí)別需要注意的問題
既然涉及到異常級(jí)別,那就不得不說一下使用異常級(jí)別需要注意的問題了。安全和非安全這是物理隔離的,但是異常級(jí)別卻是需要進(jìn)行切換的。比如我們從非安全到安全,是不能直接切換過去的,需要借助el3這個(gè)電梯,可以借助這個(gè)過去。
然后就是你在el1上訪問某些寄存器的時(shí)候,突然系統(tǒng)hard fault,這時(shí)就要看aarch64的芯片手冊(cè)了,看這個(gè)寄存器是在那個(gè)異常級(jí)別下可以訪問的。有些寄存器在不對(duì)應(yīng)的異常級(jí)別,讀為零,寫無效。比如GIC的某些寄存器。
異常級(jí)別對(duì)于芯片的體系架構(gòu)非常重要,做底層開發(fā),離不開體系架構(gòu)知識(shí),做上層開發(fā)理解芯片體系架構(gòu)更好,設(shè)計(jì)更加符合芯片設(shè)計(jì)的產(chǎn)品,做更加性能優(yōu)化的產(chǎn)品是非常好的。