版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
/""中斷源碼分析(2)——中斷處理流程支持7類異常中斷,所以中斷向量表設(shè)8個條目,每個條目4字節(jié),共32字節(jié)。
異常名稱中斷向量異常中斷模式優(yōu)先級復(fù)位0x0特權(quán)模式1未定義的指令0x4未定義指令中止模式6軟件中斷0x8特權(quán)模式6指令預(yù)取中止0x0c中止模式5數(shù)據(jù)訪問中止0x10中止模式2保留0x14
外部中斷請求0x18模式4快速中斷請求0x1c模式3
回顧第一節(jié)所講的內(nèi)容,當(dāng)一個異?;蛑袛喟l(fā)生時,處理器會將設(shè)置為特定地址,從而跳轉(zhuǎn)到已經(jīng)初始化好的異常向量表。因此,要理清中斷處理流程,先從異常向量表開始。對于而言,異常向量表和異常處理程序都存在匯編文件中。異常向量表點(diǎn)擊(此處)折疊或打開
:
0
b
+
,
+
b
+
b
+
b
+
b
+
@中斷入口,
b
+
:為中斷的入口點(diǎn),此處之所以要加上,是為了實(shí)現(xiàn)位置無關(guān)編程。首先分析一下(宏)是如何計算的:
,+0x200-在第3節(jié)中已經(jīng)提到,內(nèi)核啟動時會將異常向量表拷貝到00000,將異常向量處理程序的拷貝到00200。圖5-1描述了異常向量表和異常處理程序搬移前后的內(nèi)存布局。圖5-1
異常向量表和異常處理程序搬移前后對比當(dāng)匯編器看到B指令后會把要跳轉(zhuǎn)的標(biāo)簽轉(zhuǎn)化為相對于當(dāng)前的偏移量(±32M)寫入指令碼。由于內(nèi)核啟動時中斷向量表和都發(fā)生了代碼搬移,所以如果中斷向量表中仍然寫成b,那么實(shí)際執(zhí)行的時候就無法跳轉(zhuǎn)到搬移后的處,因為指令碼里寫的是原來的偏移量,所以需要把指令碼中的偏移量寫成搬移后的。設(shè)搬移后的偏移量為,如圖5-1所示,=L12
=[0x200-(-)]+(-)
=[0x200-(-)]+(-)
=0x200-++-
=+(+0x200-)-令=+0x200-則=+-,所以中斷入口點(diǎn)為“b
+”,其中減去是由匯編器在編譯時完成的。處理函數(shù)在分析處理函數(shù)之前,先了解一下當(dāng)一個異常或中斷導(dǎo)致處理器模式改變時,處理器內(nèi)核的處理流程如下圖所示:
中斷剛發(fā)生時,處理器處于模式。在和之間找到處理函數(shù)的定義,,4,其中是一個宏(在中定義),為了分析更直觀,我們將宏展開如下:
/*
*
*/
:
4
,
,
#4
@在中斷發(fā)生時,指向最后執(zhí)行的指令地址加上8。只有在當(dāng)前指令執(zhí)行完畢后,才進(jìn)入中斷處理,所以返回地址應(yīng)指向下一條指令,即(4)處。
@
@r0,
<>
()
<>
@
()
@
,
{r0,
}
@保存r0,
到模式下的棧中
,
,
[,
#8]
@保存到模式下的棧中
@
@
32.
.
@
r0,
r0,
r0,
#(
^)
@設(shè)置成模式,但未切換
,
r0@保存到中
@
@
@
,
,
#0x0f存儲著上一個處理器模式的值,
=
&0x0f取出用于判斷發(fā)生中斷前是用戶態(tài)還是核心態(tài)的信息,該值用于下面跳轉(zhuǎn)表的索引。
r0,
@將模式下的保存到r0,作為參數(shù)傳遞給即將調(diào)用的或
,
[,
,
#2]
指向當(dāng)前執(zhí)行指令地址加8,即跳轉(zhuǎn)表的基址。作為索引,由于是4字節(jié)對齊,所以
=
<<
2.
,
@
@當(dāng)指令后加“s”且目標(biāo)寄存器為時,當(dāng)前模式下的會被復(fù)制到,從而完成模式切換(從模式切換到模式)并且跳轉(zhuǎn)到指向的指令繼續(xù)執(zhí)行()
@0
(26/32)
@1
(26/32)
@2
(26/32)
@3
(26/32)
@4
@5
@6
@7
@8
@9
@a
@b
@c
@d
@e
@f如果發(fā)生中斷前處于用戶態(tài)則進(jìn)入,其定義如下():
5
:
@保存中斷上下文,稍后分析
@獲取當(dāng)前進(jìn)程的進(jìn)程描述符中的成員變量的地址,并將該地址保存到寄存器(r9)(在中定義)@如果定義了搶占,增加搶占數(shù)值
r8,
[,
]
@獲取計數(shù)器值
r7,
r8,
#1
@加1,標(biāo)識禁止搶占
r7,
[,
]
@將加1后的結(jié)果寫入進(jìn)程內(nèi)核棧的變量中
@調(diào)用中斷處理程序,稍后分析
r0,
[,
]
@獲取計數(shù)器值
r8,
[,
]
@將恢復(fù)到中斷前的值
r0,
r7@比較中斷前后是否相等
r0,
[r0,
0]
@如果不等,則產(chǎn)生異常(向地址0寫入數(shù)據(jù))?
,
#08=0
b
@中斷處理完成,恢復(fù)中斷上下文并返回中斷產(chǎn)生的位置,稍后分析
(
)()宏定義(保護(hù)上下文到棧)上面代碼中的是一個宏定義,主要用于保護(hù)上下文到棧中:
(
)
(
)
@
,
,
中,堆棧被定義為遞減式滿堆棧,所以首先讓向下移動(結(jié)構(gòu)體),準(zhǔn)備向棧中存放數(shù)據(jù)。此處的是模式下的棧指針。
,
{r1
-
r12}
r0,
{r1
-
r3}
r0,
,
@
r4,
1
@
""
""
""
""
r1,
[]
@
""
r0
@
@
@
:
@
@r2
-
<>,
@r3
-
<>
@r4
-
0
(
)
@
@,
@
r0,
{r2
-
r4}
r0,
{,
}^@將模式下的和保存到模式的棧中
@
@
@
r0
@
@
@
上面的這段代碼主要是在填充結(jié)構(gòu)體,在中定義:
{
[18];};
[16]
[15]
[14]
[13]
[12]
[11]10
[10]9
[9]8
[8]7
[7]6
[6]5
[5]4
[4]3
[3]2
[2]1
[1]0
[0]0
[17]宏填充結(jié)構(gòu)體的過程如圖5-2所示,先將r1~r12保存到1~(綠色部分),然后將產(chǎn)生中斷時的r0寄存器內(nèi)容保存到0(藍(lán)色部分),接下來將產(chǎn)生中斷時的下一條指令地址、和r4保存到、和0(紅色部分),最后將用戶模式下的和保存到
和
中。圖5-2宏填充結(jié)構(gòu)體如果發(fā)生中斷前處于核心態(tài)則進(jìn)入,其定義如下():
5
:
@保存中斷上下文
r8,
[,
]
@獲取計數(shù)器值
r7,
r8,
#1
@加1,標(biāo)識禁止搶占
r7,
[,
]
@將加1后的結(jié)果寫入進(jìn)程內(nèi)核棧的變量中
@調(diào)用中斷處理程序,稍后分析
r8,
[,
]
@恢復(fù)中斷前的計數(shù)器
r0,
[,
]
@獲取
r8,
#0
@判斷是否等于0
r0,
#0
@如果不等于0,r0=0
r0,
@將r0與做“與操作”
@如果不等于0,說明發(fā)生內(nèi)核搶占,需要重新調(diào)度。
r0,
[,
]
@
,
r0
r0,
r4
@恢復(fù)中斷上下文,稍后分析。
(
)()宏定義(保護(hù)中斷上下文到棧)其中是一個宏定義,主要用于保護(hù)中斷上下文到棧中。主要是在當(dāng)前堆棧上分配一個結(jié)構(gòu),把r015以及等保存到這個結(jié)構(gòu)中,在進(jìn)入時,指向底端:
,
0
(
)
({r0
-
}
)
,
,
#(
+
\)
(
,
#4
)
(
,
,
#4
)
,
{r1
-
r12}
r0,
{r1
-
r3}
r5,
,
@
r4,
1
@
""
""
""
""
r0,
,
#(
+
\)
(
r0,
r0,
#4
)
r1,
[]
@
""
r0
@
r1,
@
@
:
@
@r0
-
@r1
-
@r2
-
<>,
@r3
-
<>
@r4
-
0
(
)
@
r5,
{r0
-
r4}
宏填充結(jié)構(gòu)體的過程如圖5-2所示,先將r1~r12保存到1~(綠色部分),然后將產(chǎn)生中斷時的r0寄存器內(nèi)容保存到0(藍(lán)色部分),由于是在模式下產(chǎn)生的中斷,所以最后將、、、和r4保存到、、、和0(紅色部分)。圖5-3宏填充結(jié)構(gòu)體上述的中斷上下文保存過程共涉及了3種棧指針,分別是:用戶空間棧指針,內(nèi)核空間棧指針和模式下的棧棧指針。指向在函數(shù)中創(chuàng)建的用戶空間棧。指向在函數(shù)中創(chuàng)建的內(nèi)核空間棧。在函數(shù)中被賦值,指向全局變量[0]。附錄1,體系下結(jié)構(gòu)
{
[18];
};
[0]-[17]分別對應(yīng),r0-r15,,0
附錄1,中斷時堆棧的變化
,中斷返回地址,修正后的
r0
<-進(jìn)入之前,的值,也是r0的值
<-進(jìn)入后,的值(中斷處理程序)保存中斷上下文后則進(jìn)入中斷處理程序——,定義在文件中:
r5,
1:
r0,
r6,
r5,
@獲取中斷號,存到r0中,稍后分析
r1,
@如果中斷號不等于0,將r1,即結(jié)構(gòu)體首地址
@
@r0
=
,
r1
=
*
@
,
1b@如果r0(中斷號)不等于0,(返回地址)等于標(biāo)號1處,即r0,
r6,
r5,
的那行,即循環(huán)處理所有的中斷。
@進(jìn)入中斷處理,稍后分析?!?/p>
用于判斷當(dāng)前發(fā)生的中斷號(與緊密相關(guān)),此處不再分析。如果獲取的中斷號不等于0,則將中斷號存入r0寄存器作為第一個參數(shù),結(jié)構(gòu)體地址存入r1寄存器作為第二個參數(shù),跳轉(zhuǎn)到c語言函數(shù)做進(jìn)一步處理。為了不讓大家在匯編語言和C語言之間來回切換,還是先把最后一點(diǎn)匯編語言代碼(中斷返回匯編代碼)分析了再去分析吧?;乜春蜆?biāo)號處的代碼,在完成了中斷處理函數(shù)后,要完成從中斷異常處理程序返回到中斷點(diǎn)的工作。如果中斷產(chǎn)生于用戶空間,則調(diào)用來恢復(fù)中斷現(xiàn)場并返回用戶空間繼續(xù)運(yùn)行:
():
@,此處不明白,應(yīng)該接受中斷號作為參數(shù),來禁止指定的號中斷線。但是此處調(diào)用之前并沒有將中斷號存入r0寄存器,這是為什么?
r1,
[,
]
@獲取>
r1,
@判斷是否有待處理的
@如果有,則進(jìn)入進(jìn)一步處理,主要是完成用戶進(jìn)程搶占相關(guān)處理。:
@如果沒有待處理,則準(zhǔn)備恢復(fù)中斷現(xiàn)場,返回用戶空間。
/*
*/
r1,
@調(diào)用體系結(jié)構(gòu)相關(guān)的代碼
=
0,
=
0@調(diào)用()以下是恢復(fù)中斷現(xiàn)場寄存器的宏,就是將發(fā)生中斷時保存在內(nèi)核空間堆棧上的寄存器還原,可以對照圖5-2所示的內(nèi)核空間堆棧保存的內(nèi)容來理解下面代碼:
,
=
0,
=
0
r1,
[,
#\
+
]
@從內(nèi)核棧中獲取發(fā)生中斷時的值
,
[,
#\
+
]!
@從內(nèi)核棧中獲取發(fā)生中斷時的下一條指令地址
,
r1
@將r1保存到
(32v6K)
@
(6)
r1,
r2,
[]
@
\
,
{r1
-
}^
@r1
-
,
{r0
-
}^@存在^,所以將內(nèi)核棧保存的內(nèi)容恢復(fù)到用戶空間的r0~寄存器
,
,
-
,
@將發(fā)生中斷時的下一條指令地址存入,從而返回中斷點(diǎn)繼續(xù)執(zhí)行,并且將發(fā)生中斷時的內(nèi)容恢復(fù)到寄存器中(開啟中斷)。
如果中斷產(chǎn)生于內(nèi)核空間,則調(diào)用來恢復(fù)中斷現(xiàn)場:
,
,
\
(32v6K)
@
,
{r0
-
}^
@r0
-
,
(6)
r0,
[]
r1,
r2,
[]
@
,
{r1
-
}^
@r1
-
,
,
{r0
-
}^
@返回內(nèi)核空間時,恢復(fù)中斷現(xiàn)場比較簡單,就是將r0以及恢復(fù)即可,同時中斷也被開啟。
函數(shù),分析完所有與中斷相關(guān)的匯編語言代碼后,下面開始分析C語言代碼:在文件中找到函數(shù)定義:(
,
*)
{
/*保存新的寄存器集合指針到全局變量,方便后續(xù)處理程序訪問寄存器集合。*/
*
=
();
();
/*
*
.
*
,
.
*/
((
>=
))
{判斷中斷號
(())
(
"\n",
);
();
}
{
();
調(diào)用中斷處理函數(shù)
}
/*
91
*/
();
();
();}是中斷處理的C入口函數(shù),主要負(fù)責(zé)調(diào)用注冊的中斷處理函數(shù),其流程如圖5-4所示:圖5-4流程1、
=
()其中,將指向寄存器結(jié)構(gòu)體的指針保存在一個全局的變量中,后續(xù)的程序可以通過該變量訪問寄存器結(jié)構(gòu)體。所以在進(jìn)入中斷處理前,先將全局變量中保存的舊指針保留下來,等到中斷處理結(jié)束后再將其恢復(fù)。2、負(fù)責(zé)更新一些統(tǒng)計量:<>
(){
=
();
();
(()
())
{
();
();
}
();}如果系統(tǒng)開啟動態(tài)時鐘特性且很長時間沒有產(chǎn)生時鐘中斷,則調(diào)用更新全局變量(關(guān)于動態(tài)時鐘特性,在后續(xù)的總結(jié)中再進(jìn)行分析)。宏()定義如下:()
\
{
\
();
\
();
\
();
\
}
(0)()使表示中斷處理程序嵌套層次的計數(shù)器加1。計數(shù)器保存在當(dāng)前進(jìn)程結(jié)構(gòu)的字段中:圖5-5結(jié)構(gòu)內(nèi)核將分成5部分:0~7與相關(guān),8~15用作軟中斷計數(shù)器,16~25用作硬中斷計數(shù)器,26用作不可屏蔽中斷計數(shù)器,28用作標(biāo)志。3、是體系結(jié)構(gòu)無關(guān)函數(shù),用來調(diào)用>,該函數(shù)指針在中斷初始化時指向了電流處理函數(shù)(或),針對不同的中斷觸發(fā)類型(邊沿觸發(fā)或電平觸發(fā))做相應(yīng)的處理。然后調(diào)用遍歷鏈表從而調(diào)用該中斷號對應(yīng)的一個或多個中斷處理程序>,而>就是通過初始化的。首先分析一下函數(shù):<>
(
,
*){
*;
;
(>);
/*訪問內(nèi)容之前先加自旋鎖*/
(,
);
/*屏蔽與號對應(yīng)的中斷線
*//*
在多處理器系統(tǒng)上,為了避免多同時處理同一中斷。*當(dāng)>包含標(biāo)志時,說明該中斷*正在另一個上處理,因此當(dāng)前可以直接放棄處理。*/
((>
&
))
;
>
~(
|
);
(,
);
/*
*如果沒有對該中斷注冊處理程序,即>為。
*
或者>設(shè)置為,表示該中斷是被禁止的。
*
以上兩種情況只要出現(xiàn)一種即可放棄處理。*/
=
>;
((
(>
&
)))
;
>
;
/*標(biāo)識中斷狀態(tài)為正在處理*/
(>);
/*釋放自旋鎖*/
/*調(diào)用由注冊的處理函數(shù),稍后分析。*/
=
(,
);
()
(,
,
);
(>);
/*訪問內(nèi)容前加自旋鎖*/
>
;
/*清除“正在處理”的標(biāo)識*//*如果>包含,*則將>設(shè)置為,使該中斷仍處于被屏蔽狀態(tài)。
*/
((>
&
))
>
;/*如果中斷處理函數(shù)中未對>設(shè)置為,*且>>不為空,則>>所指向的芯片相關(guān)函數(shù),*解除對該中斷的屏蔽。
*/
(!(>
&
)
>>)
>>();:
(>);
/*釋放自旋鎖*/}再來介紹一下函數(shù),相對于要復(fù)雜一點(diǎn):<>
(
,
*){
(>);
>
~(
|
);
/*
*
如果該中斷正在被其他處理,或者是該中斷已被禁止,
*
則不處理該中斷,但要將其標(biāo)識為狀態(tài)且屏蔽該中斷以便后續(xù)處理
*/
(((>
&
(
|
))
>))
{
>
(
|
);
(,
);
;
}
(,
);
/*
*/
(>>)
>>();
/*
標(biāo)識該中斷狀態(tài)為“正在處理”*/
>
;
{
*
=
>;
;
(())
{
>>();
;
}
/*
*
如果當(dāng)處理該中斷時有另一個中斷到達(dá),
*
那么當(dāng)時可能屏蔽了該中斷。
*
如果該中斷沒有被禁止,則解除對該中斷的屏蔽。
*/
(((>
&
(
|
|
))
(
|
)))
{
>>();
>
;
}
>
;
(>);
/*調(diào)用由注冊的處理函數(shù),稍后分析。*/
=
(,
);
()
(,
,
);
(>);
/*如果該中斷沒有被禁止,并且有其他中斷等待處理(),*則循環(huán)處理其他中斷。*/
}
((>
&
(
|
))
);
>
;:
(>);}不管是電平觸發(fā)還是邊沿觸發(fā),最終都會通過來調(diào)用注冊的中斷處理函數(shù)。<>
(
,
*){
,
=
;
=
0;/*如果注冊中斷時沒有設(shè)置標(biāo)志,則在此處開啟硬中斷!開啟后允許硬中斷嵌套。從2.6.36版本內(nèi)核開始,標(biāo)志被廢除,此處不再開啟硬中斷,以防止中斷嵌套可能造成棧溢出的潛在風(fēng)險。詳細(xì)信息參見:*/
(!(>
&
))
();
{
(,
);
/*調(diào)用由注冊的中斷處理函數(shù)*/
=
>(,
>);
(,
,
);
()
{
*進(jìn)行中斷線程化處理*/
/*
*
*
.
*/
=
;
((>))
{
(,
);
;
}
(((,
>)))
{
(,
>);
/*喚醒由注冊的中斷處理線程*/
(>);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 借款合同簡單版借款文本
- 菜籽植物油購銷合同
- 購車合作合同模板
- 經(jīng)典借款合同范本詳細(xì)版
- 模板采購合同的訴訟途徑
- 標(biāo)準(zhǔn)項目咨詢服務(wù)合同全文
- 簡易工程分包合同格式
- 水池經(jīng)營合同
- 采購合同范本版本
- 購銷合同的格式要點(diǎn)
- 預(yù)拌混凝土企業(yè)質(zhì)量管理體系·程序文件
- 外國人換發(fā)或補(bǔ)發(fā)永久居留證件申請表樣本
- 塔吊安裝旁站監(jiān)理記錄表(示范稿)
- GCC認(rèn)證對整車的一般要求
- OBD-II標(biāo)準(zhǔn)故障代碼表
- 施工現(xiàn)場類安全隱患排查清單表
- 采購項目組織履約、驗收方案、程序、辦法
- 基于單片機(jī)的數(shù)字萬用表設(shè)計(共32頁)
- 送貨單(三聯(lián)針式打印)
- pdca循環(huán)在護(hù)理教學(xué)中的應(yīng)用學(xué)習(xí)教案
- 初中數(shù)學(xué)教學(xué)心得 展思維、立素養(yǎng)、樂評價——我的教學(xué)主張
評論
0/150
提交評論