Linux character driver skeleton

Driver file:

  1. /*
  2.  * simplechrdriver.c
  3.  *
  4.  * Copyright (C) 2008 Breathomn <[email protected]>
  5.  *
  6.  */
  7. #include <linux/module.h>
  8. #include <linux/kernel.h>
  9. #include <linux/fs.h>
  10. #include <linux/init.h>
  11. #include <asm/uaccess.h>    /* copy_*_user */
  12. static unsigned int major_num = 0;
  13. static int global_var = 0;
  14. static ssize_t simplechr_read(struct file *filp, char *buf, ssize_t size, loff_t *off)
  15. {
  16.     if (copy_to_user(buf, &global_var, sizeof(int)))
  17.         return -EFAULT;
  18.     return sizeof(int);
  19. }
  20. static ssize_t simplechr_write(struct file *filp, const char *buf, ssize_t size, loff_t *off)
  21. {
  22.     if (copy_from_user(&global_var, buf, sizeof(int)))
  23.         return -EFAULT;
  24.     return sizeof(int);
  25. }
  26. static struct file_operations simplechrdev_ops = 
  27. {
  28.     .owner  = THIS_MODULE,
  29.     .read   = simplechr_read,
  30.     .write  = simplechr_write,
  31. };
  32. static int __init simplechr_init(void)
  33. {
  34.     int ret;
  35.     if ((ret = register_chrdev(major_num, "simplechrdev", &simplechrdev_ops)) < 0)
  36.         printk(KERN_ALERT "simplechrdev register failed!/n");
  37.     else
  38.     {
  39.         major_num = ret;
  40.         printk(KERN_ALERT "simplechrdev register success!/n");
  41.     }
  42.     return ret;
  43. }
  44. static void __exit simplechr_exit(void)
  45. {
  46.     int ret;
  47.     if ((ret = unregister_chrdev(major_num, "simplechrdev")))
  48.         printk(KERN_ALERT "simplechrdev unregister failed!/n");
  49.     else
  50.         printk(KERN_ALERT "simplechrdev unregister success!/n");
  51. }
  52. module_init(simplechr_init);
  53. module_exit(simplechr_exit);

User file:

  1. /*
  2.  * simplechrsrc.c
  3.  *
  4.  * Copyright (C) 2008 Breathomn <[email protected]>
  5.  *
  6.  */
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <stdio.h>
  10. #include <fcntl.h>
  11. int main()
  12. {
  13.     int fd, num;
  14.     if ((fd = open("/dev/simplechrdev", O_RDWR, S_IRUSR | S_IWUSR)) != -1)
  15.     {
  16.         read(fd, &num, sizeof(int));
  17.         printf("Read: %d/n", num);
  18.         printf(" Write a num: ");
  19.         scanf("%d", &num);
  20.         write(fd, &num, sizeof(int));
  21.         read(fd, &num, sizeof(int));
  22.         printf("Raed again: %d/n", num);
  23.         close(fd);
  24.     }
  25.     else
  26.         printf("Open device failed!/n");
  27. }

Makefile file:

 

obj-m := simplechrdriver.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD       := $(shell pwd)

all:
            $(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:
            rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

 

Compile our driver into kernel:
(1) Create a new directory named simplechrdev in "$(KERNELSOURCE)/drivers/char" directory.
(2) Copy the driver file "simplechrdriver.c" to the new directory.
(3) Create a Kconfig file in "simplechrdev" directory with contents below:
    config SIMPLECHRDEV
    tristate "SimpleChrDev"
(4) Modify the Kconfig file of its parent directory "char", add contents:
    source "drivers/char/simplechrdev/Kconfig"
    Then we can find a item named "SimpleChrDev" in "Device Driver->Character devices" when we use "make menuconfig/xconfig".
(5) Create a Makefile file in "simplechrdev" directory with contents below:
    obj-$(CONFIG_SIMPLECHRDEV)      += simplechrdriver.o
(6) Modify the Makefile file of its parent directory "char", add contents:
    obj-$(CONFIG_SIMPLECHRDEV)      += simplechrdev/
    All things done! Remake kernel and reboot computer, the driver simplechrdriver works probably. Input the command "cat /proc/devices", our device simplechrdev is in the Character devices list.
(7) To load our module automatically
    We can choose to compile our driver as a module, but sometimes the kernel can not load our module automatically. We can find a solution that add some contents to "/etc/rc.d/rc.sysinit" file to the problem.
    # SimpleChrDev
    if [ -d /lib/modules/$unamer/kernel/drivers/char/simplechrdev ]; then
    for module in /lib/modules/$unamer/kernel/drivers/char/simplechrdev/*; do
    module=${module##*/}
    module=${module%.ko}
    modprobe $module >/dev/null 2>&1
    done
    fi

你可能感兴趣的:(Linux character driver skeleton)