博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【驱动】linux驱动程序开发及环境搭建
阅读量:6273 次
发布时间:2019-06-22

本文共 4033 字,大约阅读时间需要 13 分钟。

1.mystery引入

   1)设备驱动程序对外提供如下的功能

       1)设备初始化:对硬件设备进行初始化操作
       2)数据交换:数据交换包括由内核层向硬件层传送数据、从硬件层读取数据到内核层;
                     应用程序向设备文件传送数据、设备文件向应用程序回送数据
       3)设备请求与检测:检测各硬件设备的各种参数信息、错误信息
       4)设备释放:设备使用完后的资源释放
   2)驱动一般分为字符设备驱动、块设备驱动和网络设备驱动
       1)字符设备驱动:可以按字节操作的方式对设备文件进行存取,一般对应慢速设备,例如串口设备
       2)块设备驱动:是按数据块的方式对设备文件进行访问,一般对应高速设备,例如DMA
       3)网络设备驱动:是面向网卡设备,用于处理网络报文的发送与接收
   3)字符设备与块设备均可以通过访问文件的方式进行操作,二者唯一的不同的是Linux对于它们的数据管理方式的不同。
   4)应用程序对字符设备的I/O操作,会直接传送到内核驱动层,而块设备的操作,则是需要借助于中间的缓存区,以间接的方式进行数据交换。

 

 


2.环境搭建及测试

   1)下载对应版本的内核源码包
   2)因为现在对内核还不是很熟,加上内核源码比较大,所以我先下一个内核的开发包
   3)终端:

sudo yum install kernel-devel

   4)如图

 

   5)环境搭建好了,问题又来了。。uname -r 的结果和我系统内核版本不一样。。

   这里我直接用我系统的内核版本号作测试了,我的系统内核版本是3.6.10-2.fc17.i686

   6)第一个版本的Makefile文件如下:

obj-m:=chardev.oKDIR:=/lib/modules/3.6.10-2.fc17.i686/buildSRCPWD:=$(shell pwd)all:    make -C $(KDIR) M=$(SRCPWD) modulesclean:    rm -rf chardev.o

 

   7)编译结果如图

 

 

 


3.驱动验证

   1)设备安装
       当安装驱动时,又出现错误了,纠结。。错误:编译使用的内核和当前系统的内核不一样!
   2)反思
      1)这时我才想起,前断时间我更新了下系统,当时把系统内核升级到了3.6,但是无法进入系统,所以我直接把grub项的3.6内核的引导删掉了,现在打开grub查找错误
      2)grub中关于内核3.6开机引导项内容如下:

 

      3)看了这断代码,对升级后新内核无法进入系统的原因就明了了,我在想,为什么升级内核的时候没有制作initrd

      4)于是我退后一步,自己制作initrd,终端下:

mkinitrd initrd-3.6.6 3.6.6

      (先切换到linux-3.6.6的上一级目录),由于系统升级内核时已经编译过内核镜像和内核模块了,并且也已经安装过内核模块了

      5)所以我要做的就是将initrd复制到boot目录下,然后再添加新的引导项
      6)在上图 echo 'Loading Fedora (3.6.10-2.fc17.i686)' 的下一行添加自己制作的initrd,代码:initrd/boot/initrd-3.6.10-2.fc17.i686.img
      7)重启电脑,OK,成功引导进行新内核,但是有很多地方不尽人意
         1)电脑需要重装显卡驱动,分辨率太低
         2)无法联网,需要重装网卡驱动
         3)无法挂载FAT格式的盘
         4)无法挂载NTFS格式的盘
      8)因此,我还是决定用3.3的内核,只是在3.6下作驱动程序测试


4.驱动测试

   1)如图所示:

 

 

 

   2)驱动设备创建好后,编写一个程序验证下

   3)效果如图:

 

   4)这里出现OPEN错误和READ错误,但是却又读出了驱动函数的内容,表示驱动还是成功的,由于这个内核开始出现的不尽人意,也没有去调试这个错误的原因


5.驱动源代码

#include 
#include
#include
#include
#include
static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *); static int char_open(struct inode *,struct file *); static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*);static int char_release(struct inode *,struct file *); static int device_open_count; static int major;static const struct file_operations file_ops ={ .read = char_read, .write = char_write, .open = char_open, .release = char_release,};static int __init char_init(void){ int value; major = 0; value = register_chrdev(major, "chardev", &file_ops); if (value < 0) { printk("无法注册设备"); return value; } if (major == 0) major = value; return 0;}static int char_open(struct inode *inode,struct file *file){ if(device_open_count == 0) device_open_count++; else { printk("设备已经被打开\n"); return -1; } try_module_get(THIS_MODULE); return 0;}static int char_release(struct inode *inode,struct file *file){ device_open_count--; module_put(THIS_MODULE); return 0;}static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset){ if(length < 0) return -1; else if(length > 12) length = 12; if(copy_to_user(buffer,"Hello Linux!",length)) return length; return -1;}static int char_write(struct file *filp,const char __user *buffer,size_t length,loff_t *offset){ return 0;}static void __exit module_close(void){ unregister_chrdev(major, "chardev");}module_init(char_init);module_exit(module_close);

 

 

 


6.Makefile源代码

obj-m:=chardev.oKDIR:=/lib/modules/$(shell uname -r)/buildSRCPWD:=$(shell pwd)all:    make -C $(KDIR) M=$(SRCPWD) modulesclean:    rm -rf chardev.o

 

 

 


7.测试程序源代码

#include 
#include
#include
#include
#include
#include
#include
int main(void){ int testdev; int i,rf=0; char buf[15]; memset(buf, 0, sizeof(buf)); testdev = open("/dev/chardev",O_RDWR); if ( testdev == -1 ) { perror("open\n"); exit(0); } rf=read(testdev,buf,11); if(rf<0) perror("read error\n"); printf("R:%s\n",buf); close(testdev); return 0;}

 

 

本文出自 “” 博客,请务必保留此出处

转载地址:http://wmopa.baihongyu.com/

你可能感兴趣的文章
At.js – 用于 Web 应用程序的自动完成库
查看>>
[Android Pro] Android权限设置android.permission完整列表
查看>>
如何对抗硬件断点--- 调试寄存器
查看>>
mybatis学习
查看>>
从不同层面看cocos2d-x
查看>>
Struts2技术详解
查看>>
MFC应用程序向导生成的文件
查看>>
Oracle体系结构之oracle密码文件管理
查看>>
【leetcode】Remove Element (easy)
查看>>
mysql多表查询及其 group by 组内排序
查看>>
alsa的snd_pcm_readi()函数和snd_pcm_writei()
查看>>
Android学习网站推荐(转)
查看>>
嵌入式根文件系统的移植和制作详解
查看>>
MEF部件的生命周期(PartCreationPolicy)
查看>>
LCD的接口类型详解
查看>>
nginx 基础文档
查看>>
LintCode: Unique Characters
查看>>
Jackson序列化和反序列化Json数据完整示例
查看>>
.net 中的DllImport
查看>>
nyoj 517 最小公倍数 【java睑板】
查看>>