Results 1 to 1 of 1
I created this method for testing/experimenting with a kernel on a 32 bit Intel/AMD system. The programs can easily be port to a 64 bit Intel/AMD processor with some reference ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 01-21-2010 #1
Creating a Test Interrupt for a Intel/AMD 32 bit processor
I created this method for testing/experimenting with a kernel on a 32 bit Intel/AMD system. The programs can easily be port to a 64 bit Intel/AMD processor with some reference to the Intel/AMD manuals..I actually have it here somewhere if you really need it.
Please Note - This is a hack that will only work on a 32 bit Intel/AMD system, paying special attention to the lines "don't need this line for some compilers/systems - i.e slackware 13.0"
So what does the module and program do?
The module basically sets up an interrupt "0x81" and a simple handler so that the programmer can interact with the kernel in a free and controlled way by calling the interrupt and executing the handler.
I know, not much of an example, its basic allowing the programmer to pass the address of a variable into the kernel an then set it to 99999 but this implementation can be expanded to cover a whole host of interests.
test1.c - The Kernel Module
testit.c - The test user space executableCode:#include <linux/kernel.h> #include <linux/module.h> struct id//interrupt description table { unsigned short limit; void *base; }__attribute__((packed)) myidtr; struct intgate//interrupt gate struct { unsigned short off1; unsigned short sel; unsigned short none; unsigned short off2; }__attribute__((packed)) *idttr1, *idttr2, orig, orig2; unsigned int myint = 99999;//value to set user variable to void myfunc(void)//our simple handler { __asm__ ( "movl %ebp, %esp\n\t"//don't need this line for some compilers/systems - i.e slackware 13.0 "popl %ebp\n\t"//don't need this line for some compilers/systems - i.e slackware 13.0 "pushl %eax\n\t" "pushl %ebx\n\t" "movl myint, %ebx\n\t" "movl %ebx, (%eax)\n\t" "popl %ebx\n\t" "popl %eax\n\t" "iret\n\t" ); } union myaddr { void *addr; struct { unsigned short a; unsigned short b; }__attribute__((packed)) iaddr; }__attribute__((packed)) theaddr; int init_module() { __asm__ ("sidt myidtr\n\t"); idttr1 = (struct intgate*)(myidtr.base + (128 * 8));//interrupt 0x80 idttr2 = (struct intgate*)(myidtr.base + (129 * 8));//interrupt 0x81 orig2 = *idttr2; *idttr2 = *idttr1;//short cut - set 0x81 interrupt equal to interrupt 0x08 theaddr.addr = (void*)myfunc;//interrupt handler idttr2->off1 = theaddr.iaddr.a;//set myfunc to 0x81 handler idttr2->off2 = theaddr.iaddr.b;//set myfunc to 0x81 handler return 0; } void cleanup_module() { *idttr2 = orig2; printk("setting everything back...we're out of here!\n"); }
Note - this is from months of reading the AMD/Intel manuals...I thought I would save you the pleasure of that task..Code:#include <stdio.h> #include <stdlib.h> unsigned int testval = 0; int main(int argc, char**argv) { fprintf(stdout, "initial testval->%d\n", testval); __asm__ ( "movl $testval, %eax\n\t" "int $0x81\n\t" ); fprintf(stdout, "final testval->%d\n", testval); exit(EXIT_SUCCESS); }Make mine Arch Linux


Reply With Quote
