首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OSDev。__attribute__((中断))不能完全工作

OSDev。__attribute__((中断))不能完全工作
EN

Stack Overflow用户
提问于 2022-09-12 11:08:28
回答 1查看 157关注 0票数 2

我在写操作系统。我想使用__attribute__((interrupt))来做一些中断支持(我从PonchoOS复制了一堆代码来启动).However,只有检测到的页面故障和双故障是有效的,其他中断不能工作(例如键盘和计时器)。

这是标题:

代码语言:javascript
复制
#ifndef _KERNEL_INTERRUPTS_H_
#define _KERNEL_INTERRUPTS_H_
#include <stdint.h>

#define GP_FAULT 0xD
#define PAGE_FAULT 0xE
#define TIME_INTR 0x20
#define KERYBOARD_INTR 0x21
#define MOUSE_INTR 0x2C
#define PI_INTR 0x20
#define SOFT_INTR 0x80
#define DOUBLE_PAGE_FAULT 0x08

#define IDT_InterruptGate    0x8e
#define IDT_CallGate         0x8c
#define IDT_TrapGate         0x8f

#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
#define PIC_EOI 0x20

#define ICW1_INIT 0x10
#define ICW1_ICW4 0x01
#define ICW4_8086 0x01

typedef struct _idtr {
    uint16_t limit;
    uint64_t offset;
} __attribute__((packed)) IDTR;

typedef struct _idt {
    uint16_t offset0;
    uint16_t selector;
    uint8_t zero;
    uint8_t type;
    uint16_t offset1;
    uint32_t offset2;
    uint32_t reserved;
} __attribute__((packed)) IDT;

void setIDTOffset(IDT* _idt, uint64_t offset);
uint64_t getIDTOffset(IDT* _idt);
void initializeInterrupts(void);
void setIRQ(uint8_t iqrn, void* handler, uint8_t typeAttributes, uint8_t selector);
void initializePIC(void);
void picEnd(void);

struct InterruptFrame;
__attribute__((interrupt)) void pageFaultHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void timerHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void doubleFaultHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void gpFaultHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void keyboardIntHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void mouseIntHandler(struct InterruptFrame* Frame);
__attribute__((interrupt)) void pitIntHandler(struct InterruptFrame* Frame);

#endif /* _KERNEL_INTERRUPTS_H_ */

这就是执行情况:

代码语言:javascript
复制
#include <interrupts.h>
#include <graphics.h>
#include <io.h>

IDT idt[256];
IDTR idtr;

void setIDTOffset(IDT* _idt, uint64_t offset) {
    _idt->offset0 = (uint16_t)(offset & 0xffff);
    _idt->offset1 = (uint16_t)((offset & 0xffff0000) >> 16);
    _idt->offset2 = (uint32_t)((offset & 0xffffffff00000000) >> 32);
}

uint64_t getIDTOffset(IDT* _idt) {
    uint64_t offset = 0;
    offset |= (uint64_t)_idt->offset0;
    offset |= (uint64_t)_idt->offset1 << 16;
    offset |= (uint64_t)_idt->offset2 << 32;
    return offset;
}

void initializeInterrupts(void) {
    idtr.limit = sizeof(IDT) * 256 - 1;
    idtr.offset = (uint64_t)idt;

    asm volatile("cli");
    setIRQ(PAGE_FAULT, (void*)pageFaultHandler, IDT_InterruptGate, 0x8);
    setIRQ(TIME_INTR, (void*)timerHandler, IDT_InterruptGate, 0x8);
    setIRQ(KERYBOARD_INTR, (void*)keyboardIntHandler, IDT_InterruptGate, 0x8);
    setIRQ(DOUBLE_PAGE_FAULT, (void*)doubleFaultHandler, IDT_InterruptGate, 0x8);
    setIRQ(GP_FAULT, (void*)gpFaultHandler, IDT_InterruptGate, 0x8);
    setIRQ(MOUSE_INTR, (void*)mouseIntHandler, IDT_InterruptGate, 0x8);
    setIRQ(PI_INTR, (void*)pitIntHandler, IDT_InterruptGate, 0x8);
    asm ("lidt %0" : : "m" (idtr));
    asm volatile("sti");
    initializePIC();
}

void setIRQ(uint8_t iqrn, void* handler, uint8_t typeAttributes, uint8_t selector) {
    setIDTOffset(&idt[iqrn], (uint64_t)handler);
    idt[iqrn].type = typeAttributes;
    idt[iqrn].selector = selector;
    idt[iqrn].zero = 0;
    idt[iqrn].reserved = 0;
}

void initializePIC(void) {
    uint8_t a1, a2;
    a1 = inb(PIC1_DATA);
    ioWait();
    a2 = inb(PIC2_DATA);
    ioWait();

    outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
    ioWait();
    outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
    ioWait;

    outb(PIC1_DATA, 0x20);
    ioWait();
    outb(PIC2_DATA, 0x28);
    ioWait();

    outb(PIC1_DATA, 4);
    ioWait();
    outb(PIC2_DATA, 2);
    ioWait();

    outb(PIC1_DATA, ICW4_8086);
    ioWait();
    outb(PIC2_DATA, ICW4_8086);
    ioWait();

    outb(PIC1_DATA, a1);
    ioWait();
    outb(PIC2_DATA, a2);
}

void picEnd(void){
    outb(PIC2_COMMAND, PIC_EOI);
    outb(PIC1_COMMAND, PIC_EOI);
}

__attribute__((interrupt)) void pageFaultHandler(struct InterruptFrame* Frame) {
    clear();
    debugPrint("Page Fault Detected");
    while(1);
}

__attribute__((interrupt)) void timerHandler(struct InterruptFrame* Frame) {
    debugPrint("timer\n");
    picEnd();
}

__attribute__((interrupt)) void doubleFaultHandler(struct InterruptFrame* Frame) {
    clear();
    debugPrint("Double Fault Detected");
    while(1);
}

__attribute__((interrupt)) void gpFaultHandler(struct InterruptFrame* Frame) {
    clear();
    debugPrint("General Protection Fault Detected");
    while(1);
}

__attribute__((interrupt)) void keyboardIntHandler(struct InterruptFrame* Frame) {
    clear();
    debugPrint("Pressed");
    uint8_t scanCode = inb(0x60);
    picEnd();
}

__attribute__((interrupt)) void mouseIntHandler(struct InterruptFrame* Frame) {

}

__attribute__((interrupt)) void pitIntHandler(struct InterruptFrame* Frame) {

}

这是我的github

我使用"asm (“int $0x21”)手动触发键盘中断。数据可以通过端口0x60读取。

我正在使用x86_64-elf来构建,使用QEMU运行kerne.How,我解决了这个问题吗?有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-15 12:02:47

谢谢您的reply.Just打开所有的中断。

代码语言:javascript
复制
outb(PIC1_DATA, 0x0); // enable all interrupt
ioWait();
outb(PIC2_DATA, 0x0);
ioWait();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73688328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档