Хочу написать модуль ядра который бы при загрузке ствил бы свой обравотчик 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>] Что я неправильно делаю?
1) вы неправильно объявили структуру idt - надо так typedef struct { unsigned short idt_len; unsigned long idt_base; } __attribute__ ((packed)) idt_t; 2) по-моему вы неразобрались с тем, что там должно находится в защищенном режиме 3) после того как вы модифицируете такую важную структуру как idt вы просто обязаны сбросить data cache 4) кто вам сказал, что страница , на которой располагается idt вообще должна быть доступна для записи?
именно. одна команда sidt, потом все можно писать на чистом С.под black assembly magic подразумевалось то, что вы написали в set_handler()
если для вас это еще актуально, то вот пример модуля ядра, который это делает: #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() { }