#include #include #include #include #include static char hello_world[]="Hello World\n"; static dev_t hello_dev_number; static struct cdev *driver_object; static struct class *hello_class; static struct device *hello_dev; static ssize_t driver_read(struct file *instanz,char __user *user, size_t count, loff_t *offset ) { unsigned long not_copied, to_copy; to_copy = min( count, strlen(hello_world)+1 ); not_copied=copy_to_user(user,hello_world,to_copy); return to_copy-not_copied; } static struct file_operations fops = { .owner= THIS_MODULE, .read= driver_read, }; static int __init mod_init( void ) { if( alloc_chrdev_region(&hello_dev_number,0,1,"Hello")<0 ) return -EIO; driver_object = cdev_alloc(); /* Anmeldeobjekt reserv. */ if( driver_object==NULL ) goto free_device_number; driver_object->owner = THIS_MODULE; driver_object->ops = &fops; if( cdev_add(driver_object,hello_dev_number,1) ) goto free_cdev; /* Eintrag im Sysfs, damit Udev die Geraetedatei erzeugt */ hello_class = class_create( THIS_MODULE, "Hello" ); if( IS_ERR( hello_class ) ) { pr_err( "hello: no udev support\n"); goto free_cdev; } hello_dev = device_create(hello_class,NULL,hello_dev_number, NULL, "%s", "hello" ); dev_info( hello_dev, "mod_init called\n" ); return 0; free_cdev: kobject_put( &driver_object->kobj ); free_device_number: unregister_chrdev_region( hello_dev_number, 1 ); return -EIO; } static void __exit mod_exit( void ) { dev_info( hello_dev, "mod_exit called\n" ); /* Loeschen des Sysfs-Eintrags und damit der Geraetedatei */ device_destroy( hello_class, hello_dev_number ); class_destroy( hello_class ); /* Abmelden des Treibers */ cdev_del( driver_object ); unregister_chrdev_region( hello_dev_number, 1 ); return; } module_init( mod_init ); module_exit( mod_exit ); MODULE_LICENSE("GPL");