//------------------------------------------------------------------- // gdt.c (Global Descriptor Table) // // This is a Linux character-mode device-driver which allows // user-level programs to read the processor's GDT as though // it were a 'read-only' file, once the required device-node // has been created by a System Administrator: // // root# /sbin/mknod /dev/gdt c 98 0 // // NOTE: Written and tested with Linux kernel version 2.4.20 // // programmer: ALLAN CRUSE // written on: 14 APR 2003 //------------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include // for copy_to_user() static char modname[] = "gdt"; static int my_major = 98; static long gdtsize; static char *gdtbase; static ssize_t my_read( struct file *file, char *buf, size_t count, loff_t *pos ) { char *from = gdtbase + *pos; if ( *pos >= gdtsize ) return 0; if ( *pos + count > gdtsize ) count = gdtsize - *pos; if ( copy_to_user( buf, from, count ) ) return -EFAULT; *pos += count; return count; } static loff_t my_seek( struct file *file, loff_t offset, int whence ) { loff_t newpos; switch( whence ) { case 0: newpos = offset; break; // SEEK_SET case 1: newpos = file->f_pos + offset; break; // SEEK_CUR case 2: newpos = gdtsize + offset; break; // SEEK_END default: return -EINVAL; // this should never occur } if ( newpos < 0 ) return -EINVAL; file->f_pos = newpos; return newpos; } static struct file_operations my_fops = { owner: THIS_MODULE, read: my_read, llseek: my_seek, }; int init_module( void ) { unsigned short gdtr[3]; // initialize device-driver's global variables asm(" sgdt %0 " : "=m" (gdtr) ); gdtsize = 1 + gdtr[0]; gdtbase = (char *)(*(unsigned long *)(gdtr+1)); // register this device-driver with the kernel return register_chrdev( my_major, modname, &my_fops ); } void cleanup_module( void ) { unregister_chrdev( my_major, modname ); } MODULE_LICENSE("GPL");