操作系统开发人员:设置idt

时间:2019-02-16 15:45:42

标签: c kernel osdev general-protection-fault

我试图从头开始编写一个没有任何库和东西的操作系统。因此,我设置了IDT和其他东西,最后完成了它。因此,当我尝试它时,它一直在重新启动。我只写了int 0x0,所以我写了前16个以处理我至少会看到的异常。所以我要做的就是设置一个set_background函数,并给每个异常一个从0到15的异常颜色,我给了20到2f的颜色(我在13h模式下:320x200p 256色)当我运行OS时,我发现我的异常是带有2d颜色代码的代码。这是位于13的通用保护错误。我知道抛出通用保护错误时,它指向通过eip的指令。因此,我使用了仿真器控制台(qemu监视器)来获取引发异常的指令的值。我猜它与我的fill_rect函数的地址相对应,但是我不确定我什至找不到。

内核如下

#include "OS.h"


int kmain()
{

    init_idt();

    //asm("int $0x0");

    while(1);
}

我没有写太多内核代码,因为我不需要

OS.h文件如下

#include "IO.h"
#include "screen.h"

#ifndef __TARAOS_H
#define __TARAOS_H

    #define NULL 0
    //TODO: Add more keys
    unsigned char MapScancodeToAscii(unsigned Scancode)
    {
        unsigned char ScancodeTabel[] = {
            '\0',       
            '\0',       //
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            '0',
            '-',
            '=',
            '   ',
            'q',
            'w',
            'e',
            'r',
            't',
            'y',
            'u',
            'i',
            'o',
            'p',
            '[',
            ']',
            '\n',
            'a',
            's',
            'd',
            'f',
            'g',
            'h',
            'j',
            'k',
            'l',
            ',',
            '\\',
            '`',
            'z',
            'x',
            'c',
            'v',
            'b',
            'n',
            'm',
            ',',
            '.',
            '/',
            ' '
        };

        unsigned char ret = ScancodeTabel[Scancode];


        if(ret == 0) {/* TODO: ADD ERROR - HANDLE CODE */}

        return ret;
    }
    //Video
    //Definitions of Video constants

    #define __VIDMEM__ 0xA000
    #define __DEFAULT_WOB__ 0x0f

    //Keyboard
    //Definition of Keyboard Driver constants

    #define __STATUS_PORT__ 0x64
    #define __DATA_PORT__ 0x60


    void* memset(void* ptr, int value, int num) 
    { 
       unsigned char* ptr_byte = (unsigned char*)ptr;

       for (int i = 0; i < num; ptr_byte[i] = (unsigned char)value, i++);   
       return ptr;
    }

    int strlen(char *s)
    {
        char *p = s;
        while (*p != '\0')
            ++p;
        return p - s; 
    }

    int strcmp(char string1[], char string2[] )
    {
        for (int i = 0; ; i++)
        {
            if (string1[i] != string2[i])
            {
                return string1[i] < string2[i] ? -1 : 1;
            }
            if (string1[i] == '\0')
            {
                return 0;
            }
        }
    }

    void set_background(unsigned char* screen,int color)
    {
        unsigned char* vm = screen;
        fill_rect((int)vm,0,320,0,200,color);   
    }



    //IDT///////////////////////////////////////////
    struct idt
    {
        short limit;
        unsigned int base;
    }__attribute__ ((packed));
    struct idt_entry
    {
        short base_low;
        short select;
        char always0;
        char flags;
        short base_high;
    }__attribute__ ((packed));
    struct idt Tidt;
    struct idt_entry _idt_entries[256];
    #define IDTBASE    0x00000000
    #define IDTSIZE 0xFF

    void init_idt_entry(int num, unsigned int offset, unsigned short select, 
        unsigned short flags)
        {
            _idt_entries[num].base_low = (offset & 0xffff);
            _idt_entries[num].base_high =  (offset & 0xffff0000) >> 16;
            _idt_entries[num].always0 = 0;
            _idt_entries[num].flags = flags;
            _idt_entries[num].select = select;
             return;
        }
    void isr_common_handler()
    {

        asm(".intel_syntax noprefix;"
            "sti;"
            "iret;"
            ".att_syntax prefix;"
            );
    }
    void isr0()
    {
        asm(".intel_syntax noprefix;"
            ""
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x20);

        isr_common_handler();
    }
    void isr1()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x21);

        isr_common_handler();
    }
    void isr2()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x22);

        isr_common_handler();
    }
    void isr3()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x23);

        isr_common_handler();
    }
    void isr4()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x24);

        isr_common_handler();
    }
    void isr5()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x25);

        isr_common_handler();
    }
    void isr6()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x26);

        isr_common_handler();
    }
    void isr7()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x27);

        isr_common_handler();
    }
    void isr8()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x28);

        isr_common_handler();
    }
    void isr9()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x29);

        isr_common_handler();
    }
    void isr10()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x2a);

        isr_common_handler();
    }
    void isr11()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x2b);

        isr_common_handler();
    }
    void isr12()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x2c);

        isr_common_handler();
    }
    void isr13()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );




        set_background((unsigned char*)0xA0000, 0x2d);
        isr_common_handler();
    }
    void isr14()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x2e);

        isr_common_handler();
    }
    void isr15()
    {
        asm(".intel_syntax noprefix;"
            "cli;"
            ".att_syntax prefix;"
            );

        set_background((unsigned char*)0xA0000, 0x2f);

        isr_common_handler();

    }



    void idt_flush(int offset)
    {
        asm volatile(
        ".intel_syntax noprefix;"
        "mov eax, [esp+4]  ;" 
        "lidt [eax]        ;"
        "ret;"
        ".att_syntax prefix;"
        );
    }

    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();
        Tidt.limit = 8 * 256;
        Tidt.base  = (int)&_idt_entries;


        memset(&_idt_entries, 0, 8*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); 
        init_idt_entry(15,(int)&isr15,0x08, 0x8E); 



        idt_flush((int)&Tidt);


        asm volatile(".intel_syntax noprefix;"
            "sti;"
            ".att_syntax prefix;"
            );
    }


