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

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

超詳細(xì)的ARM處理器異常處理(含視頻教學(xué)~)

2022-06-17 20:28 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

1.1 ? ARM處理器異常處理

  • 所謂異常就是正常的用戶程序被暫時(shí)中止,處理器就進(jìn)入異常模式,例如響應(yīng)一個來自外設(shè)的中斷,或者當(dāng)前程序非法訪問內(nèi)存地址都會進(jìn)入相應(yīng)異常模式。

1.1.1 ? 異常分類

(1)復(fù)位異常

  • 當(dāng)CPU剛上電時(shí)或按下reset重啟鍵之后進(jìn)入該異常,該異常在管理模式下處理。

(2)一般/快速中斷請求

  • CPU和外部設(shè)備是分別獨(dú)立的硬件執(zhí)行單元,CPU對全部設(shè)備進(jìn)行管理和資源調(diào)度處理,CPU要想知道外部設(shè)備的運(yùn)行狀態(tài),要么CPU定時(shí)的去查看外部設(shè)備特定寄存器,要么讓外部設(shè)備在出現(xiàn)需要CPU干涉處理時(shí)“打斷”CPU,讓它來處理外部設(shè)備的請求,毫無疑問第二種方式更合理,可以讓CPU“專心”去工作,這里的“打斷”操作就叫做中斷請求,根據(jù)請求的緊急情況,中斷請求分一般中斷和快速中斷,快速中斷具有最高中斷優(yōu)先級和最小的中斷延遲,通常用于處理高速數(shù)據(jù)傳輸及通道的中數(shù)據(jù)恢復(fù)處理,如DMA等,絕大部分外設(shè)使用一般中斷請求。

(3)預(yù)取指令中止異常

  • 該異常發(fā)生在CPU流水線取指階段,如果目標(biāo)指令地址是非法地址進(jìn)入該異常,該異常在中止異常模式下處理。

(4)未定義指令異常

  • 該異常發(fā)生在流水線技術(shù)里的譯碼階段,如果當(dāng)前指令不能被識別為有效指令,產(chǎn)生未定義指令異常,該異常在未定義異常模式下處理。

(5)軟件中斷指令(swi)異常

  • 該異常是應(yīng)用程序自己調(diào)用時(shí)產(chǎn)生的,用于用戶程序申請?jiān)L問硬件資源時(shí),例如:printf()打印函數(shù),要將用戶數(shù)據(jù)打印到顯示器上,用戶程序要想實(shí)現(xiàn)打印必須申請使用顯示器,而用戶程序又沒有外設(shè)硬件的使用權(quán),只能通過使用軟件中斷指令切換到內(nèi)核態(tài),通過操作系統(tǒng)內(nèi)核代碼來訪問外設(shè)硬件,內(nèi)核態(tài)是工作在特權(quán)模式下,操作系統(tǒng)在特權(quán)模式下完成將用戶數(shù)據(jù)打印到顯示器上。這樣做的目的無非是為了保護(hù)操作系統(tǒng)的安全和硬件資源的合理使用,該異常在管理模式下處理。

(6)數(shù)據(jù)中止訪問異常

  • 該異常發(fā)生在要訪問數(shù)據(jù)地址不存在或者為非法地址時(shí),該異常在中止異常模式下處理。

1.1.2 ? 異常發(fā)生的硬件操作

  • 在異常發(fā)生后,ARM內(nèi)核會自動做以下工作:

  1. 保存執(zhí)行狀態(tài):將CPSR復(fù)制到發(fā)生的異常模式下SPSR中;

  2. 模式切換:將CPSR模式位強(qiáng)制設(shè)置為與異常類型相對應(yīng)的值,同時(shí)處理器進(jìn)入到ARM執(zhí)行模式,禁止所有IRQ中斷,當(dāng)進(jìn)入FIQ快速中斷模式時(shí)禁止FIQ中斷;

  3. 保存返回地址:將下一條指令的地址(被打斷程序)保存在LR(異常模式下LR_excep)中。

  4. 跳入異常向量表:強(qiáng)制設(shè)置PC的值為相應(yīng)異常向量地址,跳轉(zhuǎn)到異常處理程序中。

(1)保存執(zhí)行狀態(tài)

  • 當(dāng)前程序的執(zhí)行狀態(tài)是保存在CPSR里面的,異常發(fā)生時(shí),要保存當(dāng)前的CPSR里的執(zhí)行狀態(tài)到異常模式里的SPSR里,將來異常返回時(shí),恢復(fù)回CPSR,恢復(fù)執(zhí)行狀態(tài)。

