Модификация idt в модуле ядра.

Тема в разделе "WASM.UNIX", создана пользователем int_0x80, 11 июл 2006.

  1. int_0x80

    int_0x80 New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    25
    Хочу написать модуль ядра который бы при загрузке ствил бы свой обравотчик Int 1.
    есть такой код:
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    asmlinkage void handler(void) {
    printk("<1>Int1\n");
    }
    void set_handler(void * addr) {
    struct idt {
    long a;
    int b;
    };
    struct idt idt_table;
    __asm__ __volatile__ ("movl %%eax,%%eax\n" \
    "sidt %0\n" \
    "movl 2%0,%%ebx\n" \
    "addl $8,%%ebx\n" \
    "movl %1,%%eax\n" \
    "movw %%ax,(%%ebx)\n" \
    "shr $16,%%eax\n" \
    "movw %%ax,6(%%ebx)\n" \
    :
    :"m"(idt_table),
    "m"(addr)
    );


    }
    static int hello_init(void) {
    printk("<1>1\n");
    set_handler(handler);
    asm ("intw 1");
    return 0;
    }

    static void hello_exit(void) {
    printk("<1>2\n");
    }

    module_init(hello_init);
    module_exit(hello_exit);
    При загрузке появляются вот такие сообщения:
    1
    Trying to vfree() bad address (00600280)
    Badness in __vunmap at mm/vmalloc.c:308
    [<c0143751>]
    [<c012ee5a>]
    [<c01029b9>]
    Что я неправильно делаю?
     
  2. int_0dh

    int_0dh New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    1) вы неправильно объявили структуру idt - надо так typedef struct {
    unsigned short idt_len;
    unsigned long idt_base;
    } __attribute__ ((packed)) idt_t;
    2) по-моему вы неразобрались с тем, что там должно находится в защищенном режиме
    3) после того как вы модифицируете такую важную структуру как idt вы просто обязаны сбросить data cache
    4) кто вам сказал, что страница , на которой располагается idt вообще должна быть доступна для записи?
     
  3. int_0dh

    int_0dh New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    ещё одно замечание: зачем для установки шлюза прерывания использовать gcc black assembly magic?
     
  4. int_0x80

    int_0x80 New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    25
    А разве можно установить шлюз прерывания без асемблера?
     
  5. int_0dh

    int_0dh New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    естественно можно - ведь это сводится только к записи в idt (фактически в какую-то область памяти)
     
  6. int_0x80

    int_0x80 New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    25
    Но чтобы получить адрес idt нужно применить асемблер а точнее команду sidt.Или я не прав?
     
  7. int_0dh

    int_0dh New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    именно. одна команда sidt, потом все можно писать на чистом С.под black assembly magic подразумевалось то, что вы написали в set_handler()
     
  8. int_0dh

    int_0dh New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    если для вас это еще актуально, то вот пример модуля ядра, который это делает:

    #define __KERNEL__
    #define MODULE

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/mm.h>

    void
    int01_handler()
    {
    printk("int 01 called!\n");
    }

    typedef
    struct
    {
    unsigned short idt_len;
    unsigned long idt_base;
    } __attribute__((packed)) idt_t;

    typedef
    struct
    {
    unsigned long data;
    unsigned long data1;
    } __attribute__ ((packed)) trapgate_t;


    int init_module()
    {
    idt_t idt;
    asm("sidt %0"::"m" (idt));
    printk("idt base at 0x%08x\n", idt.idt_base);

    trapgate_t *traps = (trapgate_t *)idt.idt_base;
    traps++;

    trapgate_t trap;
    trap.data = (__KERNEL_CS << 16) | ((unsigned long)int01_handler & 0xffff);
    trap.data1 = ((unsigned long)int01_handler & 0xffff0000) | 0x8f00;

    *traps = trap;
    printk("called int1...\n");

    asm("int $0x1");
    return 0;
    }

    void cleanup_module()
    {
    }