Driver file:
- /*
- * simplechrdriver.c
- *
- * Copyright (C) 2008 Breathomn <breathomn@sohu.com>
- *
- */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/init.h>
- #include <asm/uaccess.h> /* copy_*_user */
- static unsigned int major_num = 0;
- static int global_var = 0;
- static ssize_t simplechr_read(struct file *filp, char *buf, ssize_t size, loff_t *off)
- {
- if (copy_to_user(buf, &global_var, sizeof(int)))
- return -EFAULT;
- return sizeof(int);
- }
- static ssize_t simplechr_write(struct file *filp, const char *buf, ssize_t size, loff_t *off)
- {
- if (copy_from_user(&global_var, buf, sizeof(int)))
- return -EFAULT;
- return sizeof(int);
- }
- static struct file_operations simplechrdev_ops =
- {
- .owner = THIS_MODULE,
- .read = simplechr_read,
- .write = simplechr_write,
- };
- static int __init simplechr_init(void)
- {
- int ret;
- if ((ret = register_chrdev(major_num, "simplechrdev", &simplechrdev_ops)) < 0)
- printk(KERN_ALERT "simplechrdev register failed!/n");
- else
- {
- major_num = ret;
- printk(KERN_ALERT "simplechrdev register success!/n");
- }
- return ret;
- }
- static void __exit simplechr_exit(void)
- {
- int ret;
- if ((ret = unregister_chrdev(major_num, "simplechrdev")))
- printk(KERN_ALERT "simplechrdev unregister failed!/n");
- else
- printk(KERN_ALERT "simplechrdev unregister success!/n");
- }
- module_init(simplechr_init);
- module_exit(simplechr_exit);
User file:
- /*
- * simplechrsrc.c
- *
- * Copyright (C) 2008 Breathomn <breathomn@sohu.com>
- *
- */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <fcntl.h>
- int main()
- {
- int fd, num;
- if ((fd = open("/dev/simplechrdev", O_RDWR, S_IRUSR | S_IWUSR)) != -1)
- {
- read(fd, &num, sizeof(int));
- printf("Read: %d/n", num);
- printf(" Write a num: ");
- scanf("%d", &num);
- write(fd, &num, sizeof(int));
- read(fd, &num, sizeof(int));
- printf("Raed again: %d/n", num);
- close(fd);
- }
- else
- printf("Open device failed!/n");
- }
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