编写好驱动,经过挂载的方法将驱动程序挂载到内核里面,大体步骤以下:node
一: 1>创建以.c为后缀的c语言程序文件 (里面包含了设备名及设备号等)
2>创建Makefile文件(做用是经过make来产生设备文件*.ko文件,里面能够创建本身的平台所需的设备文件如:arm等).make 产生相应的设备文件linux
二: 要在/dev下创建相应的设备结点(设备名),用insomd *.ko命令将相应的驱动设备文件挂载到内核中.shell
三:编写测试文件(.c文件)用来测试内核是否已近成功挂载到内核.(编写好相应的测试文件后,用gcc –o Filename Filename.c(测试文件名) 来产生相应的可执行文件).bash
四:若是设备驱动挂载成功,当执行测试文件(./Filename)时会产生相应的结果.
五:可能用到的相关命令:
1. lsmod:列出内核已经载入模块的专题.
输出:
Module(模块名) size(大小) used by (被..使用)
2. demop:分析可加载模块的依赖性,生成modules.dep文件和映射文件
3. uname –r 显示内核版本(在编写Makefile时使用到)
4. modprobe : linux 内核添加和删除模块(相关参数请查看man帮助文档)
5. modinfo:显示内核模块的信息.
6. insmod: 向linux内核中加载一个模块,用法:insmod [filename] [module options…]
7. rmmod: 删除内核中的模块, 用法: rmmod [-f,w,s,v] [modulename]
8. dmesg: 显示内核缓冲区,内核的各类信息,内核启动时的信息会写入到/var/log/下.less
六.例子函数
#include <linux/fs.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/uaccess.h> #include <linux/module> #include <linux/kernel>
//定义设备名称 #define DEVICE_NAME "test" //设备名 #define BUF_SIZE 1024 static char tmpbuf[BUF_SIZE]; //定义主次设备号 static unsigned int TestMajor=0; //主 static unsigned int TestMinor=0; //次 static struct cdev *test_cdev; static dev_t dev;
static int test_chardev_open(struct inode *inode,struct file *file) { printk("open major=%d, minor=%d\n", imajor(inode), iminor(inode)); return 0; } static int test_chardev_release(struct inode *inode,struct file *file) { printk("close major=%d,minor=%d\n",imajor(inode), iminor(inode)); return 0; }
static ssize_t test_chardev_read(struct file *file,char __user *buf, size_t const count,loff_t *offset) { if(count < BUF_SIZE) { if(copy_to_user(buf,tmpbuf,count)) { printk("copy to user fail \n"); return -EFAULT; } }else{ printk("read size must be less than %d\n", BUF_SIZE); return -EINVAL; } *offset += count; return count; }
static ssize_t test_chardev_write(struct file *file, const char __user *buf,size_t const count,loff_t *offset) { if(count < BUF_SIZE) { if(copy_from_user(tmpbuf,buf,count)) { printk("copy from user fail \n"); return -EFAULT; } }else{ printk("size must be less than %d\n", BUF_SIZE); return -EINVAL; } *offset += count; return count; }
static struct file_operations chardev_fops={ .owner = THIS_MODULE, .read = test_chardev_read, .write = test_chardev_write, .open = test_chardev_open, .release = test_chardev_release, };
static int __init chrdev_init(void) { int result; if(TestMajor) { dev=MKDEV(TestMajor,TestMinor);//建立设备编号 result=register_chrdev_region(dev,1,DEVICE_NAME); } else { result=alloc_chrdev_region(&dev,TestMinor,1,DEVICE_NAME); TestMajor=MAJOR(dev); } if(result<0) { printk(KERN_WARNING"LED: cannot get major %d \n",TestMajor); return result; } test_cdev=cdev_alloc(); cdev_init(test_cdev,&chardev_fops); //test_cdev->ops=&chardev_fops; test_cdev->owner=THIS_MODULE; result=cdev_add(test_cdev,dev,1); if(result) printk("<1>Error %d while register led device!\n",result); return 0; }
unregister_chrdev_region(MKDEV(TestMajor,TestMinor),1); cdev_del(test_cdev);
$mknod /dev/test c XXX(主设备号) XX(次设备号)
#include <linux/init.h> #include <linux/module.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/uaccess.h> #define DEVICENAME "ccccc" unsigned int major=221; unsigned int minor=0; struct cdev *abc; dev_t dev; static char bufrh[1024]="read success!"; static int aaaaa_open(struct inode *inodep, struct file *filep) { printk("read success!\n"); return 0; } int aaaaa_release(struct inode *inodep, struct file *filep) { return 0; } static ssize_t aaaaa_read (struct file *filep, char __user *buf, size_t count, loff_t *offset) { if(copy_to_user(buf, bufrh, 1)) { printk("copy_to_user fail!\n"); } return 0; } ssize_t aaaaa_write (struct file *filep, const char __user *buf, size_t count, loff_t *offse) { printk("write!\n"); return 0; } static const struct file_operations fops = { .owner = THIS_MODULE, .open = aaaaa_open, .release = aaaaa_release, .read = aaaaa_read, .write = aaaaa_write, }; static int __init aaaaa_init(void) { int a; dev=MKDEV(major, minor); a=register_chrdev_region(dev, 1, DEVICENAME); abc=cdev_alloc(); abc->owner=THIS_MODULE; cdev_init(abc, &fops); cdev_add(abc, dev, 1); return 0; } static void __exit aaaaa_cleanup(void) { cdev_del(abc); unregister_chrdev_region(dev, 1); } module_init(aaaaa_init); module_exit(aaaaa_cleanup); MODULE_LICENSE("GPL ");
Makefile文件测试
obj-m += firstqd.o(相应设备文件名) KERDIR = /usr/src/linux-headers-2.6.32-24-generic #x86平台 PWD=$(shell pwd) modules: $(MAKE) -C $(KERDIR) M=$(PWD) modules pc: gcc -o fristqd firstqd.c arm: arm-linux-gcc -o fristqd firstqd.c clean: rm -rf *.o *~core *.depend *.cmd *.ko *.mod.c *.tmp_versions
#include <stdio.h> #include <sys/types.h> #include <fcntl.h> char buf[1024]; char bufw[1024]="write success"; int main() { int fd,m,n; fd=open("/dev/aaa",O_RDWR); if (fd) { m=read(fd,buf,100); printf("read kernel:%s\n",buf); n=write(fd,bufw,10); } //printf("ni hao"); return 0; }