Linux內(nèi)核設(shè)計與實現(xiàn) 中斷I/O: 頂部

中斷I/O

? ? ? ? CPU與外設(shè)之間的一種通信方式志衣。? 與CPU內(nèi)部的異常類似屯援。但區(qū)別就在于異常的發(fā)生是與處理器的時鐘信號的同步的,所以異常有時也被稱為同步中斷念脯。而中斷是異步的狞洋,可能發(fā)生在任何時候(如果中斷被允許的話)。

中斷處理程序

? ? ? ? 中斷處理程序是內(nèi)核用來響應(yīng)相應(yīng)中斷的程序绿店,通常來說每個設(shè)備都擁有對應(yīng)的中斷處理程序吉懊,來進行相應(yīng)的處理。舉例來說假勿,如果用戶按下鍵盤借嗽,則鍵盤會發(fā)送信號給中斷控制器,接著中斷控制器又通過CPU的中斷引腳通知CPU转培,在執(zhí)行完當(dāng)前指令后恶导,CPU立即檢測中斷引腳(似乎在每條指令執(zhí)行后,都會進行一次檢測)堡距,發(fā)現(xiàn)有中斷發(fā)生甲锡。CPU經(jīng)過一系列的檢查后兆蕉,如果當(dāng)前允許中斷,則確定中斷是由鍵盤產(chǎn)生的缤沦,然后啟動鍵盤的中斷處理程序虎韵,讀取用戶的輸入。

? ? ? ? 中斷程序必須執(zhí)行得盡可能的快缸废,這對于系統(tǒng)性能來說十分重要包蓝。但是通常來說,中斷程序的工作量十分浩大企量,比如說網(wǎng)絡(luò)設(shè)備的中斷程序:首先需要向設(shè)備確認(rèn)已了解到中斷的發(fā)生(設(shè)備不再發(fā)出中斷信號)测萎,然后將設(shè)備中的數(shù)據(jù)復(fù)制到內(nèi)存中,進行甄別届巩,把數(shù)據(jù)發(fā)送到其對應(yīng)的協(xié)議的椆枨疲或者是應(yīng)用程序中。顯然恕汇,在今天巨大的網(wǎng)絡(luò)吞吐量下腕唧,這是個耗時的工作。

? ? ? ? 于是就產(chǎn)生了矛盾瘾英,所以我們把中斷服務(wù)程序分為上下兩部分枣接。上半部分執(zhí)行耗時極少的工作,比如確認(rèn)已檢測到中斷或者將相應(yīng)設(shè)備重置缺谴。然后將那些繁重的但惶,卻又不是很迫切而可以延遲的工作,交付給中斷程序的下半部分湿蛔。在頂部執(zhí)行時膀曾,系統(tǒng)通常會禁止中斷的投遞,也就是說頂部的工作不會被其他中斷打斷(注意:此時在中斷上下文)阳啥,因為這部分工作相當(dāng)重要妓肢。而底部的工作,會在未來某個恰當(dāng)?shù)臅r機執(zhí)行苫纤,并且允許其他中斷的發(fā)生碉钠。

登記中斷處理程序

? ? ? ? 我們可以調(diào)用request_irq()函數(shù)(Kernel/irq.c)來向系統(tǒng)注冊一個中斷服務(wù)程序。


request_irq()

? ? ? ? 接下來解析每個參數(shù)的含義卷拘。irq指明要申請的的中斷號喊废,對某些設(shè)備來說,其對應(yīng)的中斷號是硬編碼的——也就是說不可更改栗弟,比如系統(tǒng)定時器和鍵盤污筷。至于其他的設(shè)備所使用的的中斷號,則是可以動態(tài)分配的。handler顧名思義就是對應(yīng)的中斷處理程序瓣蛀。irqflags可以為0陆蟆,或者從以下的值中選擇(可以使一個或者多個):

? ? ? ? SA_INTERRUPT:這種取值的中斷處理程序是快中斷處理程序。Linux系統(tǒng)通常將中斷程序相對地由快慢來劃分惋增。發(fā)展到了今天叠殷,個中的區(qū)? ? 別就是,當(dāng)快中斷程序執(zhí)行時诈皿,將當(dāng)前處理器的中斷禁用林束。這樣做會使處理程序更快地完成執(zhí)行,不會被其他中斷打擾稽亏。默認(rèn)情況下——也就是不啟用該標(biāo)志的情況下壶冒,除了與當(dāng)前處理程序共享中斷線的中斷外,所有中斷都是可用的截歉∨痔冢回憶《軟硬件接口》中的中斷屏蔽字位,可以建立起對應(yīng)關(guān)系——對每個中斷來說瘪松,確實存在私有的中斷屏蔽字胸嘁,當(dāng)起處理程序執(zhí)行時,禁用這些中斷凉逛。