#endif

我认为会导致故障的fill rect函数包含在screen.h中

#ifndef __SCREEN_H__
#define __SCREEN_H__


    void putpixel(unsigned char* screen, int x,int y, int color) {
        unsigned char* fb = screen;
        unsigned int offset = y * 320 + x;
        fb[offset] = color;
    }

    void draw_line(unsigned char* screen, int fromx, int tox, int y,int color)
    {
        unsigned char* fb = screen;
        unsigned int offset = y * 320 + fromx;

        for(int i = 0;i < tox; i++)
        {
            fb[offset+i] = color;
        }
    }

    void fill_rect(unsigned char* screen, int fromx, int tox, int fromy,int toy,int color)
    {
        unsigned char* fb = screen;
        unsigned int start_offset = fromy * 320 + fromx;
        unsigned int end_offset = toy * 320 + tox;

        for(int i = fromy; i < toy ; i++ )
        {
            for(int j = fromx; j < tox ; j++)
            {
                putpixel(fb,j,i,color);
            }

        }
    }


#endif

我认为fill_Rect函数是导致故障的函数

在地址1170中显示了导致异常的函数83 45 f8 01(我将内核加载到0x1000)

编辑:

其他文件

引导程序:

[ORG 0x7c00]
BITS 16
global _boot_start

_boot_start:
; Yükleyici

    cli
    mov bx,0x9000
    mov bp,bx
    mov sp,bx
    mov ss,bx
    sti 


    xor ax, ax     
    mov ds, ax       
    mov es, ax


    mov [bootdev], dl


    mov bx, MSG_START       ;
    call print_string


    mov dl, [bootdev]          
    mov dh, 5          
    mov cl, 0x02
    mov bx, 0x1000          
    call disk_load
    mov bx, MSG_YESNO
    call print_string

    call get_yes_no

    mov bx, MSG_BOOT_KERNEL
    call print_string

    xor ah,ah
    mov al,13h
    int 0x10

    lgdt [gdt_descriptor]

    cli

    mov eax , cr0 ; To make the switch to protected mode , we set
    or eax , 0x1 ; the first bit of CR0 , a control register
    mov cr0 , eax ; Update the control register

    jmp CODE_SEG:pm


; Alt fonksiyonlar
;******************************************************************
print_string:       

.loop:
    mov al,[bx]
    cmp al,0
    je return
    push bx
    mov ah,0Eh

    int 10h
    pop bx
    inc bx
    jmp .loop

return:
    ret 

;******************************************************************
get_yes_no:
    pusha 
.loop:
    mov ah, 00h
    int 16h
    cmp ah, 15h
    je .yes
    cmp ah, 31h
    je .no
    jmp .loop
    ret
