標題說明了一切,我的pic masking作業。 如果我發送一個IRQ(擊鍵),內核就會崩潰。 我正在使用nasm。 我應該怎樣做才能在發送中斷時執行例外處理函式呢?
idt.h
#pragma once
#include "./types.h"
#define IDT_MAX_DESCRIPTORS 256
#define GDT_OFFSET_KERNEL_CODE (0x01 * 0x08) //!!!! 只是為了測驗。
extern uint64_t isr_stub_table[] 。
typedef struct {
uint16_t isr_low; //ISR的地址的低16位。
uint16_t kernel_cs; //CPU在呼叫ISR之前將加載到CS的GDT段選擇器。
uint8_t ist; //CPU將加載到RSP的TSS中的IST;暫時設定為零。
uint8_t attributes; // Type and attributes; see the IDT page。
uint16_t isr_mid; //ISR地址的低32位中的高16位。
uint32_t isr_high; //ISR地址的高32位。
uint32_t reserved; //設定為零。
} __attribute__((packed)) idt_desc_t;
typedef struct {
uint16_t limit。
uint64_t base。
} __attribute__((packed)) idtr_t;
static idtr_t idtr;
void idt_reload(idtr_t* idtr)。
void idt_set_descriptor(uint8_t vector, uintptr_t isr, uint8_t flags, uint8_t ist) ;
void idt_init(void)。
static bool vectors[IDT_MAX_DESCRIPTORS] 。
idt.c:
#include "idt.h"
#include "./types.h"
idt_desc_t idt[IDT_MAX_DESCRIPTORS]; //創建一個IDT條目的陣列;為了性能而對齊。
void idt_set_descriptor(uint8_t vector, uintptr_t isr, uint8_t flags, uint8_t ist) {
idt_desc_t* descriptor = &idt[vector] 。
descriptor->isr_low = isr & 0xFFFF;
descriptor->kernel_cs = GDT_OFFSET_KERNEL_CODE;
descriptor->ist = ist;
descriptor->屬性 = flags;
descriptor->isr_mid = (isr >> 16) & 0xFFFF;
descriptor->isr_high = (isr >> 32) & 0xFFFFFFFF;
descriptor->reserved = 0;
}
void idt_init() {
idtr.base = (uintptr_t)& idt[0]。
idtr.limit = (uint16_t)sizeof(idt_desc_t) * IDT_MAX_DESCRIPTORS - 1;
for (uint8_t vector =0; vector < 32; vector ) {
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E, 1) 。
vectors[vector] = true;
}
volatile("lidt %0"/span> : : "memory"(idtr)); //加載新的IDT。
__asm__ volatile("sti"); ///設定中斷標志。
}
void exception_handler() {
terminal_puts("Hello")。
__asm__ volatile ("cli; hlt"); //徹底掛起電腦。
如果我去掉__asm__ volatile("sti");部分,它就不會再崩潰了,但仍然不能處理中斷。
idt.asm:
extern exception_handler
%macro isr_err_stub 1 例外處理程式。
isr_stub_% %1:
呼叫例外處理程式
iretq
%endmacro
%macro isr_no_err_stub 1: 呼叫例外處理程式 iretq %endmacro
isr_stub_% %1:
呼叫例外處理程式
iretq
%endmacro
isr_no_err_stub 0: 呼叫例外處理程式 iretq %endmacro
isr_no_err_stub1
isr_no_err_stub2
isr_no_err_stub3
isr_no_err_stub4
isr_no_err_stub5
isr_no_err_stub6
isr_no_err_stub7
isr_err_stub8
isr_no_err_stub9
isr_err_stub10
isr_err_stub11
isr_err_stub12
isr_err_stub13
isr_err_stub14
isr_no_err_stub15
isr_no_err_stub16
isr_err_stub17
isr_no_err_stub18
isr_no_err_stub19
isr_no_err_stub20
isr_no_err_stub21
isr_no_err_stub22
isr_no_err_stub23
isr_no_err_stub 24
isr_no_err_stub 25
isr_no_err_stub26
isr_no_err_stub27
isr_no_err_stub28
isr_no_err_stub29
isr_err_stub 30
isr_no_err_stub31
全域 isr_stub_table
isr_stub_table。
%assign i 0.
%rep 32 1
%endrep
我不知道還有什么細節可以補充,所以如果你需要的話,請問一下。 我已經使用了這個教程。https://wiki.osdev.org/Interrupts_tutorial
uj5u.com熱心網友回復:
一切都正確,但gdt的初始化方式不正確
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/320397.html
標籤:
上一篇:從C代碼到RISC-V匯編代碼
