//------------------------------------------------------------------- // smiload.cpp // // This program loads copies of a SMI interrupt service routine // into prescribed locations in the System Management Memory on // our classroom workstations, relying on functions provided by // our 'smram.c' device-driver which must already be installed. // The name of the file containing the ISR in binary executable // format is supplied as a command-line argument. Students may // then use our 'issuesmi.cpp' application-program to trigger a // System Management Interrupt, and thereby execute those ISRs. // // to compile: $ g++ smiload.cpp -o smiload // to execute: $ ./smiload // // // NOTE: The system manufacturer's SMI handlers get overwritten // by this action, and thus they cease to function until a user // reboots the machine. Students should not neglect to perform // a 'cold' reboot when they have finished any experiments they // undertake using this application. (This code is specific to // the system configuration of our classroom's workstations for // Fall 2008, and must NOT be executed on any outside machines; // it is created solely for our CS 630 "in-class" experiments.) // // NOTE: The four SMI entry-points (hardcoded below) were found // by using our 'smlayout.cpp' development utility. // // programmer: ALLAN CRUSE // written on: 09 DEC 2008 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #define MAX_INPUT 4096 #define SMIENTRY0 0x000F8000 #define SMIENTRY1 0x000E8000 #define SMIENTRY2 0x000D8000 #define SMIENTRY3 0x000C8000 char devname[] = "/dev/smram"; int main( int argc, char **argv ) { // check for the required command-line argument if ( argc == 1 ) { fprintf( stderr, "No input-file\n" ); exit(1); } // open the specified input-file for reading int fi = open( argv[1], O_RDONLY ); if ( fi < 0 ) { perror( argv[1] ); exit(1); } // obtain the input-file's size int filesize = lseek( fi, 0, SEEK_END ); printf( "\n\'%s\': filesize = 0x%X \n", argv[1], filesize ); if ( filesize > MAX_INPUT ) { fprintf( stderr, "input-file too large\n" ); exit(1); } // read the contents of the input-file char inbuff[ MAX_INPUT ] = {0}; lseek( fi, 0, SEEK_SET ); if ( read( fi, inbuff, sizeof( inbuff ) ) < 0 ) { perror( "read" ); exit(1); } // open the device-file for reading and writing int fo = open( devname, O_RDWR ); if ( fo < 0 ) { perror( devname ); exit(1); } //--------------------------------------------- // install copies of the SMI interrupt-handler //--------------------------------------------- lseek( fo, SMIENTRY0, SEEK_SET ); if ( write( fo, inbuff, filesize ) < 0 ) { perror( "write" ); exit(1); } lseek( fo, SMIENTRY1, SEEK_SET ); if ( write( fo, inbuff, filesize ) < 0 ) { perror( "write" ); exit(1); } lseek( fo, SMIENTRY2, SEEK_SET ); if ( write( fo, inbuff, filesize ) < 0 ) { perror( "write" ); exit(1); } lseek( fo, SMIENTRY3, SEEK_SET ); if ( write( fo, inbuff, filesize ) < 0 ) { perror( "write" ); exit(1); } close( fo ); }