首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我正在制作的引导程序不会得到任何IRQ12

我正在制作的引导程序不会得到任何IRQ12
EN

Stack Overflow用户
提问于 2018-10-21 16:57:28
回答 1查看 152关注 0票数 0

我测试我的操作系统的计算机是一台带有触摸屏的笔记本电脑。当我打开电脑时,它会读取键盘,但在我触摸触屏后,它也不会读取触屏或键盘。我也使用qemu,在qemu上,它不读取鼠标,而是一直读取键盘。

这是我为鼠标使用的代码:

代码语言:javascript
复制
#ifndef _MOUSE
#define _MOUSE

#include "base.cpp"
#include "math.cpp"
#include "vector.cpp"
//#include "console.cpp"//------

class Mouse
{
    public:
    Bool key_pressed[3];
    Vector2 position;

    private:
    Vector<Ubyte> bytes_buffer;
    double mouse_area_y_respect_x;

    void limit_inside_area()
    {
        limit_inside(position.x,0,1);
        limit_inside(position.y,0,mouse_area_y_respect_x);
    }
    Bool process_stroke()
    {
        if(bytes_buffer.size()<4) return false;
        else
        {
            position.x=0;
            limit_inside_area();

            bytes_buffer.resize(bytes_buffer.size()-4);

            return true;
        }
    }

    Ubyte in_port_0x64()
    {
        Ubyte val;
        asm("in al,0x64;":"=a"(val));
        return val;
    }
    Ubyte in_port_0x60()
    {
        Ubyte val;
        asm("in al,0x60;":"=a"(val));
        return val;
    }
    void out_port_0x60(Ubyte byte)
    {
        asm("out 0x60,%%al"::"a"(byte));
    }
    void out_port_0x64(Ubyte byte)
    {
        asm("out 0x64,%%al"::"a"(byte));
    }
    void wait_for_device(Uint64 mode)
    {
        if(mode==0)
        {
            for(Uint64 n=0;n<10000;n++)
            {
                Ubyte val=in_port_0x64();
                if((val&1)==1) break;
            }
        }
        else
        {
            for(Uint64 n=0;n<10000;n++)
            {
                Ubyte val=in_port_0x64();
                if((val&2)==0) break;
            }
        }
    }
    void send_to_device(Ubyte byte)
    {
        wait_for_device(1);
        out_port_0x64(0xD4);
        wait_for_device(1);
        out_port_0x60(byte);
    }
    Ubyte wait_for_device_acknowledge()
    {
        wait_for_device(0);
        return in_port_0x60();
    }

    public:


    void initialize(double _mouse_area_y_respect_x)
    {
        for(Uint64 n=0;n<3;n++)
        {
            key_pressed[n]=false;
        }
        mouse_area_y_respect_x=_mouse_area_y_respect_x;
        if(mouse_area_y_respect_x>=0.1 && mouse_area_y_respect_x<=100){}
        else if(mouse_area_y_respect_x<0.1) mouse_area_y_respect_x=0.1;
        else if(mouse_area_y_respect_x>100) mouse_area_y_respect_x=100;
        else
        {
            mouse_area_y_respect_x=1;
        }
        position=Vector2(0.5,mouse_area_y_respect_x/2);
    }
    void initialize_device()
    {
        asm("cli");

        wait_for_device(1);
        out_port_0x64(0xA8);
        wait_for_device_acknowledge();

        wait_for_device(1);
        out_port_0x64(0x20);
        wait_for_device(0);
        Ubyte status=in_port_0x60();
        status=status|2;
        wait_for_device(1);
        out_port_0x64(0x60);
        wait_for_device(1);
        out_port_0x60(status);

        send_to_device(0xF6);
        wait_for_device_acknowledge();

        send_to_device(0xF4);
        wait_for_device_acknowledge();

        asm("sti");
    }
    void update_from_interrupt()
    {
        Ubyte data=in_port_0x60();
        input_byte[input_byte_cycle]=data;
        input_byte_cycle++;
        if(input_byte_cycle>3)
        {
            input_byte_cycle=0;

            position.x=0;
        }
        position.x=0;

        //bytes_buffer.push_back(data);
        //if(bytes_buffer.size()>10000) bytes_buffer.resize(0);
    }
    Ubyte input_byte[4];
    Uint64 input_byte_cycle=0;
    void update()
    {




        //while(bytes_buffer.size()>0 && process_stroke()){}
    }
};

