日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

c语言interrupt函数,中断处理函数数组interrupt[]初始化

發(fā)布時(shí)間:2023/12/1 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言interrupt函数,中断处理函数数组interrupt[]初始化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在系統(tǒng)初始化期間,trap_init()函數(shù)將對(duì)中斷描述符表IDT進(jìn)行第二次初始化(第一次只是建一張IDT表,讓其指向ignore_intr函數(shù)),而在這次初始化期間,系統(tǒng)的0~19號(hào)中斷(用于分NMI和異常的中斷向量)均被設(shè)置好。與此同時(shí),用于系統(tǒng)調(diào)用的0x80號(hào)向量也已被設(shè)置。

然而,對(duì)于外部中斷的初始化 卻沒(méi)有在這個(gè)函數(shù)中進(jìn)行。而是在函數(shù)init_IRQ中。

仔細(xì)想一想內(nèi)核這樣做,的確是使代碼清晰又有條理。

1)trap_init -----> 內(nèi)部中斷異常和NMI(中斷向量號(hào):0~19)

2)?init_IRQ?? -----> 外部可屏蔽中斷??(中斷向量號(hào):32~127,129~238)

在init_IRQ函數(shù)中,對(duì)IDT中斷描述符表進(jìn)行了第三次完善(把相應(yīng)的外部中斷對(duì)應(yīng)的中斷向量進(jìn)行填充)

410 for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {

411 int vector = FIRST_EXTERNAL_VECTOR + i;

412 if (i >= NR_IRQS)

413 break;

414 if (vector != SYSCALL_VECTOR)

415 set_intr_gate(vector, interrupt[i]);

416 }

上述代碼解釋:

FIRST_EXTERNAL_VECTOR = 0x16;

設(shè)置中斷向量號(hào)32---NR_IRQS相應(yīng)的中斷處理程序地址為數(shù)組interrupt[i]的內(nèi)容。(除去128號(hào)中斷向量,已經(jīng)這個(gè)向量號(hào)已經(jīng)被用于系統(tǒng)調(diào)用)。

我們看一下interrupt數(shù)組的定義:這段程序時(shí)用匯編寫(xiě)的。

540 .data

541 ENTRY(interrupt)

542 .text

543

544 vector=0

545 ENTRY(irq_entries_start)

546 RING0_INT_FRAME

547 .rept NR_IRQS

548 ALIGN

549 .if vector

550 CFI_ADJUST_CFA_OFFSET -4

551 .endif

552 1: pushl $~(vector)

553 CFI_ADJUST_CFA_OFFSET 4

554 jmp common_interrupt

555 .data

556 .long 1b

557 .text

558 vector=vector+1

559 .endr

上面的代碼開(kāi)起來(lái)很亂,我們整理一下,使其更加易讀,但是又不失其本質(zhì)。

.data

ENTRY(interrupt)

.long 1b //注意 如果把數(shù)據(jù)段放在這里那么1b要改為1f了,而且失去循環(huán)執(zhí)行NR_IRQS次的功能。???????????????????? //我們只能人為的把他們想象成被循環(huán)執(zhí)行了NR_IRQS次 :)

.text

vector=0

ENTRY(irq_entries_start)

.rept NR_IRQS

1: pushl $~(vector)

jmp common_interrupt

vector=vector+1

我們把數(shù)據(jù)段放在一起,代碼段放在一起。注意這里的代碼段是用來(lái)初始化數(shù)據(jù)段的。

我們看到:interrupt作為一個(gè)內(nèi)存標(biāo)簽,其內(nèi)容為代碼段標(biāo)號(hào)1所表示的地址。同時(shí)我們也注意到這個(gè)interrupt數(shù)組的所有項(xiàng)的內(nèi)容都是一樣的:全部為“標(biāo)號(hào)1”的符號(hào)地址。

每次外部中斷來(lái)臨時(shí),硬件自動(dòng)根據(jù)PIC或者APIC送出來(lái)的中斷類型碼(中斷向量號(hào))去查找中斷描述符表的相應(yīng)項(xiàng),然后得到interrupt[n]的內(nèi)容,繼而轉(zhuǎn)去執(zhí)行標(biāo)號(hào)1地址的代碼,而標(biāo)號(hào)1的代碼僅將中斷號(hào)取反后壓入棧中,后立馬跳到common_interupt標(biāo)號(hào)處去執(zhí)行。至于為什么要把中斷向量號(hào)取反后壓棧,則是由于內(nèi)核用正的相應(yīng)號(hào)去表示系統(tǒng)調(diào)用號(hào),用負(fù)號(hào)來(lái)表示中斷號(hào)。

細(xì)心的你有可能發(fā)現(xiàn)了一個(gè)問(wèn)題:上述代碼片段只是向interrupt表示的內(nèi)存地址處存入大量重復(fù)的4字節(jié)數(shù)據(jù),卻沒(méi)有象C語(yǔ)言定義數(shù)組那樣定義interrupt[NR_IRQS-1],那么set_intr_gate這樣的函數(shù)是如何確切的指導(dǎo)interrupt是一個(gè)數(shù)組呢,而且數(shù)組的內(nèi)容是函數(shù)指針?

例如:set_intr_gate(vector,interrupt[i]);是如何取interrupt[i]內(nèi)容呢?

啰嗦了這么半天...

如下一個(gè)聲明就搞定了。[])(void);//函數(shù)指針數(shù)組

566 common_interrupt:

567 SAVE_ALL

568 TRACE_IRQS_OFF

569 movl %esp,%eax

570 call do_IRQ

571 jmp ret_from_intr

572 CFI_ENDPROC

common_interrupt首先執(zhí)行宏SAVE_ALL保存中斷處理程序可能用到的寄存器(注意:cs eip ss esp由硬件自動(dòng)保存)然后把棧頂指針傳給eax寄存器后(eax寄存器內(nèi)容將作為do_IRQ函數(shù)的參數(shù))調(diào)用do_IRQ進(jìn)行中斷處理,返回后

執(zhí)行ret_from_intr從中斷返回。

總結(jié)

以上是生活随笔為你收集整理的c语言interrupt函数,中断处理函数数组interrupt[]初始化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。