├── Makefile ├── README.md ├── device_file.c ├── device_file.h └── main.c /Makefile: -------------------------------------------------------------------------------- 1 | TARGET_MODULE:=simple-module 2 | 3 | # If we running by kernel building system 4 | ifneq ($(KERNELRELEASE),) 5 | $(TARGET_MODULE)-objs := main.o device_file.o 6 | obj-m := $(TARGET_MODULE).o 7 | 8 | # If we are running without kernel build system 9 | else 10 | BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build 11 | PWD:=$(shell pwd) 12 | 13 | 14 | all : 15 | # run kernel build system to make module 16 | $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules 17 | 18 | clean: 19 | # run kernel build system to cleanup in current directory 20 | $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) clean 21 | 22 | load: 23 | insmod ./$(TARGET_MODULE).ko 24 | 25 | unload: 26 | rmmod ./$(TARGET_MODULE).ko 27 | 28 | endif 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Linux Driver 2 | Simple Linux driver 3 | -------------------------------------------------------------------------------- /device_file.c: -------------------------------------------------------------------------------- 1 | #include "device_file.h" 2 | #include /* file stuff */ 3 | #include /* printk() */ 4 | #include /* error codes */ 5 | #include /* THIS_MODULE */ 6 | #include /* char device stuff */ 7 | #include /* copy_to_user() */ 8 | 9 | static const char g_s_Hello_World_string[] = "Hello world from kernel mode!\n\0"; 10 | static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string); 11 | 12 | /*===============================================================================================*/ 13 | static ssize_t device_file_read( 14 | struct file *file_ptr 15 | , char __user *user_buffer 16 | , size_t count 17 | , loff_t *possition) 18 | { 19 | printk( KERN_NOTICE "Simple-driver: Device file is read at offset = %i, read bytes count = %u\n" 20 | , (int)*possition 21 | , (unsigned int)count ); 22 | 23 | if( *possition >= g_s_Hello_World_size ) 24 | return 0; 25 | 26 | if( *possition + count > g_s_Hello_World_size ) 27 | count = g_s_Hello_World_size - *possition; 28 | 29 | if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition, count) != 0 ) 30 | return -EFAULT; 31 | 32 | *possition += count; 33 | return count; 34 | } 35 | 36 | /*===============================================================================================*/ 37 | static struct file_operations simple_driver_fops = 38 | { 39 | .owner = THIS_MODULE, 40 | .read = device_file_read, 41 | }; 42 | 43 | static int device_file_major_number = 0; 44 | static const char device_name[] = "Simple-driver"; 45 | 46 | /*===============================================================================================*/ 47 | int register_device(void) 48 | { 49 | int result = 0; 50 | 51 | printk( KERN_NOTICE "Simple-driver: register_device() is called.\n" ); 52 | 53 | result = register_chrdev( 0, device_name, &simple_driver_fops ); 54 | if( result < 0 ) 55 | { 56 | printk( KERN_WARNING "Simple-driver: can\'t register character device with errorcode = %i\n", result ); 57 | return result; 58 | } 59 | 60 | device_file_major_number = result; 61 | printk( KERN_NOTICE "Simple-driver: registered character device with major number = %i and minor numbers 0...255\n" 62 | , device_file_major_number ); 63 | 64 | return 0; 65 | } 66 | 67 | /*===============================================================================================*/ 68 | void unregister_device(void) 69 | { 70 | printk( KERN_NOTICE "Simple-driver: unregister_device() is called\n" ); 71 | if(device_file_major_number != 0) 72 | { 73 | unregister_chrdev(device_file_major_number, device_name); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /device_file.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_FILE_H_ 2 | #define DEVICE_FILE_H_ 3 | #include /* __must_check */ 4 | 5 | __must_check int register_device(void); /* 0 if Ok*/ 6 | void unregister_device(void); 7 | 8 | #endif //DEVICE_FILE_H_ 9 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "device_file.h" 2 | #include /* module_init, module_exit */ 3 | #include /* version info, MODULE_LICENSE, MODULE_AUTHOR, printk() */ 4 | 5 | MODULE_DESCRIPTION("Simple Linux driver"); 6 | MODULE_LICENSE("GPL"); 7 | MODULE_AUTHOR("Apriorit, Inc"); 8 | 9 | /*===============================================================================================*/ 10 | static int simple_driver_init(void) 11 | { 12 | int result = 0; 13 | printk( KERN_NOTICE "Simple-driver: Initialization started\n" ); 14 | 15 | result = register_device(); 16 | return result; 17 | } 18 | 19 | /*===============================================================================================*/ 20 | static void simple_driver_exit(void) 21 | { 22 | printk( KERN_NOTICE "Simple-driver: Exiting\n" ); 23 | unregister_device(); 24 | } 25 | 26 | /*===============================================================================================*/ 27 | module_init(simple_driver_init); 28 | module_exit(simple_driver_exit); 29 | --------------------------------------------------------------------------------