static Mouse*CURRENT_MOUSE;

#endif

这就是我在引导加载程序中调用函数"initialize_device()“的点:

代码语言:javascript
复制
    Mouse mouse;
    mouse.initialize(768.0/1024);
    mouse.initialize_device();
    CURRENT_MOUSE=&mouse;

    set_interrupts_handler((Uint64)&interrupts_handler);

    //the BIOS call for VESA
    call_assembly(0,0x4f02,VESA_MODE,0,0,0,0,0,0x10);

    Uint64 time=0;
    while(1)
    {
        for(Uint64 n=0;n<1;n++)
        {
            CURRENT_KEYBOARD->update();
            CURRENT_MOUSE->update();
        }

        time++;
        console.draw(screen,time/10);

        screen.circlefill((CURRENT_MOUSE->position*1024).toPos(),10,0xffffff);

        if(bootloader_info.VESA->BitsPerPixel==24) screen.draw(bootloader_info.VESA->PhysBasePtr);
        else screen.draw_alpha(bootloader_info.VESA->PhysBasePtr);
    }

以及处理某些中断的中断处理程序:

代码语言:javascript
复制
void interrupts_handler()
{
    Uint64 interrupt_number=get_interrupt_number_interrupts_handler();

    if(interrupt_number==8)
    {
        TIME++;
    }
    else
    {
        CURRENT_CONSOLE->printhex(interrupt_number);//---------------------
        CURRENT_CONSOLE->printf(" ");

        if(interrupt_number==9)
        {
            Uint64 var;
            asm("in al,0x60;"
                /*"out 0x61,al;"*/:"=a"(var));
            Ubyte keycode=var;
            CURRENT_KEYBOARD->update_from_interrupt(var);
        }
        else if(interrupt_number==0x74)
        {
            CURRENT_MOUSE->update_from_interrupt();
        }
        else if(interrupt_number==0x0f)
        {

        }
    }
}

这只是代码的一小部分,但我已经把我认为最重要的部分放在了这里。

以及类型(在base.cpp中定义):

代码语言:javascript
复制
typedef char Int8;
typedef unsigned char Uint8;
typedef short int Int16;
typedef unsigned short int Uint16;
typedef int Int32;
typedef unsigned int Uint32;
typedef long long int Int64;
typedef unsigned long long int Uint64;

typedef Int8 Byte;
typedef Uint8 Ubyte;
typedef Ubyte* Ptr;
typedef Ubyte Bool;

在中断处理程序中使用"CURRENT_CONSOLE->printhex(interrupt_number);“,我让它打印它得到的中断的数目,这就是为什么我知道我没有得到任何IRQ12,(我没有重新映射它)。

中断处理程序的另一部分,在nasm程序集中:

代码语言:javascript
复制
LONG_MODE_BASIC_INTERRUPTION_HANDLER:

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_E 1
push rax
mov al,%1
jmp .handler
%endmacro

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 1
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x01
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x02
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x03
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x04
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x05
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x06
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x07
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x08
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x09
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0A
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0B
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0C
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0D
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0E
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0F
%endmacro

LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x10
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x20
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x30
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x40
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x50
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x60
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x70
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x80
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x90
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xA0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xB0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xC0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xD0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xE0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xF0

.handler:

cmp al,8
je .timer_or_double_fault
cmp al,9
je .keyboard
cmp al,0x0d
je .general_protection_fault
cmp al,0x0e
je .page_fault_or_floppy_disc
cmp al,0x0f
je .strange_or_spurious
cmp al,0x74
je .mouse


call NOT_HANDLED_INTERRUPT_MESSAGE
jmp $

.timer_or_double_fault:

;pop rbx
;pop rcx
;cmp rcx,0
;je .double_fault
;push rcx
;push rbx

push rbx
push rcx
mov rcx,[rsp-3]
mov rbx,[rsp-4]
cmp rcx,0
je .double_fault
pop rcx
pop rbx

jmp .timer

.keyboard:
.mouse:
.strange_or_spurious:
.timer:

push rbx
mov rbx,[POINTER_TO_INTERRUPTS_HANDLER]
cmp rbx,0
je .no_cpp

