編寫好驅動,經過掛載的方法將驅動程序掛載到內核裏面,大體步驟以下: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; }