(2)模式切換

  • 硬件自動根據(jù)當(dāng)前的異常類型,將異常碼寫入CPSR里的M[4:0]模式位,這樣CPU就進(jìn)入了對應(yīng)異常模式下。不管是在ARM狀態(tài)下還是在THUMB狀態(tài)下發(fā)生異常,都會自動切換到ARM狀態(tài)下進(jìn)行異常的處理,這是由硬件自動完成的,將CPSR[5] 設(shè)置為 0。同時(shí),CPU會關(guān)閉中斷IRQ(設(shè)置CPSR 寄存器I位),防止中斷進(jìn)入,如果當(dāng)前是快速中斷FIQ異常,關(guān)閉快速中斷(設(shè)置CPSR寄存器F位)。

(3)保存返回地址

  • 當(dāng)前程序被異常打斷,切換到異常處理程序里,異常處理完之后,返回當(dāng)前被打斷模式繼續(xù)執(zhí)行,因此必須要保存當(dāng)前執(zhí)行指令的下一條指令的地址到LR_excep(異常模式下LR,并不存在LR_excep寄存器,為方便讀者理解加上_excep,以下道理相同),由于異常模式不同以及ARM內(nèi)核采用流水線技術(shù),異常處理程序里要根據(jù)異常模式計(jì)算返回地址。

(4)跳入異常向量表

  • 該操作是CPU硬件自動完成的,當(dāng)異常發(fā)生時(shí),CPU強(qiáng)制將PC的值修改為一個固定內(nèi)存地址,這個固定地址叫做異常向量(詳見3.2.4章節(jié))。

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


1.1.3 ? 異常返回地址

  • 由1.1.3節(jié)可知,一條指令的執(zhí)行分為:取指,譯碼,執(zhí)行三個主要階段, CPU由于使用流水線技術(shù),造成當(dāng)前執(zhí)行指令的地址應(yīng)該是PC – 8(32位機(jī)一條指令四個字節(jié)),那么執(zhí)行指令的下條指令應(yīng)該是PC – 4。在異常發(fā)生時(shí),CPU自動會將將PC – 4 的值保存到LR里,但是該值是否正確還要看異常類型才能決定。

  • 各模式的返回地址說明如下:

(a)一般/快速中斷請求:

  • 快速中斷請求和一般中斷請求返回處理是一樣的。通常處理器執(zhí)行完當(dāng)前指令后,查詢FIQ/IRQ中斷引腳,并查看是否允許FIQ/IRQ中斷,如果某個中斷引腳有效,并且系統(tǒng)允許該中斷產(chǎn)生,處理器將產(chǎn)生FIQ/IRQ異常中斷,當(dāng)FIQ/IRQ異常中斷產(chǎn)生時(shí),程序計(jì)數(shù)器pc的值已經(jīng)更新,它指向當(dāng)前指令后面第3條指令(對于ARM指令,它指向當(dāng)前指令地址加12字節(jié)的位置;對于Thumb指令,它指向當(dāng)前指令地址加6字節(jié)的位置),當(dāng)FIQ/IRQ異常中斷產(chǎn)生時(shí),處理器將值(pc-4)保存到FIQ/IRQ異常模式下的寄存器lr_irq/lr_irq中,它指向當(dāng)前指令之后的第2條指令,因此正確返回地址可以通過下面指令算出:

(b)預(yù)取指中止異常:

  • 在指令預(yù)取時(shí),如果目標(biāo)地址是非法的,該指令被標(biāo)記成有問題的指令,這時(shí),流水線上該指令之前的指令繼續(xù)執(zhí)行,當(dāng)執(zhí)行到該被標(biāo)記成有問題的指令時(shí),處理器產(chǎn)生指令預(yù)取中止異常中斷。發(fā)生指令預(yù)取異常中斷時(shí),程序要返回到該有問題的指令處,重新讀取并執(zhí)行該指令,因此指令預(yù)取中止異常中斷應(yīng)該返回到產(chǎn)生該指令預(yù)取中止異常中斷的指令處,而不是當(dāng)前指令的下一條指令。

  • 指令預(yù)取中止異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)指令預(yù)取中止異常中斷發(fā)生時(shí),程序計(jì)數(shù)器pc的值還未更新,它指向當(dāng)前指令后面第2條指令(對于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置)。此時(shí)處理器將值(pc-4)保存到lr_abt中,它指向當(dāng)前指令的下一條指令,所以返回操作可以通過下面指令實(shí)現(xiàn):