mov [INTERRUPT_NUMBER_FOR_HANDLER],al
PUSHA64
call [POINTER_TO_INTERRUPTS_HANDLER]
POPA64

.no_cpp:
pop rbx

mov al,0x20
out 0x20,al
jmp .end

.double_fault:
push rbx

call DOUBLE_FAULT_MESSAGE

BITS 64

.general_protection_fault:

call GENERAL_PROTECTION_FAULT_MESSAGE

mov al,0x20
out 0x20,al
jmp .end

.page_fault_or_floppy_disc:

push rbx
push rcx
mov rcx,[rsp-3]
mov rbx,[rsp-4]
cmp rcx,32
jl .page_fault
pop rcx
pop rbx

mov al,0x20
out 0x20,al
jmp .end

.page_fault:
push rbx


;-----------------------------

mov al,0x20
out 0x20,al
jmp .end

.end:
pop rax
iretq

编辑:

我已在程序集中更改了处理程序:

代码语言:javascript
复制
LONG_MODE_BASIC_INTERRUPTION_HANDLER:

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_E 1
push rax
mov al,%1
jmp .handler
%endmacro

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 1
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x01
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x02
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x03
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x04
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x05
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x06
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x07
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x08
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x09
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0A
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0B
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0C
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0D
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0E
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0F
%endmacro

LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x10
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x20
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x30
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x40
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x50
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x60
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x70
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x80
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x90
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xA0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xB0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xC0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xD0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xE0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xF0

.handler:

cmp al,8
je .timer_or_double_fault
cmp al,9
je .keyboard
cmp al,0x0d
je .general_protection_fault
cmp al,0x0e
je .page_fault_or_floppy_disc
cmp al,0x0f
je .strange_or_spurious
cmp al,0x74
je .mouse


call NOT_HANDLED_INTERRUPT_MESSAGE
jmp $

.timer_or_double_fault:

;pop rbx
;pop rcx
;cmp rcx,0
;je .double_fault
;push rcx
;push rbx

push rbx
push rcx
mov rcx,[rsp-3]
mov rbx,[rsp-4]
cmp rcx,0
je .double_fault
pop rcx
pop rbx

jmp .timer

.keyboard:
.mouse:
.strange_or_spurious:
.timer:

push rbx
mov rbx,[POINTER_TO_INTERRUPTS_HANDLER]
cmp rbx,0
je .no_cpp

mov [INTERRUPT_NUMBER_FOR_HANDLER],al
PUSHA64
call [POINTER_TO_INTERRUPTS_HANDLER]
POPA64

.no_cpp:

mov al,0x20
mov bl,[INTERRUPT_NUMBER_FOR_HANDLER]
cmp bl,0x70
jl .IRQ0_7
out 0xA0,al
.IRQ0_7:
out 0x20,al

pop rbx

jmp .end

.double_fault:
push rbx

call DOUBLE_FAULT_MESSAGE

BITS 64

.general_protection_fault:

call GENERAL_PROTECTION_FAULT_MESSAGE

jmp .end

.page_fault_or_floppy_disc:

push rbx
push rcx
mov rcx,[rsp-3]
mov rbx,[rsp-4]
cmp rcx,32
jl .page_fault
pop rcx
pop rbx

mov al,0x20
out 0x20,al
jmp .end

.page_fault:
push rbx


;-----------------------------

jmp .end

.end:
pop rax
iretq

编辑2:

程序集中的中断处理程序:

代码语言:javascript
复制
%macro PUSHA64 0
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
%endmacro

%macro POPA64 0
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
%endmacro

LONG_MODE_BASIC_INTERRUPTION_HANDLER:

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_E 1
push rax
mov al,%1
jmp .handler
%endmacro

%macro LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 1
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x01
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x02
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x03
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x04
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x05
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x06
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x07
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x08
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x09
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0A
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0B
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0C
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0D
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0E
LONG_MODE_BASIC_INTERRUPTION_HANDLER_E %1+0x0F
%endmacro

LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x00
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x10
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x20
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x30
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x40
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x50
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x60
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x70
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x80
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0x90
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xA0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xB0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xC0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xD0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xE0
LONG_MODE_BASIC_INTERRUPTION_HANDLER_16E 0xF0

