Ошибка общей защиты после разрешения прерываний. OSDEV

Я пытаюсь разработать собственную операционную систему. Я написал код для 32-битной версии и дошел до пейджинга, когда внезапно решил, что хочу перейти на 64-битную версию. Я включил длинный режим, установил базовую подкачку страниц, запустил ядро, ядро ​​установило лучшую подкачку (первые 4 мегабайта выгружены, а также запуск фреймбуфера). Теперь я хочу включить прерывания, я реорганизовал свой 32-битный код idt в 64-битный и попытался включить его, он чудесным образом работает. В тот момент, когда я включаю его, я получаю общую ошибку защиты. Вот некоторые вещи, которые следует учитывать, у меня, кажется, есть все обработчики irq и isr, я знаю это, потому что, когда возникает общая ошибка защиты, она выводит ее на экран. Я почти уверен, что это вызвано таймером, но я не могу подтвердить, поскольку мой обработчик прерывания таймера также существует. Нет, я не забыл про iretq: D. Вот мой idt.c и полюбите его всему репозиторию github.

      
#include "IDT.h"

#define PUSHALL \
     ".intel_syntax noprefix\n\t" \
    "push    r15\n\t"\
    "push    r14\n\t"\
    "push    r13\n\t"\
    "push    r12\n\t"\
    "push    r11\n\t"\
    "push    r10\n\t"\
    "push    r9\n\t"\
    "push    r8\n\t"\
    "push    rax\n\t"\
    "push    rcx\n\t"\
    "push    rdx\n\t"\
    "push    rbx\n\t"\
    "push    rsp\n\t"\
    "push    rbp\n\t"\
    "push    rsi\n\t"\
    "push    rdi\n\t"\
     ".att_syntax\n\t" \

#define POPALL\
    ".intel_syntax noprefix\n\t" \
    "pop     rdi\n\t"\
    "pop     rsi\n\t"\
    "pop     rbp\n\t"\
    "add     rsp, 10\n\t"\
    "pop     rbx\n\t"\
    "pop     rdx\n\t"\
    "pop     rcx\n\t"\
    "pop     rax\n\t"\
    "pop     r8\n\t"\
    "pop     r9\n\t"\
    "pop     r10\n\t"\
    "pop     r11\n\t"\
    "pop     r12\n\t"\
    "pop     r13\n\t"\
    "pop     r14\n\t"\
    "pop     r15\n\t"\
    "add     rsp, 0x10\n\t"\
    ".att_syntax\n\t" \
    

/* Common body for interrupt handler */
#define MAKE_INTERRUPT_COMMON_STUB(intno, intfunc) \
            "push $"#intno"\n\t" \
            PUSHALL  \
            "cld\n\t" \
            "push %rsp\n\t" \
            "call " #intfunc "\n\t" \
            POPALL \
            "add $10, %rsp\n\t"       /* Skip int_num and err_code */ \
            "iretq \n\t" \
            "#.popsection\n\t"

/* Make interrupt for exception without error code. Push a dummy value for the
 * error code in it place. Push all the segment registers and the segment registers
 * so that they are available to interrupt function (intfun). Pushes a unique
 * interrupt number (intno) after the error code so that a handler can be multiplexed
 * if needed. Restore all the registers upon exit.
 *
 * intentry: Is the interrupt entry point that can be used in an Interrupt
 *           Descriptor Table (IDT) entry.
 * intfunc:  Is the C interrupt function that the stub calls to do processing
 * intno:    Interrupt number. Can be used to multiplex multiple interrupts to one
 *           intfunc handler.
 */
#define MAKE_INTERRUPT(intentry, intfunc, intno) \
    extern void intentry (void); \
    __asm__("#.pushsection .text\n\t" \
            ".global " #intentry "\n\t" \
            ".align 16\n\t" \
            #intentry ":\n\t" \
            "push $0\n\t"            /* Push dummy error code */ \
            MAKE_INTERRUPT_COMMON_STUB(intno, intfunc));

