/* Appropriate Kernel header files */ #include #include #include #include #include #include #include #include #include #include #include /* Defaults */ #define DEFAULT_MAJOR 168 #define DEFAULT_NAME "memtest" /* Parameters that can be set by insmod */ static int major = DEFAULT_MAJOR; static char* name = DEFAULT_NAME; #define uint unsigned int /* Function Prototypes */ ssize_t memtest_read (struct file *, char *, size_t, loff_t *); ssize_t memtest_write (struct file *, const char *, size_t, loff_t *); int memtest_ioctl(struct inode *, struct file *, unsigned int, unsigned long); int memtest_open (struct inode *, struct file *); int memtest_release (struct inode *, struct file *); MODULE_AUTHOR("Siva Prasad."); MODULE_DESCRIPTION("This a a very simple memory test module"); MODULE_LICENSE("GPL"); /* * This must be made static since it is use after the current * function returns. It holds the methods used by the driver. */ #define NUMMINORS 5 static struct file_operations memtest_fops = { .read = memtest_read, .write = memtest_write, .ioctl = memtest_ioctl, .open = memtest_open, .release = memtest_release, .owner = THIS_MODULE, }; static dev_t memtestdev; static struct cdev *memtest_cdev; #define K(x) ((x) << (PAGE_SHIFT - 10)) #define PAGEFACTOR 32 /* * my_init_module() * * First function called when loaded with insmod. This registers the * char driver handler. * * Returns 0 if successfull, non-zero on failure */ int my_init_module(void) { unsigned long total_memory, free_memory, page_size; unsigned long testable_memory, testable_pages; struct sysinfo meminformation; int retval; /* Load character driver */ memtest_cdev = cdev_alloc(); memtestdev = MKDEV(major,0); retval = register_chrdev_region(memtestdev,NUMMINORS,name); /* Fail to load if register_chardriver fails */ if (retval < 0) return retval; /* If major = 0, it if auto-allocated */ if (!major) major = retval; printk(KERN_EMERG "Memtest module registered with major = %d\n",major); memtest_cdev->ops = &memtest_fops; memtest_cdev->owner = THIS_MODULE; retval = cdev_add(memtest_cdev,memtestdev,NUMMINORS); si_meminfo(&meminformation); total_memory = K(meminformation.totalram); // in Kbytes total_memory *= 1024; // Regular bytes free_memory = K(meminformation.freeram); free_memory *= 1024; page_size = PAGE_SIZE * PAGEFACTOR; printk(KERN_EMERG "System Information...\n"); printk(KERN_EMERG "Total Memory = %uK.\n", (uint)(total_memory/1024)); printk(KERN_EMERG "Free Memory = %uK.\n", (uint)(free_memory/1024)); printk(KERN_EMERG "Test Page Size = %08X.\n", (uint)page_size); testable_memory = (free_memory/100)*50; testable_pages = testable_memory / (page_size); return retval; } /* * my_cleanup_module() * * Called when module is removed by insmod. */ void my_cleanup_module(void) { printk(KERN_EMERG "memtest Cleaning up the module.\n"); cdev_del(memtest_cdev); /* Unregister character driver. */ unregister_chrdev_region(memtestdev,NUMMINORS); } // * Returns number of bytes read ssize_t memtest_read (struct file *filp, char *buf, size_t nbytes, loff_t* ppos) { int tr; char stringpass[] = "Dude, here is the info from kernel to user"; printk(KERN_EMERG "memtest READ.\n"); tr = 80; tr = tr - copy_to_user(buf, stringpass, tr); return tr; } // * Returns the number of bytes written ssize_t memtest_write (struct file *filp, const char *buf, size_t nbytes, loff_t* ppos) { printk(KERN_EMERG "memtest WRITE: %d bytes\n",(int)nbytes); if (!nbytes) return 0; return nbytes; } // * Returns 0 for success int memtest_ioctl(struct inode *inode , struct file * filp, unsigned int cmd, unsigned long arg) { printk(KERN_EMERG "memtest IOCTL: cmd = %d\n",cmd); // Just return, as there is nothing to do in open. return -ENOTTY; } // * Returns 0 on success, non-zero on error int memtest_open (struct inode * inode, struct file * filp) { unsigned int minor = MINOR(inode->i_rdev); printk(KERN_EMERG "memtest OPEN: Major=%d Minor=%d Mode=%08x\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev),filp->f_mode); if (minor >3 ) return -ENXIO; // Just return, as there is nothing to do in open. return 0; } // * Returns 0 on success, non-zero on error int memtest_release (struct inode *inode, struct file * filp) { printk(KERN_EMERG "memtest RELEASED:\n"); // Just return, as there is nothing to do in release. return 0; } module_init(my_init_module); module_exit(my_cleanup_module);