#define __KERNEL__ #define MODULE #include #include #include #include #include #include #if CONFIG_DEVFS_FS # include #endif #define DEVICE_NAME "hellodev" #define DEVICE_MAJOR 123 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Fredrik Roubert"); MODULE_DESCRIPTION("Hello, world!"); MODULE_SUPPORTED_DEVICE(DEVICE_NAME); #define PRINTK(...) printk(KERN_INFO DEVICE_NAME ": " __VA_ARGS__) static const char msg[] = "Hello, world!\n"; #if CONFIG_DEVFS_FS static devfs_handle_t devfs_handle; #endif static ssize_t hellodev_read(struct file *, char *, size_t, loff_t *); static int hellodev_open(struct inode *, struct file *); static int hellodev_release(struct inode *, struct file *); static struct file_operations fops = { .read = hellodev_read, .open = hellodev_open, .release = hellodev_release }; static ssize_t hellodev_read(struct file *filp, char *buf, size_t len, loff_t *off) { loff_t i = *off; size_t j = 0; while (j < len && msg[i] != '\0') put_user(msg[i ++], &buf[j ++]); *off = i; return j; } static int hellodev_open(struct inode *inop, struct file *filp) { MOD_INC_USE_COUNT; return 0; } static int hellodev_release(struct inode *inop, struct file *filp) { MOD_DEC_USE_COUNT; return 0; } static int __init hellodev_init(void) { PRINTK("Initializing ...\n"); #if CONFIG_DEVFS_FS if ((devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, DEVICE_MAJOR, 0, S_IFCHR | S_IRUGO, &fops, NULL)) == NULL) { PRINTK("devfs_register() failed.\n"); return -EIO; } #else int s; if ((s = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &fops)) < 0) { PRINTK("register_chrdev() failed, error code %d.\n", s); return s; } #endif PRINTK("Initialized.\n"); return 0; } static void __exit hellodev_exit(void) { #if CONFIG_DEVFS_FS devfs_unregister(devfs_handle); #else int s; if ((s = unregister_chrdev(DEVICE_MAJOR, DEVICE_NAME)) < 0) PRINTK("unregister_chrdev() failed, error code %d.\n", s); #endif PRINTK("Unloaded.\n"); } module_init(hellodev_init); module_exit(hellodev_exit);