/* Make interrupt for exception with error code. Processor pushes the error code
 * after the return address automatically. Push all the segment registers and the
 * segment registers so that they are available to interrupt function (intfun).
 * Pushes a unique interrupt number (intno) after the error code so that a handler
 * can be multiplexed if needed. Restore all the registers upon exit.
 *
 * intentry: Is the interrupt entry point that can be used in an Interrupt
 *           Descriptor Table (IDT) entry.
 * intfunc:  Is the C interrupt function that the stub calls to do processing
 * intno:    Interrupt number. Can be used to multiplex multiple interrupts to one
 *           intfunc handler.
*/
#define MAKE_INTERRUPT_ERRCODE(intentry, intfunc, intno) \
    extern void intentry (void); \
    __asm__("#.pushsection .text\n\t" \
            ".global " #intentry "\n" \
            ".align 16\n\t" \
            #intentry ":\n\t" \
            MAKE_INTERRUPT_COMMON_STUB(intno, intfunc));

MAKE_INTERRUPT        (isr0,  isr0_handler,  0x00)
MAKE_INTERRUPT        (isr1,  isr1_handler,  0x01)
MAKE_INTERRUPT        (isr2,  isr2_handler,  0x02)
MAKE_INTERRUPT        (isr3,  isr3_handler,  0x03)
MAKE_INTERRUPT        (isr4,  isr4_handler,  0x04)
MAKE_INTERRUPT        (isr5,  isr5_handler,  0x05)
MAKE_INTERRUPT        (isr6,  isr6_handler,  0x06)
MAKE_INTERRUPT        (isr7,  isr7_handler,  0x07)
MAKE_INTERRUPT_ERRCODE(isr8,  isr8_handler,  0x08)
MAKE_INTERRUPT        (isr9,  isr9_handler,  0x09)
MAKE_INTERRUPT_ERRCODE(isr10, isr10_handler, 0x0a)
MAKE_INTERRUPT_ERRCODE(isr11, isr11_handler, 0x0b)
MAKE_INTERRUPT_ERRCODE(isr12, isr12_handler, 0x0c)
MAKE_INTERRUPT_ERRCODE(isr13, isr13_handler, 0x0d)
MAKE_INTERRUPT_ERRCODE(isr14, isr14_handler, 0x0e)
/* Reserved 0x0f */
MAKE_INTERRUPT        (isr16, isr0_handler,  0x10)
MAKE_INTERRUPT_ERRCODE(isr17, isr0_handler,  0x11)
MAKE_INTERRUPT        (isr18, isr0_handler,  0x12)
MAKE_INTERRUPT        (isr19, isr0_handler,  0x13)
MAKE_INTERRUPT        (isr20, isr0_handler,  0x14)
/* Reserved 0x15 to 0x1d */
MAKE_INTERRUPT_ERRCODE(isr30, isr0_handler,  0x1e)
/* Reserved 0x1f */

/* IRQ handlers */
MAKE_INTERRUPT        (irq0,  irq0_handler,  0x00)
MAKE_INTERRUPT        (irq1,  irq1_handler,  0x01)
MAKE_INTERRUPT        (irq2,  irq2_handler,  0x02)
MAKE_INTERRUPT        (irq3,  irq3_handler,  0x03)
MAKE_INTERRUPT        (irq4,  irq4_handler,  0x04)
MAKE_INTERRUPT        (irq5,  irq5_handler,  0x05)
MAKE_INTERRUPT        (irq6,  irq6_handler,  0x06)
MAKE_INTERRUPT        (irq7,  irq7_handler,  0x07)
MAKE_INTERRUPT        (irq8,  irq8_handler,  0x08)
MAKE_INTERRUPT        (irq9,  irq9_handler,  0x09)
MAKE_INTERRUPT        (irq10, irq10_handler,  0x0A)
MAKE_INTERRUPT        (irq11, irq11_handler,  0x0B)
MAKE_INTERRUPT        (irq12, irq12_handler,  0x0C)
MAKE_INTERRUPT        (irq13, irq13_handler,  0x0D)
MAKE_INTERRUPT        (irq14, irq14_handler,  0x0E)
MAKE_INTERRUPT        (irq15, irq15_handler,  0x0F)

