//------------------------------------------------------------------- // pgdir.c // // This module implements a 'visualization' of the 4GB virtual // address space under Linux, based on page-directory entries. // The data-granularity depicted is 4MB. Frames which are not // presently 'mapped' are shown by '-', while frames which are // mapped are marked by a character ('3' or '7') based on bits // from the page-directory entry. // // Usage: Compile and install the module object-file, // then execute the shell-command: $ cat /proc/pgdir // // NOTE: Written and tested using Linux kernel version 2.4.20. // // programmer: ALLAN CRUSE // written on: 16 FEB 2003 //------------------------------------------------------------------- #define __KERNEL__ #define MODULE #include // for init_module() #include // for create_proc_read_entry() #include // for phys_to_virt() #define SUCCESS 0 static char modname[] = "pgdir"; static int my_proc_read( char *buf, char **start, off_t off, int count, int *eof, void *data ); int init_module( void ) { printk( "<1>\nInstalling \'%s\' module\n", modname ); create_proc_read_entry( modname, 0, NULL, my_proc_read, NULL ); return SUCCESS; } void cleanup_module( void ) { remove_proc_entry( modname, NULL ); printk( "<1>Removing \'%s\' module\n", modname ); } MODULE_LICENSE("GPL"); static int my_proc_read( char *buf, char **start, off_t off, int count, int *eof, void *data ) { unsigned long ptdb, *pgdir; int i, k, len; // inline assembly-language is used to access register CR3 asm(" movl %%cr3, %%eax \n movl %%eax, %0 " : "=m" (ptdb) ); pgdir = (unsigned long *)phys_to_virt( ptdb ); // title for the visualization len = 0; len += sprintf( buf+len, "\n\n " ); len += sprintf( buf+len, "A \'scientific visualization\' for the " ); len += sprintf( buf+len, "IA-32 Virtual Address Space under Linux\n" ); // loop through page-directory entries (from highest to lowest) for (i = 0; i < 1024; i++) { int k = 1023- i; unsigned char attr = (pgdir[ k ]&7) | '0'; if ( !(attr&1) ) attr = '-'; if ( ( i % 64 ) == 0 ) len += sprintf( buf+len, "\n " ); len += sprintf( buf+len, "%c", attr ); if ( ( i % 64 ) == 63 ) len += sprintf( buf+len, " %08X", k<<22 ); } // display explanatory legend (plus some extra info) len += sprintf( buf+len, "\n\n\n Legend: " ); len += sprintf( buf+len, " \'-\'=unmapped " ); len += sprintf( buf+len, " \'3\'=supervisor " ); len += sprintf( buf+len, " \'7\'=user " ); len += sprintf( buf+len, " (CR3=%08X) ", ptdb ); len += sprintf( buf+len, "\n\n" ); *eof = 1; return len; }