.no:
    mov bx, No
    call print_string
    mov ah, 00h
    int 13h 
    jmp $
.yes:   
    mov bx, Yes
    call print_string
    jmp .done
.done:
    popa
    ret 
;******************************************************************
disk_load:
    push dx
    mov ah, 02h    
    mov al, dh    
    mov ch, 0x00   
    mov dh, 0x00  
    ;mov cl, 0x02   
    int 0x13     
    pop dx
    jc disk_error 
    cmp dh, al 
    jne disk_error_double
    mov bx,MSG_LOAD_SUCC
    call print_string
    ret 

disk_error:
    mov bx,MSG_LOAD_FAIL 
    call print_string
    jmp $
disk_error_double:
    mov bx,MSG_LOAD_FAIL_C
    call print_string
    jmp $




BITS 32

    pm:


    mov ax , DATA_SEG ; Now in PM , our old segments are meaningless ,
    mov ds , ax 
    mov ss , ax 
    mov es , ax
    mov fs , ax
    mov gs , ax

    mov ebp , 0x90000 
    mov esp , ebp

    call KERNEL_OFFSET

    jmp $   

;******************************************************************
print_string_pm :
    pusha
    mov edx , VIDEO_MEMORY ; Set edx to the start of vid mem.
    .print_string_pm_loop :
    mov al , [ ebx ] ; Store the char at EBX in AL
    mov ah , WHITE_ON_BLACK ; Store the attributes in AH
    cmp al , 0 ; if (al == 0), at end of string , so
    je .print_string_pm_done ; jump to done
    mov [edx], ax ; Store char and attributes at current
    ; character cell.
    add ebx , 1 ; Increment EBX to the next char in string.
    add edx , 2 ; Move to next character cell in vid mem.
    jmp .print_string_pm_loop ; loop around to print the next char.
    .print_string_pm_done :
    popa
    ret 

; Global Descriptor table
; GDT
gdt_start :
gdt_null : ; the mandatory null descriptor
dd 0x0 ; 'dd ' means define double word ( i.e. 4 bytes )
dd 0x0
gdt_code : 
dw 0xffff ; Limit ( bits 0 -15)
dw 0x0 ; Base ( bits 0 -15)
db 0x0 ; Base ( bits 16 -23)
db 10011010b ; 1st flags , type flags
db 11001111b ; 2nd flags , Limit ( bits 16 -19)
db 0x0 ; Base ( bits 24 -31)
gdt_data : 
dw 0xffff ; Limit ( bits 0 -15)
dw 0x0 ; Base ( bits 0 -15)
db 0x0 ; Base ( bits 16 -23)
db 10010010b ; 1st flags , type flags
db 11001111b ; 2nd flags , Limit ( bits 16 -19)
db 0x0 ; Base ( bits 24 -31)
gdt_end : 

gdt_descriptor :
dw gdt_end - gdt_start - 1 
dd gdt_start 

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start   



; Değişkenler

MSG_START DB ">",13,10,0
MSG_LOAD_SUCC DB "> Succesfully loaded",13,10,0
MSG_LOAD_FAIL DB "> Failed to load Please try to restart the system",13,10,0
MSG_LOAD_FAIL_C DB "> Error while loading",13,10,0
MSG_YESNO DB "> Do you want to boot up in kernel mode Y/N :",0
MSG_BOOT_KERNEL DB 13,10,"> Booting in kernel mode",0
MSG_BOOT_32 DB "32 bit pm",13,10,0
Yes db "Y",0
No db "N",0
bootdev: db 0
KERNEL_OFFSET equ 0x1000 
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f

times 510-($-$$) db 0
dw 0xaa55

IO.h:

#ifndef __IO_H
#define __IO_H


    unsigned char inb ( unsigned short port ) {
    unsigned char result ;
    __asm__ (" in %%dx , %%al " : "=a" ( result ) : "d" ( port ));
    return result ;
    }


    void outb ( unsigned short port , unsigned char data ) {

        __asm__ (" out %%al , %%dx " : :"a" ( data ), "d" ( port ));
    }
    unsigned short inw ( unsigned short port ) {
    unsigned short result ;
        __asm__ (" in %%dx , %%ax " : "=a" ( result ) : "d" ( port ));
        return result ;
    }
    void outw ( unsigned short port , unsigned short data ) {
        __asm__ (" out %%ax , %%dx " : :"a" ( data ), "d" ( port ));
    }
