2014-10-12 41 views
3

這可能是一個不好的問題, 但我一直在編寫一個小型操作系統的教程。 到目前爲止,我已經設置了中斷描述符表,用於 註冊處理的方法,一個默認的處理程序(打印整型數字屏幕) 和重新映射PIC對中斷0x20的最多。PIT不發送中斷到IRQ0

我只是設置了可編程間隔計時器滴答爲50Hz,但它並 不會產生任何IRQ0的。我已經在描述符表的 的中斷32中設置了定時器處理程序,但是如果我手動生成中斷:__asm__ volatile ("int $0x20);我在屏幕上打印出「Tick:0x00000001」。

這裏是我的/timer.c裏的文件:

#include <common.h> 
#include <drivers/timer.h> 
#include <drivers/isr.h> 
#include <drivers/display.h> 
#include <drivers/io.h> 

u32int tick = 0; 

static void timer_callback(registers_t regs) { 
    tick++; 
    print("Tick: "); 
    print_hex_dword(tick); 
    print("\n"); 
} 

void init_timer(u32int frequency) { 
    register_interrupt_handler(IRQ0, &timer_callback); 

    u32int divisor = 1193180/frequency; 

    outb(0x43, 0x36); 

    u8int l = (u8int) (divisor & 0xFF); 
    u8int h = (u8int) ((divisor >> 8) & 0xFF); 

    outb(0x40, l); 
    outb(0x40, h); 
} 
+0

是否有可能你沒有編程的PIC掩碼,使PIT中斷?通常這是通過讀取端口0x21(主PIC數據端口)完成的,然後通過將新掩碼寫入0x21來啓用IRQ。將掩碼中的一位設置爲0可啓用中斷。所以你必須用0xFE(11111110)來'和'當前的位掩碼來啓用IRQ0上的PIT。 – 2014-10-12 05:01:17

+0

..或者定時器硬件必須在某些電源管理寄存器中打開? – 2014-10-12 07:38:36

+0

最小工作PIT示例:https://github.com/cirosantilli/x86-bare-metal-examples/blob/9a24f92f36a45abb3f8c37aafc0c3ee9b15563ab/in_pit.S – 2015-10-30 20:35:57

回答

0

三江源那些誰迴應。 但是你的回答很有幫助,問題在於 設置IDT並重新映射PIC之後,我忘記了再次包含程序集到 中斷。

PS: 是的,在重新映射PIC之後,我用0x0 屏蔽了它們,它們將啓用所有中斷。 - 感謝Michael Petch。

此外,我正在運行Oracle VirtualBox上的內核 Ubuntu 12.10,偶爾會在真實硬件上進行測試。 它也沒有工作,所以我不認爲計時器是以任何方式禁用的 。 - 感謝馬丁詹姆斯