? ? ? ? SA_SAMPLE_RANDOM:暫時不知道這是干啥的。

? ? ? ? SA_SHIRQ:設(shè)置了此為的處理程序表示其irq參數(shù)所指定的中斷線可以被其他中斷處理程序分享群井。如果不設(shè)置此位状飞,那么中斷線是被單一設(shè)備獨占的。早期的計算機系統(tǒng)中設(shè)備并不多书斜,因此設(shè)備獨占中斷線號的方法是可行的诬辈,當(dāng)往計算機里增加的設(shè)備越來越多時,獨占的方式明顯是不切實際的荐吉。因此產(chǎn)生了共享中斷線號的思想焙糟。那么當(dāng)一條共享中斷線中發(fā)來中斷信號,我們該如何辨別到底是哪個設(shè)備發(fā)生了中斷样屠?其實就是將該共享中斷線上的所以處理程序調(diào)用穿撮,不過在每個中斷處理程序的內(nèi)部首先檢查(參數(shù)信息以及設(shè)備硬件的支持)是不是這個中斷處理程序?qū)?yīng)的設(shè)備產(chǎn)生的中斷,通常是通過讀取該硬件設(shè)備提供的中斷標(biāo)志位進行判斷痪欲。如果不是悦穿,立即返回,如果是业踢,則處理完成栗柒,如果鏈表中沒有一個是,則說明出現(xiàn)錯誤知举。

? ? ? ? 下面回到對參數(shù)的介紹瞬沦。顧名思義devname就是設(shè)備的名字太伊,ASCII的文本。這個參數(shù)會被/proc/irq/proc/interrupts所使用逛钻。第五個參數(shù)dev_id是用于共享中斷線的僚焦。如果不提供這樣一個唯一的設(shè)備ID,那么我們就沒有辦法從共享中斷線中移除指定的中斷處理程序绣的。想象一下叠赐,每個人都長得差不多,那么辨別我們的方法就是身份證了屡江。通常來講芭概,這個參數(shù)會設(shè)置為硬件驅(qū)動的設(shè)備結(jié)構(gòu)體——獨一無二的,并且可能在處理程序中會被用到惩嘉。

? ? ? 注意:dev_id不是用于識別究竟是哪個設(shè)備產(chǎn)生中斷的0罩蕖!文黎!


釋放中斷處理程序

? ? ? ? 通過調(diào)用free_irq()來實現(xiàn)惹苗。


free_irq()

? ? ? ? 可以看到dev_id發(fā)揮了重要作用,它被用于判定處理程序是否為我們想要移除和釋放的處理程序耸峭。注意到第8行桩蓉,用了一個沒有釋放內(nèi)存但卻很有趣的刪除手段。

編寫中斷處理程序

? ? ? ? 中斷處理程序定義是這樣的:

? ? ? ? ? ? ? ? static irqreturn_t? intr_handler(int irq, void *dev_id, struct pt_regs*regs)

? ? ? ? 在這里劳闹,傳遞dev_id的原因是用于區(qū)分共享中斷處理程序的不同設(shè)備院究。在早期每個設(shè)備獨占中斷線號,用Irq區(qū)分即可本涕。但今非昔比业汰。還有比較重要的是返回值類型irqreturn_t——實際上就是int。其值只有兩種菩颖。我們用宏IRQ_RETVAL(val)來檢測样漆,val非0就返回IRQ_HANDLED,否則就返回IRQ_NONE晦闰。IRQ_HANDLED表示設(shè)備確實有中斷請求放祟,我們調(diào)用了正確的處理程序。如果是IRQ_NONE則表示未檢測到設(shè)備的中斷請求呻右。每個中斷處理程序的實現(xiàn)取決于設(shè)備舞竿,但通常來說都要向設(shè)備確認(rèn):我已了解到中斷了。

? ? ? ? 再次強調(diào):當(dāng)某中斷服務(wù)程序執(zhí)行時窿冯,其共享中斷線號上的所有中斷被屏蔽骗奖。并且相同的處理程序不可能在相同處理器并行地執(zhí)行。


中斷上下文

? ? ? ? ? 當(dāng)處理程序運行時,無論是上下部分执桌,它都是處于中斷上下文的鄙皇。

? ? ? ? ? 在Linux2.6里,每個進程的內(nèi)核棧大小都初始地被分配為一個頁面大小仰挣,減輕內(nèi)存壓力伴逸。中斷處理進程也被單獨地分配了一個頁大小的空間用作棧——此前膘壶,中斷進程將與被中斷的進程共享其內(nèi)核棧错蝴。如果自己新建中斷服務(wù)程序也無須擔(dān)心可用內(nèi)存的大小——因為內(nèi)核總是分配絕對的,最小的椡前牛空間顷锰。