.handler:

PUSHA64

cmp al,0x08
je .double_fault
cmp al,0x0d
je .general_protection_fault
cmp al,0x0e
je .page_fault
cmp al,0x70
je .timer
cmp al,0x71
je .keyboard
cmp al,0x76
je .floppy_disc
cmp al,0x7c
je .mouse
cmp al,0x77
je .strange_or_spurious

call NOT_HANDLED_INTERRUPT_MESSAGE
jmp $

.keyboard:
.mouse:
.strange_or_spurious:
.timer:
.floppy_disc:
mov rbx,[POINTER_TO_INTERRUPTS_HANDLER]
cmp rbx,0
je .no_cpp
mov [INTERRUPT_NUMBER_FOR_HANDLER],al
call [POINTER_TO_INTERRUPTS_HANDLER]
.no_cpp:
mov al,0x20
mov bl,[INTERRUPT_NUMBER_FOR_HANDLER]
cmp bl,0x78
jl .IRQ0_7
out 0xA0,al
.IRQ0_7:
out 0x20,al
jmp .end

.double_fault:
call DOUBLE_FAULT_MESSAGE
jmp .end_pop_error_code

.general_protection_fault:
call GENERAL_PROTECTION_FAULT_MESSAGE
jmp .end_pop_error_code

.page_fault:
jmp .end_pop_error_code

.end:
POPA64
pop rax
iretq

.end_pop_error_code:
POPA64
pop rax
pop qword[.void]
iretq

.void: dq 0

映射图片的代码:

代码语言:javascript
复制
BITS 32

io_wait:
push ecx
mov ecx,100
.loop:
loop .loop
pop ecx
ret

; Input:
; al: first PIC's offset
; bl: second PIC's offset
remap_PICs:

PIC1_COMMAND equ 0x20
PIC2_COMMAND equ 0xA0
PIC1_DATA equ 0x21
PIC2_DATA equ 0xA1
ICW1_INIT_WITH_ICW1_ICW4 equ 0x11
ICW4_8086 equ 0x01

mov ch,al
mov dh,bl

in al,PIC1_DATA
mov cl,al
in al,PIC2_DATA
mov dl,al

mov al,ICW1_INIT_WITH_ICW1_ICW4
out PIC1_COMMAND,al
call io_wait
out PIC2_COMMAND,al
call io_wait

mov al,ch
out PIC1_DATA,al
call io_wait
mov al,dh
out PIC2_DATA,al
call io_wait

mov al,4
out PIC1_DATA,al
call io_wait
mov al,2
out PIC2_DATA,al
call io_wait

mov al,ICW4_8086
out PIC1_DATA,al
call io_wait
out PIC2_DATA,al
call io_wait

mov al,cl
out PIC1_DATA,al
mov al,dl
out PIC2_DATA,al

ret
EN

回答 1

Stack Overflow用户

发布于 2018-10-23 08:49:25

你有多个问题:

1您需要在中断入口保存所有寄存器(并恢复它们)。如果不这样做,则无法在中断处理程序运行后恢复。这对于调试来说很微妙,因为如果您在中断之前处于空闲状态,您将不会注意到已损坏的寄存器状态。

2你需要把ICWs发给照片。有人在评论中提到了这一点,但如果没有ICW,你真的不知道PIC会对中断做什么。将中断重新映射到0x20..0x30。

您需要选择如何与PIC交互;当前流行的做法是使用中断项来屏蔽和确认中断,这将释放其他中断发生。

  1. 你把你的异常和中断混为一谈。这有两个问题:第一,除非是为了真正的中断,否则不应该碰PIC;其次,一些异常会在堆栈上推一个额外的值,这是您需要适应的。

因此,保存更多寄存器,初始化图片,将异常与中断分开。

更新源代码的增编: 1.我没有看到任何你初始化图片的代码。2.您使用的这个混乱的汇编程序隐藏得太多了:如果您已经将真正的中断基设置为0x70和0x78,我希望看到与这些条目相对应的代码,以及设置相应IDT条目的代码。我都没看见。

你已经耗尽了我的耐心,你没有提供所要求的资源,你提供的资源也是不明智的。我没办法帮你。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52917741

复制
相关文章

相似问题

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