c)未定義指令異常:

  • 未定義指令異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)未定義指令異常中斷產(chǎn)生時(shí),程序計(jì)數(shù)器pc的值還未更新,它指向當(dāng)前指令后面第2條指令(對于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置),當(dāng)未定義指令異常中斷發(fā)生時(shí),處理器將值(pc-4)保存到lr_und中,此時(shí)(pc-4)指向當(dāng)前指令的下一條指令,所以從未定義指令異常中斷返回可以通過如下指令來實(shí)現(xiàn):

(d)軟中斷指令(SWI)異常:

  • SWI異常中斷和未定義異常中斷指令一樣,也是由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)SWI指令執(zhí)行時(shí),pc的值還未更新,它指向當(dāng)前指令后面第2條指令(對于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置),當(dāng)未定義指令異常中斷發(fā)生時(shí),處理器將值(pc-4)保存到lr_svc中,此時(shí)(pc-4)指向當(dāng)前指令的下一條指令,所以從SWI異常中斷處理返回的實(shí)現(xiàn)方法與從未定義指令異常中斷處理返回一樣:

(e)數(shù)據(jù)中止異常:

  • 發(fā)生數(shù)據(jù)訪問異常中斷時(shí),程序要返回到該有問題的指令處,重新訪問該數(shù)據(jù),因此數(shù)據(jù)訪問異常中斷應(yīng)該返回到產(chǎn)生該數(shù)據(jù)訪問中止異常中斷的指令處,而不是當(dāng)前指令的下一條指令。

  • 數(shù)據(jù)訪問異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)數(shù)據(jù)訪問異常中斷發(fā)生時(shí),程序計(jì)數(shù)器pc的值已經(jīng)更新,它指向當(dāng)前指令后面第3條指令(對于ARM指令,它指向當(dāng)前指令地址加12字節(jié)的位置;對于Thumb指令,它指向當(dāng)前指令地址加6字節(jié)的位置)。此時(shí)處理器將值(pc-4)保存到lr_abt中,它指向當(dāng)前指令后面第2條指令,所以返回操作可以通過下面指令實(shí)現(xiàn):

  • 上述每一種異常發(fā)生時(shí),其返回地址都要根據(jù)具體異常類型進(jìn)行重新修復(fù)返回地址,再次強(qiáng)調(diào)下,被打斷程序的返回地址保存在對應(yīng)異常模式下的LR_excep里。

1.1.4 ? 異常向量表

  • 異常向量表是一段特定內(nèi)存地址空間,每種ARM異常對應(yīng)一個字長空間(4Bytes),正好是一條32位指令長度,當(dāng)異常發(fā)生時(shí),CPU強(qiáng)制將PC的值設(shè)置為當(dāng)前異常對應(yīng)的固定內(nèi)存地址。如表3-4所示是S3C2440的異常向量表。


注:

  • 異常向量也可以出現(xiàn)在高地址0xFFFF0000處,當(dāng)今操作系統(tǒng)為了控制內(nèi)存訪問權(quán)限,通常會開啟虛擬內(nèi)存,開啟了虛擬內(nèi)存之后,內(nèi)存的開始空間通常為內(nèi)核進(jìn)程空間,和頁表空間,異常向量表不能再安裝在0地址處了

  • ARM的例外優(yōu)先級從高到低依次為Reset→Data abort→FIQ→IRQ→Prefetch abort→Undefined instruction/SWI。

  • 跳入異常向量表操作是異常發(fā)生時(shí),硬件自動完成的,剩下的異常處理任務(wù)完全交給了程序員。由上表可知,異常向量是一個固定的內(nèi)存地址,我們可以通過向該地址處寫一條跳轉(zhuǎn)指令,讓它跳向我們自己定義的異常處理程序的入口,就可以完成異常處理了。

  • 正是由于異常向量表的存在,才讓硬件異常處理和程序員自定義處理程序有機(jī)聯(lián)系起來。異常向量表里0x00000000地址處是reset復(fù)位異常,之所以它為0地址,是因?yàn)镃PU在上電時(shí)自動從0地址處加載指令,由此可見將復(fù)位異常安裝在此地址處也是前后接合起來設(shè)計(jì)的,不得不感嘆CPU設(shè)計(jì)師的偉大,其后面分別是其余7種異常向量,每種異常向量都占有四個字節(jié),正好是一條指令的大小,最后一個異常是快速中斷異常,將其安裝在此也有它的意義,在0x0000001C地址處可以直接存放快速中斷的處理程序,不用設(shè)置跳轉(zhuǎn)指令,這樣可以節(jié)省一個時(shí)鐘周期,加快快速中斷處理時(shí)間。

  • 我們可以通過簡單的使用下面的指令來安裝異常向量表:

  • 通常安裝完異常向量表,跳到我們自己定義的處理程序入口,這時(shí)我們還沒有保存被打斷程序的現(xiàn)場,因此在異常處理程序的入口里先要保存打斷程序現(xiàn)場。

  • 保存執(zhí)行現(xiàn)場:

  • 異常處理程序最開始,要保存被打斷程序的執(zhí)行現(xiàn)場,程序的執(zhí)行現(xiàn)場無非就是保存當(dāng)前操作寄存器里的數(shù)據(jù),可以通過下面的棧操作指令實(shí)現(xiàn)保存現(xiàn)場:

  • 需要注意的是,在跳轉(zhuǎn)到異常處理程序入口時(shí),已經(jīng)切換到對應(yīng)異常模式下了,因此這里的SP是異常模式下的SP_excep了,所以被打斷程序現(xiàn)場(寄存器數(shù)據(jù))是保存在異常模式下的棧里,上述指令將R0~R12全部都保存到了異常模式棧,最后將修改完的被打斷程序返回地址入棧保存,之所以保存該返回地址就是將來可以通過類似:MOV ?PC, ?LR的指令,返回用戶程序繼續(xù)執(zhí)行。

  • 異常發(fā)生后,要針對異常類型進(jìn)行處理,因此,每種異常都有自己的異常處理程序,異常處理過程通過下節(jié)的系統(tǒng)中斷處理來進(jìn)行分析。