? ? ? ? 個人猜想:中斷處理程序是預(yù)先駐留在內(nèi)存給定位置的,比如8086機器亡问,是存放在0x0000H開始的一段內(nèi)存空間官紫。當(dāng)中斷發(fā)生時,便根據(jù)中斷號啟動相應(yīng)的服務(wù)程序州藕。在此過程中嗜暴,內(nèi)核并沒有給中斷程序創(chuàng)建進程描述符立轧,所以其是不可調(diào)度的,這也呼應(yīng)了中斷程序上半部分必須執(zhí)行地盡可能快的原則炼邀。并且在整個中斷執(zhí)行過程中虫啥,current的值依舊指向原進程的進程描述符烈钞。

? ? ? ? 關(guān)于中斷上下文的詳細(xì)知識蝙搔,我閱讀更多源碼后再補充锯蛀。

中斷控制

? ? ? ? 以下是幾個關(guān)于中斷控制的接口函數(shù)。

? ? ? ? 啟用中斷: local_irq_enable()

? ? ? ? 禁用中斷: local_irq_disable()

? ? ? ? 保存中斷狀態(tài):local_irq_save((unsigned long) flags)

? ? ? ? 恢復(fù)中斷狀態(tài):local_irq_restore((unsigned long) flags)

? ? ? ? 禁止指定中斷線:void disable_irq(unsigned int irq)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void disable_irq_nosync(unsigned int irq)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? void sychronize_irq(unsigned int irq)

? ? ? ? 以上函數(shù)禁止指定中斷線向所有處理器的投遞馅精,但個中關(guān)系還不明朗。

? ? ? ? 啟用指定中斷線:void enable_irq(unsigned int irq)

? ? ? ? 檢查中斷狀態(tài):#define in_interrupt() (irq_count()) 如果內(nèi)核處于中斷上下文返回非0值粱檀,包括正在執(zhí)行的中斷處理程序或是下半部分程序洲敢。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #define in_irq() (hardirq_count()) 當(dāng)內(nèi)核正在執(zhí)行中斷處理程序(特指頂部),則返回非0值茄蚯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末压彭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渗常,更是在濱河造成了極大的恐慌壮不,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皱碘,死亡現(xiàn)場離奇詭異询一,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門健蕊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菱阵,“玉大人,你說我怎么就攤上這事缩功∏缂埃” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵嫡锌,是天一觀的道長虑稼。 經(jīng)常有香客問我,道長势木,這世上最難降的妖魔是什么蛛倦? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮跟压,結(jié)果婚禮上胰蝠,老公的妹妹穿的比我還像新娘。我一直安慰自己震蒋,他們只是感情好茸塞,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著查剖,像睡著了一般钾虐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笋庄,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天效扫,我揣著相機與錄音,去河邊找鬼直砂。 笑死菌仁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的静暂。 我是一名探鬼主播济丘,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼洽蛀!你這毒婦竟也來了摹迷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤郊供,失蹤者是張志新(化名)和其女友劉穎峡碉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驮审,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鲫寄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年吉执,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塔拳。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鼠证,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出靠抑,到底是詐尸還是另有隱情量九,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布颂碧,位于F島的核電站荠列,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏载城。R本人自食惡果不足惜肌似,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诉瓦。 院中可真熱鬧川队,春花似錦、人聲如沸睬澡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煞聪。三九已至斗躏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昔脯,已是汗流浹背啄糙。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留云稚,地道東北人隧饼。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像静陈,于是被迫代替她去往敵國和親燕雁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1 中斷介紹 1.1 簡介 中斷控制是計算機發(fā)展中一種重要的技術(shù)窿给。最初它是為克服對I/O接口控制采用程序查詢所帶來...
    瘋狂小王子閱讀 8,079評論 0 9
  • 又來到了一個老生常談的問題贵白,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢率拒? 今天就這個問題開始崩泡,來談?wù)劜?..
    tangsl閱讀 4,124評論 0 23
  • 生活是可以被規(guī)劃的,意味著你大概能想象未來的一年猬膨、二年角撞、三年的自己是什么樣子的呛伴。 從12月份起,花了將近兩個月的時...
    我是十六閱讀 404評論 1 0
  • 從沒有丈量過那條路的距離谒所,一公里热康?半公里?我記得不遠(yuǎn)劣领,甚至很近姐军,近得讓人很心安。沒錯尖淘,真的不遠(yuǎn)奕锌,因為你總是每天能往...
    山鬼sg閱讀 408評論 0 1
  • 麒麟閣上開皇宴 文武大臣坐兩班 王子公主排座次 笙管歌舞帝尊前 文不加點成大賦 君恩特賞金箔扇 扇屬公主號綠晴 賜...
    一葉茶閱讀 737評論 2 4