void init_idt_entry(int num, unsigned int offset, unsigned short select, 
    unsigned short flags)
    {
        
        _idt_entries[num].offset0 = (unsigned short)(offset & 0x000000000000FFFF);
        _idt_entries[num].offset1 = (unsigned short)((offset & 0x00000000FFFF0000) >> 16);
        _idt_entries[num].offset2 = (unsigned int)((offset & 0xFFFFFFFF00000000) >> 32);

        _idt_entries[num].selector = select;
        _idt_entries[num].flags = flags;
         return;
    }




///////////////////////////////////////
void idt_flush(struct idt *idtr)
{
    asm volatile("lidt %0" :: "m"(*idtr));
}

void init_pic()
{

    outb(0x20,0x11);
    outb(0xA0,0x11);

    outb(0x21, 0x20);
    outb(0xA1, 40);

    outb(0x21, 0x04);
    outb(0xA1, 0x02);

    outb(0x21, 0x01);
    outb(0xA1, 0x01);

    outb(0x21, 0x0);
    outb(0xA1, 0x0);

    
}


void init_idt()
{
    init_pic();
    
    _idt_entries = RequestPage();
    Tidt.limit = 16 * 256;
    Tidt.base  = _idt_entries;
    
    memset(_idt_entries, 0, 16*256);
    
    
    
    for(int i = 0; i < 256 ; i++){
        init_idt_entry(i,(int)&isr0,0x08, 0x8E); 
    }
    init_idt_entry(0,(int)&isr0,0x08, 0x8E);
    init_idt_entry(1,(int)&isr1,0x08, 0x8E);
    init_idt_entry(2,(int)&isr2,0x08, 0x8E);
    init_idt_entry(3,(int)&isr3,0x08, 0x8E);
    init_idt_entry(4,(int)&isr4,0x08, 0x8E);
    init_idt_entry(5,(int)&isr5,0x08, 0x8E);
    init_idt_entry(6,(int)&isr6,0x08, 0x8E);
    init_idt_entry(7,(int)&isr7,0x08, 0x8E);
    init_idt_entry(8,(int)&isr8,0x08, 0x8E);
    init_idt_entry(9,(int)&isr9,0x08, 0x8E);
    init_idt_entry(10,(int)&isr10,0x08, 0x8E);
    init_idt_entry(11,(int)&isr11,0x08, 0x8E);
    init_idt_entry(12,(int)&isr12,0x08, 0x8E);
    init_idt_entry(13,(int)&isr13,0x08, 0x8E);
    init_idt_entry(14,(int)&isr14,0x08, 0x8E);
    /* ISR15 is reserved */
    init_idt_entry(16,(int)&isr16,0x08, 0x8E);
    init_idt_entry(17,(int)&isr17,0x08, 0x8E);
    init_idt_entry(18,(int)&isr18,0x08, 0x8E);
    init_idt_entry(19,(int)&isr19,0x08, 0x8E);
    init_idt_entry(20,(int)&isr20,0x08, 0x8E);
    /* ISR21 to ISR2F are reserved */
    init_idt_entry(30,(int)&isr30,0x08, 0x8E);

    /* IRQ handlers */
    init_idt_entry(32,(int)&irq0,0x08, 0x8E);
    init_idt_entry(33,(int)&irq1,0x08, 0x8E);
    init_idt_entry(34,(int)&irq2,0x08, 0x8E);
    init_idt_entry(35,(int)&irq3,0x08, 0x8E);
    init_idt_entry(36,(int)&irq4,0x08, 0x8E);
    init_idt_entry(37,(int)&irq5,0x08, 0x8E);
    init_idt_entry(38,(int)&irq6,0x08, 0x8E);
    init_idt_entry(39,(int)&irq7,0x08, 0x8E);
    init_idt_entry(40,(int)&irq8,0x08, 0x8E);
    init_idt_entry(41,(int)&irq9,0x08, 0x8E);
    init_idt_entry(42,(int)&irq10,0x08, 0x8E);
    init_idt_entry(43,(int)&irq11,0x08, 0x8E);
    init_idt_entry(44,(int)&irq12,0x08, 0x8E);
    init_idt_entry(45,(int)&irq13,0x08, 0x8E);
    init_idt_entry(46,(int)&irq14,0x08, 0x8E);
    init_idt_entry(47,(int)&irq15,0x08, 0x8E);
    
    
    idt_flush(&Tidt);
    
    asm volatile("sti;");
    
    
}

