2016-01-22 26 views
5

在系統初始化或啓動代碼級別需要禁用所有中斷。如果我不禁止中斷會發生什麼?爲什麼我們需要在系統啓動或系統初始化時禁用所有中斷?

+5

您必須因爲您的中斷處理程序尚未安裝。如果你不禁止它們,並且你得到一箇中斷,系統/啓動將崩潰。 –

+3

您不希望中斷在安裝相應處理程序之前觸發,並且處理程序使用的所有數據結構都已初始化。否則你可能不會得到不可預知的行爲。 –

+1

如果您正在編寫實模式OS,則可能不需要禁用中斷。有關BIOS /硬件的默認實模式中斷表將適用。如果您打算創建保護模式操作系統,則需要在切換到保護模式之前禁用中斷。如果在中斷打開的情況下切換到保護模式,並且沒有中斷向量表(IVT),則可能會出現三重故障。一旦進入保護模式,您可以設置IVT,然後重新啓用中斷。 –

回答

6

有些情況下中斷是不需要的,所以它們被禁用。
的例子有很多,但是從我的頭頂,我能想出這些:的ss:(e)sp

  • 修改。如果中斷被觸發,flags寄存器被壓入堆棧。一個無效的堆棧值會將該副本移動到某個隨機位置。更改ss:(e)sp至少在x86上不是原子的,因爲它由多條指令組成,因此中斷可以在兩者之間觸發。
    但是,如果您正確編寫代碼,則可以在不禁用中斷的情況下實現相同的原子性,因爲它們是automatically disabled on certain occasions

    @MichaelPetch發出約8088個處理器(8086,第一個x86處理器的「軟弱的弟兄」),描繪了一個例外,這些一些特殊「某些特定場合,」在評論這個答案:

    即大約被關斷的中斷,直到下一個 指令結束(移動一個值SS之後),但也有8088個 處理器,其中所述中斷沒有正確關閉 一個SS改變之後的錯誤是真實的。我們這些人(恐龍)經常會將CLI/STI 圍繞SS:SP更新,以防萬一(運行8088 系統時有這樣的錯誤的機率可能接近於零)。從歷史 的角度來看,這個PC mag article可能會揭示這個古老的問題。

    (代碼格式化加入。)的IDT/IVT的

  • 缺失。在保護模式IDT被初始化或16位實模式IVT被修改(或清零或某物)時,中斷將跳轉到一些沒有指令位於的存儲器位置。

一般來說,可以說操作以某種非原子方式修改IDT/IVT需要禁用中斷。


順便說一句:我自己已經寫了一些引導加載程序,通常在整個引導程序的整個運行時禁止中斷。在保護模式下,我最終重新啓用它們。 Linux 4.2以類似的方式處理它。如果您有興趣,請閱讀其源代碼(/arch/x86/boot/)或Minix的源代碼!

+1

實際上,在x86上,由於特殊的規則,在第一種情況下不需要禁用中斷:在'pop%ss'之後,中斷在一個週期內被禁用,因此您有時間設置堆棧指針。 – fuz

+0

@FUZxxl完成。你可以看看嗎? – Downvoter

+0

這是正確的,但要小心,當你連續執行多個這樣的指令時,會有微妙的行爲。 – fuz