//------------------------------------------------------------------- // mch.c // // This Linux kernel module creates a '/proc' interface to the // PCI Configuration Space Header for the system's Host-to-PCI // Memory Controller Hub. (We are interested in studying this // because of its role in enabling access to System Management // Ram where an SMI interrupt-handler would be resident.) Our // custom 'Makefile' is recommended for compiling this module: // // compile using: $ make mch.o // install using: $ /sbin/insmod mch.o // execute using: $ cat /proc/mch // removed using: $ /sbin/rmmod mch // // NOTE: Developed and tested with Linux kernel version 2.4.21. // // programmer: ALLAN CRUSE // written on: 12 MAY 2004 //------------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include // for pci_find_class() #include // for create_proc_read_entry() #define SUCCESS 0 #define HUB_CLASS 0x060000 static char modname[] = "mch"; struct pci_dev *devp = NULL; static int my_proc_read( char *buf, char **start, off_t off, int count, int *eof, void *data ) { u32 datum; int i, len = 0; len += sprintf( buf+len, "\n%s -- ", devp->name ); len += sprintf( buf+len, "PCI Configuration Header \n" ); for (i = 0; i < 256; i+=4) { if ( ( i % 32 ) == 0 ) len += sprintf( buf+len, "\n%02X: ", i ); pci_read_config_dword( devp, i, &datum ); len += sprintf( buf+len, "%08X ", datum ); } len += sprintf( buf+len, "\n\n" ); *eof = 1; return len; } int init_module( void ) { printk( "<1>\nInstalling \'%s\' module\n", modname ); devp = pci_find_class( HUB_CLASS, devp ); if ( !devp ) return -ENODEV; printk( "<1> %s \n", devp->name ); create_proc_read_entry( modname, 0, NULL, my_proc_read, NULL ); return SUCCESS; } void cleanup_module( void ) { printk( "<1>Removing \'%s\' module\n", modname ); remove_proc_entry( modname, NULL ); } MODULE_LICENSE("GPL");