Вот мои isr.c и irq.c

ISR:

      #include "isr.h"

void isr0_handler(interrupt_frame_t *frame)
{
    panic("Divide by zero");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr1_handler(interrupt_frame_t *frame)
{
    panic("Debug");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr2_handler(interrupt_frame_t *frame)
{
    panic("NMI");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr3_handler(interrupt_frame_t *frame)
{
    panic("Breakpoint");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr4_handler(interrupt_frame_t *frame)
{
    panic("Overflow");
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr5_handler(interrupt_frame_t *frame)
{
    panic("Bound range exceeded");
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr6_handler(interrupt_frame_t *frame)
{
    panic("Invalid Opcode");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr7_handler(interrupt_frame_t *frame)
{
    panic("Device Not Available");
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr8_handler(interrupt_frame_t *frame)
{
    panic("Double Fault");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr9_handler(interrupt_frame_t *frame)
{
    panic("COPRO SEGMENT OVERRUN");
    
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr10_handler(interrupt_frame_t *frame)
{
    panic("Invalid TSS");
    
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr11_handler(interrupt_frame_t *frame)
{
    panic("Segment Not present");
    
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr12_handler(interrupt_frame_t *frame)
{
    panic("Stack Segment Fault");
    
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr13_handler(interrupt_frame_t *frame)
{
    panic("General Protection Fault");
    while(1);
    //fillRect(0, 0, 1080, 1920, 0xff0000);
}
void isr14_handler(interrupt_frame_t *frame)
{
    panic("Page Fault");
    
    while(1);
   //fillRect(0, 0, 1080, 1920, 0xff0000);
}

IRQ:

      
#include "irq.h"
#include "../../PS2/ps2.h"
#include "../../PS2/keyboard/keyboard.h"
#include "../../PS2/mouse/mouse.h"
#include "../../video/video.h" 
#include "../../string/string.h"

void default_irq_handler(interrupt_frame_t *frame)
{
        /* If IRQ # on slave PIC send EOI to slave */
        if (frame->int_no >= 8)
            outb(0xA0,0x20);

        /* Send EOI to master PIC */
        outb(0x20,0x20);
}

/* -------------------------- Programable Interval Timer ------------------------- */
void irq0_handler(interrupt_frame_t* frame)
{
    EnvironmentTick++;
    default_irq_handler(frame);
}

void Sleep(int ticks)
{
    int now = EnvironmentTick;

    while (EnvironmentTick != now + ticks);

    return;

}
void SetPITSpeed(int hz)
{
    int divisor = 1193180 / hz;       /* Calculate our divisor */
    outb(0x43, 0x36);             /* Set our command byte 0x36 */
    outb(0x40, divisor & 0xFF);   /* Set low byte of divisor */
    outb(0x40, divisor >> 8);     /* Set high byte of divisor */
}
/*  ------------------------------------------------------------------------------ */


/* -------------------------- Keyboard Controller -------------------------------- */
unsigned char currentCharInScancode;
unsigned char currentCharInKeycode;
unsigned char currentCharInASCII;

int isE0 = 0;
int isE1 = 0;
int pause = 0;
int prntscrn = 0;   
int isKeyPressed = 0;
int ignore = 0;
int isShift = 0;
char kbd_buffer[100];
int bufferIterator = 0;
char buffer[8];

void irq1_handler(interrupt_frame_t* frame)
{
    
    currentCharInScancode = readKeyboard();
    
    if(ignore > 0)
    {
        ignore--;
        default_irq_handler(frame);
        return;
    }
    else if(currentCharInScancode == 0xE1 && pause == 0)
    {
        pause = 1;
        ignore = 5;
    }
    else if(currentCharInScancode == 0xE0)
    {
        isE0 = 1;
        default_irq_handler(frame);
        return;
    }
    else if(currentCharInScancode == 0xF0)
    {
        isKeyPressed = 2;
        default_irq_handler(frame);
        return;
    }
    else if(currentCharInScancode == 0x7C && isE0 == 1)
    {   
        prntscrn = 1;
        ignore = 2;
    }
    
    
    if(isKeyPressed == 0)
        isKeyPressed = 1;
    else if(isKeyPressed == 2)
        isKeyPressed = 0;
    
    currentCharInKeycode = ScancodeToKeyCode(currentCharInScancode, isE0, prntscrn, pause);
    if(isE0 == 1) isE0 = 0;
    if(pause == 1) pause = 0;
    if(prntscrn == 1) prntscrn = 0;
    
    //drawStringToCursor(itoa(isKeyPressed, buffer, 16), 0xffffff, 0x000000);
    
    KeyPressed[currentCharInKeycode] = isKeyPressed; 
    
    //drawStringToCursor(itoa(isKeyPressed, buffer, 16), 0xffffff, 0x000000);
    
    kbd_buffer[bufferIterator] = currentCharInKeycode;
    if(bufferIterator == 99) bufferIterator = 0;
    else bufferIterator++;
    
    /*
    if((KeyCodeToASCII(currentCharInKeycode, KeyPressed[LSHIFT] | KeyPressed[RSHIFT]) != 0) && isKeyPressed == 1) 
    {
        drawCharToCursor(KeyCodeToASCII(currentCharInKeycode, KeyPressed[LSHIFT] | KeyPressed[RSHIFT]), 0xffffff, 0x000000);
        incrementCursor();
    }*/
    default_irq_handler(frame);
}
/*  ------------------------------------------------------------------------------ */

 
void irq2_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq3_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq4_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq5_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq6_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq7_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq8_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq9_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq10_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq11_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}

// -------------------------------- Mouse Controller ------------------------

unsigned char mouse_cycle = 0;
signed char mouse_byte[3];    //signed char
signed char mouse_x = 0;         //signed char
signed char mouse_y = 0;         //signed char
signed char state = 0;
signed char d = 0;

int LeftButton = 0;
int MiddleButton = 0;
int RightButton = 0;

unsigned char buff[16];
void irq12_handler(interrupt_frame_t* frame)
{
    switch(mouse_cycle)
    {
        case 0:
            mouse_byte[0]=readMouse();
            mouse_cycle++;
            break;
        case 1:
            mouse_byte[1]=readMouse();
            mouse_cycle++;
            break;
        case 2:
            mouse_byte[2]=readMouse();
            
            
            state = mouse_byte[2];
            d = mouse_byte[0];
            mouse_x = d - ((state << 4) & 0x100);
            d = mouse_byte[1];      
            mouse_y = d - ((state << 3) & 0x100);
            
            MouseX = MouseX + mouse_x;
            MouseY = MouseY - mouse_y;
            
            putpixel(MouseX, MouseY, 0xffffff);
            
            if( (state & 0b00001100) == 0b00001100 ) MiddleButton = 1;
            else if( (state & 0b00001100) == 0b00001000 ) MiddleButton = 0;
            
            if( (state & 0b000010001) == 0b00001001 ) LeftButton = 1;
            else if( (state & 0b00001001) == 0b00001000 ) LeftButton = 0;
            
            if( (state & 0b00001010) == 0b00001010 ) RightButton = 1;
            else if( (state & 0b00001010) == 0b00001000 ) RightButton = 0;
            
            //drawStringToCursor(itoa(RightButton, buffer, 16), 0xffffff, 0x000000);
            //incrementCursor();
            mouse_cycle=0;
            break;
    }
    default_irq_handler(frame);
}
// --------------------------------------------------------------------------

void irq13_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq14_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}
void irq15_handler(interrupt_frame_t* frame)
{
    default_irq_handler(frame);
}

И весь репозиторий github:https://github.com/Danyy427/OSDEV5.git

Вы можете найти материалы, связанные с idt, в source / kernel / idt

вы можете найти материалы, связанные с подкачкой, в источнике / ядре / памяти / подкачке

вы можете найти материал, связанный с gdt, в source / bootloader / AfterBoot.asm, который устанавливает 64-битный gdt.

0 ответов

Другие вопросы по тегам