1.1.5 ? 異常處理的返回

  • 異常處理完成之后,返回被打斷程序繼續(xù)執(zhí)行,具體操作如下:

  1. 恢復(fù)被打斷程序運(yùn)行時(shí)寄存器數(shù)據(jù)

  2. 恢復(fù)程序運(yùn)行時(shí)狀態(tài)CPSR

  3. 通過進(jìn)入異常時(shí)保存的返回地址,返回到被打斷程序繼續(xù)執(zhí)行

  • 異常發(fā)生后,進(jìn)入異常處理程序時(shí),將用戶程序寄存器R0~R12里的數(shù)據(jù)保存在了異常模式下棧里面,異常處理完返回時(shí),要將棧里保存的的數(shù)據(jù)再恢復(fù)回原先R0~R12里,毫無疑問在異常處理過程中必須要保證異常處理入口和出口時(shí)棧指針SP_excep要一樣,否則恢復(fù)到R0~R12里的數(shù)據(jù)不正確,返回被打斷程序時(shí)執(zhí)行現(xiàn)場不一致,出現(xiàn)問題,雖然將執(zhí)行現(xiàn)場恢復(fù)了,但是此時(shí)還是在異常模式下,CPSR里的狀態(tài)是異常模式下狀態(tài),因此要恢復(fù)SPSR_excep里的保存狀態(tài)到CPSR里,SPSR_excep是被打斷程序執(zhí)行時(shí)的狀態(tài),在恢復(fù)SPSR_excep到CPSR的同時(shí),CPU的模式和狀態(tài)從異常模式切換回了被打斷程序執(zhí)行時(shí)的模式和狀態(tài)。此刻程序現(xiàn)場恢復(fù)了,狀態(tài)也恢復(fù)了,但PC里的值仍然指向異常模式下的地址空間,我們要讓CPU繼續(xù)執(zhí)行被打斷程序,因此要再手動改變PC的值為進(jìn)入異常時(shí)的返回地址,該地址在異常處理入口時(shí)已經(jīng)計(jì)算好,直接將PC = LR_excep即可。

  • 上述操作可以一步一步實(shí)現(xiàn),但是通常我們可以通過一條指令實(shí)現(xiàn)上述全部操作:

  • 以上操作可以用下圖來描述:




超詳細(xì)的ARM處理器異常處理(含視頻教學(xué)~)的評論 (共 條)

分享到微博請遵守國家法律
依安县| 自治县| 延川县| 荥阳市| 罗平县| 龙海市| 垫江县| 桑日县| 山东省| 江达县| 泰兴市| 湖州市| 新河县| 永城市| 上栗县| 多伦县| 望都县| 和龙市| 澄城县| 平昌县| 六安市| 壤塘县| 舟曲县| 泰和县| 资阳市| 仙居县| 遂溪县| 宜君县| 仙居县| 九龙坡区| 潜山县| 新化县| 阿克苏市| 柯坪县| 柳河县| 沁源县| 清远市| 勐海县| 溧水县| 侯马市| 西充县|