#endif

这是我的makefile

OS:
    nasm -fbin bootload.asm -o bootload.bin
    gcc -ffreestanding -c kernel.c -o kernel.o
    nasm kernel_entry.asm -f elf -o k_entry.o
    ld -T NUL -o kernel.tmp -Ttext 0x1000 k_entry.o kernel.o
    objcopy -O binary -j .text  kernel.tmp kernel.bin
    copy /b bootload.bin+kernel.bin os-image.bin 
    qemu-system-i386 -monitor stdio os-image.bin 
clean:
    del *.o
    del *.temp
    del *.bin

当我用-v运行它时,它给出了

    Using built-in specs.
COLLECT_GCC=gcc
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-sjlj-exceptions --with-dwarf2 --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/i686-w64-mingw32-static --with-pkgversion='i686-win32-dwarf-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/include -I/c/mingw810/prerequisites/i686-zlib-static/include -I/c/mingw810/prerequisites/i686-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/opt/lib -L/c/mingw810/prerequisites/i686-zlib-static/lib -L/c/mingw810/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware'
Thread model: win32
gcc version 8.1.0 (i686-win32-dwarf-rev0, Built by MinGW-W64 project)
COLLECT_GCC_OPTIONS='-v' '-Os' '-fno-PIC' '-m32' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=generic' '-march=i686'
 D:/MinGw1/mingw32/bin/../libexec/gcc/i686-w64-mingw32/8.1.0/cc1.exe -quiet -v -iprefix D:/MinGw1/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/ -U_REENTRANT kernel.c -quiet -dumpbase kernel.c -m32 -mtune=generic -march=i686 -auxbase-strip kernel.o -Os -version -fno-PIC -ffreestanding -o C:\Users\Z2123~1\AppData\Local\Temp\cc2jKvGE.s
GNU C17 (i686-win32-dwarf-rev0, Built by MinGW-W64 project) version 8.1.0 (i686-w64-mingw32)
        compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "D:/MinGw1/mingw32/lib/gcc/../../lib/gcc/i686-w64-mingw32/8.1.0/include"
ignoring nonexistent directory "C:/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32C:/msys64/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/../../../../include"
ignoring duplicate directory "D:/MinGw1/mingw32/lib/gcc/../../lib/gcc/i686-w64-mingw32/8.1.0/include-fixed"
ignoring duplicate directory "D:/MinGw1/mingw32/lib/gcc/../../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/include"
ignoring nonexistent directory "C:/mingw810/i686-810-win32-dwarf-rt_v6-rev0/mingw32/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
 D:/MinGw1/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/include
 D:/MinGw1/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/include-fixed
 D:/MinGw1/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/include
End of search list.
GNU C17 (i686-win32-dwarf-rev0, Built by MinGW-W64 project) version 8.1.0 (i686-w64-mingw32)
        compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 283040c7d21de7e7c3c642876453fb1b
In file included from kernel.c:1:
TaraOS.h: In function 'MapScancodeToAscii':
TaraOS.h:28:13: warning: multi-character character constant [-Wmultichar]
             '   ',
             ^~~~~
TaraOS.h:28:13: warning: unsigned conversion from 'int' to 'unsigned char' changes value from '2105376' to '32' [-Woverflow]
TaraOS.h: In function 'set_background':
TaraOS.h:121:19: warning: passing argument 1 of 'fill_rect' makes pointer from integer without a cast [-Wint-conversion]
         fill_rect((int)vm,0,320,0,200,color);
                   ^~~~~~~
In file included from TaraOS.h:5,
                 from kernel.c:1:
screen.h:22:35: note: expected 'unsigned char *' but argument is of type 'int'
     void fill_rect(unsigned char* screen, int fromx, int tox, int fromy,int toy,int color)
                    ~~~~~~~~~~~~~~~^~~~~~
COLLECT_GCC_OPTIONS='-v' '-Os' '-fno-PIC' '-m32' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=generic' '-march=i686'
 D:/MinGw1/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/as.exe -v --32 -o kernel.o C:\Users\Z2123~1\AppData\Local\Temp\cc2jKvGE.s
GNU assembler version 2.30 (i686-w64-mingw32) using BFD version (GNU Binutils) 2.30

,然后再次输入相同的错误代码

0 个答案:

没有答案