//------------------------------------------------------------------- // showpdir.cpp // // This application uses a pair of installable kernel modules, // named 'cr3.c' and 'dram.c', to obtain the value in register // CR3, and then use it to read in this task's page-directory. // The address and contents of the page-directory are shown in // hexadecimal format (the number of page-tables being used by // this task is also shown). // // Note that 'root' privileges are normally needed, to install // kernel modules or to create device-nodes, like this: // // root# /bin/mknod /dev/dram c 253 0 // root# /sbin/insmod dram.o // root# /sbin/insmod cr3.o // // NOTE: Written and tested using Linux kernel version 2.4.21. // // programmer: ALLAN CRUSE // written on: 21 APR 2004 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), close() char devname[] = "/dev/dram"; // name of the 'device' file char filname[] = "/proc/cr3"; // name of /proc pseudo-file int main( int argc, char **argv ) { // install device-driver modules in the kernel system( "/sbin/insmod dram.o" ); system( "/sbin/insmod cr3.o" ); // get physical address of this task's page-directory int fd = open( filname, O_RDONLY ); char inbuf[ 20 ] = ""; if ( read( fd, inbuf, 16 ) < 12 ) { perror( filname ); exit(1); } unsigned long cr3 = strtol( inbuf+4, 0, 16 ) & 0xFFFFF000; close( fd ); // report physical address of the page-directory printf( "\npage-directory at %08X \n", cr3 ); // open device file for reading from physical memory fd = open( devname, O_RDONLY ); if ( fd < 0 ) { perror( devname ); exit(1);} // read this task's page-directory unsigned long pgdir[ 1024 ]; lseek( fd, cr3, SEEK_SET ); if ( read( fd, pgdir, 4096 ) < 4096 ) { perror( devname ); exit(1); } close( fd ); // display the page-directory entries for (int i = 0; i < 1024; i++) { if ( ( i % 8 ) == 0 ) printf( "\n%03X: ", i*4 ); printf( "%08X ", pgdir[ i ] ); } printf( "\n" ); // count the number of 4KB pages which are 'present' int present = 0; for (int i = 0; i < 1024; i++) if ( ( pgdir[ i ] & 0x101 ) == 0x001 ) ++present; printf( "\nNumber of page-tables = %d \n", present ); printf( "\n" ); }