我的Debian2.6.26 入门驱动

    在linux写驱动要比windows下简单的多,不过刚开始驱动环境的搭建耗了我不少时间,下面主要说下我的第一个驱动的完整过程。
    一、下载内核源码.
    很简单,apt-get install linux-source-2.6.26,下载之后解压tar jxvf linux-source-2.6.26.tar.bz2。
    二、配置并编译内核
    配置使用默认的就可以,make oldconfig。然后是编译,make。编译的时间比较长。编译之后会在当前文件夹生成一个文件vmlinux。
    三、编译和安装模块
    make modules, make modules_install
    执行结束之后,会在/lib/modules下生成新的目录/lib/modules/2.6.26/。 在随后的编译模块文件时,要用到这个路径下的build目录。至此,内核编译完成。可以重启一下系统。
   
    这时候编译的时候就不会找不到delay.h之类的头文件了。下面写一个驱动的框架。
#ifndef __KERNEL__ #define __KERNEL__ #endif #ifndef MODULE #define MODULE #endif #define DEVICE_NAME "can_bus" #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/fs.h> #include <asm/uaccess.h> #include <asm/io.h> typedef unsigned char BYTE; int major; ssize_t can_read (struct file *file, char *buf, size_t count, loff_t *f_ops) { printk ("can_read/n"); return 0; } ssize_t can_write (struct file *file, const char *buf, size_t count, loff_t *f_ops) { printk ("can_write/n"); return 0; } int can_ioctl (struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { printk ("ioctl/n"); return 0; } int can_open (struct inode *inode, struct file *file) { printk ("open can bus/n"); try_module_get (THIS_MODULE); return 0; } int can_release (struct inode *inode, struct file *file) { module_put (THIS_MODULE); return 0; } struct file_operations can_fops = { open: can_open, read: can_read, write: can_write, ioctl: can_ioctl, release: can_release, }; int can_init (void) { int retval = 0; major = retval = register_chrdev (0, DEVICE_NAME, &can_fops); if (retval < 0) { printk ("%s: register_chrdev () failed with %d/n", DEVICE_NAME, retval); return -ENODEV; } printk ("can_bus major num = %d/n", major); return 0; } void can_cleanup (void) { unregister_chrdev (major, DEVICE_NAME); } MODULE_LICENSE ("GPL"); module_init (can_init); module_exit (can_cleanup);
这是我写的CAN总线的驱动,摘了个框架出来,在2.6内核下,模块计数的加减要用try_module_get和module_put,然后就是makefile的编写
obj-m:=can_bus.o KERNELDIR:=/lib/modules/2.6.26/build PWD:=$(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm *.o *.ko *.mod.c *.order *.symvers

然后make就可以了,写驱动程序的时候,如果定义一个没有形参的函数,括号里一定要写上void,否则会有一个警告,虽然没什么大碍,不过有警告很不爽,看来养成良好的变成习惯也很重要,make之后会生成一个can_bus.ko,下面的就简单了

1、安装模块insmod can_bus.ko

    如果要想看到输出信息,可以用cat /var/log/messages或者切换到文本界面,直接就能在控制台看到输出:can_bus major num = 249,这是我这里显示的,就是说生成的主设备号是249,用lsmod可以查看模块是否加载了


2、创建设备文件
    mknod /dev/can_bus c 249 0,上面提到的249就用到了,我一直在想,当我使用open打开can_bus设备的时候,怎么跟我的驱动关联起来,这个249就是关键了,刚开始的时候,我就随便写了个主设备号,结果怎么也打不开设备。

3、测试

int fd; fd = open ("/dev/can_bus", O_RDWR); if (fd < 0) { printf ("open can_bus failed/n"); } else { printf ("open can_bus success/n"); }

如果成功打开就能看到控制台open can bus的输出,这时,一个完整的驱动就差不多了。要卸载模块,使用rmmod can_bus即可。

4、开机自动加载
    差不多就是还差一点,驱动不可能每次都要手动去加载,我想让驱动开机的时候自动加载,这就要修改rc.local文件,输入vim /etc/init.d/rc.local,在文件的最后两行添上
insmod /can/can_bus.ko
mknod /dev/can_bus c 249 0
我的can_bus.ko是放在/can目录下的,读者可自行修改,这下就完整了,重启电脑,在做下上面的测试,OK了,不用手动去加载了,大功告成。

你可能感兴趣的:(框架,struct,Debian,Module,File,makefile)