1、/dev目录下,主设备号和次设备号。ls -l可以通过第一个字母是c或者b区分是字符设备或者是块设备。主设备号标识设备对应的驱动程序。

2、分配设备编号:

如果我们提前明确知道所需要的设备编号,则使用

int  register_chrdev_region(dev_t first,unsigned int count,char * name);

否则,使用动态分配函数

int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);

3、释放设备编号

一般,该函数在模块的清除函数中调用

void unregister_chrdev_region(dev_t first,unsigned int count);

注意:驱动程序应该始终使用alloc_chrdev_region而不是register_chrdev_region函数

4、需要学习:awk工具和grep命令

(1)IBM awk教程

5、分配主设备号的最佳方式:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。

// 获取主设备号
if(scull_major){
dev = MKDEV(scull_major,scull_minor);
result = register_chrdev_region(dev,scull_nr_devs,"scull");
}else{
result = alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");
scull_major = MAJOR(dev);
}
if(result < 0){
printk(KERN_WARNING "scull: can't get major %d /n", scull_major);
return result;
}

6、一些重要的数据结构:file_operations、file和inode,这些数据结构都定义在<linux/fs.h>中

(1)scull实现file_operations其中的几个最重要的

// scull设备的文件操作
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
.read = scull_read,
.write = scull_write,
/*.ioctl = scull_ioctl,*/
.open = scull_open,
.release = scull_release,
};

(2)file结构代表一个打开的文件描述符

(3)inode在内部表示文件,i节点

补推荐直接操作i_rdev,应该使用这两个宏操作获取主设备号和次设备号:

unsigned int iminor(struct inode *inode);
unsigned int imajor(struct inode *inode);

7、(1)open和release

  • 小技巧:container_of的使用。案例:我们通常不需要cdev结构本身,而是需要包含cdev结构的scull_dev结构。由结构体中的成员指针获得结构体的指针。
  • 驱动程序如何才能知道一个打开的设备文件要被真正关闭呢?答:并不是每个close系统调用都会引起对release方法的调用。

(2)scull的内存使用

linux内核中用于内存管理的两个核心函数。定义在<linux/slab.h>中

void *kmalloc(size_t size, int flags);
void kfree(void *ptr);

read和write是站在用户空间的角度说的。

8、一篇IBM开发者社区的文章:linux内核剖析

9、linux网站,上面有初、中、高等linux教程:linux之家

10、scull模块全部代码(含注释):基本scull模块代码

11、编译测试,未实验成功。不过,找到一篇文章点击打开链接,详细介绍了每一个可能的错误和解决方法;

其中有个错误:‘SPIN_LOCK_UNLOCKED’未声明(不在函数内),在这篇文章中解决了(点击打开链接

12、scull终于编译通过后,进行了如下实验:

(1)利用scull_load安装驱动;

(2)用ls -l /dev/scull查看安装的设备。

(3)使用cp命令测试

(4)使用输入/输出重定向测试

点击打开链接

(5)使用free命令查看内存变化【未完】

(6)验证每次读写一个量子【未完】

13、学习使用strace工具

(1)strace:用来跟踪进程执行时的系统调用和所接收的信号

(2)使用strace和gdb调试程序

linux驱动开发手记【2】的更多相关文章

  1. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  2. 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  3. 【转】linux驱动开发的经典书籍

    原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...

  4. Linux驱动开发 -- 打开dev_dbg()

    Linux驱动开发 -- 打开dev_dbg() -- :: 分类: LINUX linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KER ...

  5. Linux驱动开发学习的一些必要步骤

      1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...

  6. 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  7. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  8. Linux驱动开发必看详解神秘内核(完全转载)

    Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html   IT168 技术文档]在开始步入L ...

  9. Linux内核(17) - 高效学习Linux驱动开发

    这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到 ...

随机推荐

  1. delete、truncate、drop三种删除语句联系与区别

    相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 2.drop.truncate都是DDL语句(数据定义语言),执行后会自动提交. 不同点: 1. t ...

  2. js写入和读取cookie

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. 【转】HTML meta标签总结与属性使用介绍

    HTML meta标签总结与属性使用介绍 转载处写的已经超级好了,强烈推荐. 转自:https://segmentfault.com/a/1190000004279791 本人就不再赘述.拿来主义!供 ...

  4. python:连接Oracle数据库后控制台打印中文为??

    打印查询结果,中文显示为了??? [('72H FCR', '2.0'), ('?????', '8.0')] E:\Python35\Lib\site-packages中新增文件: sitecust ...

  5. ADB 常用命令及详解

    1.pull文件 adb pull (文件路径) (想要pull的路径) MacBook-Pro:~ caris$ adb pull /sdcard/Android/data/com.xiwi.log ...

  6. java8新特性1--Lambda表达式

    一.Lambda表达式是什么? Lambda表达式有两个特点 一是匿名函数,二是可传递. 匿名函数的应用场景是 通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用Lambda表达式.lam ...

  7. [转帖]Redis性能解析--Redis为什么那么快?

    Redis性能解析--Redis为什么那么快? https://www.cnblogs.com/xlecho/p/11832118.html echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加e ...

  8. Django框架之DRF get post put delete 使用简单示例 (利用序列化反序列化)

    路由配置 # 路由 from django.conf.urls import url from django.contrib import admin from app01 import views ...

  9. (转)AS3正则:元子符,元序列,标志,数量表达符

    (转)AS3正则:元子符,元序列,标志,数量表达符: AS3正则:元子符,元序列,标志,数量表达符 七月 4th, 2010 归类于 AS3前端技术 作者Linkjun 进行评论 as3正则:元子符, ...

  10. TweenLite参数用法中文介绍

    TweenLite是一个缓动的类包,功能强大,并且易于使用,为了更多的(E文欠佳的.初学的)朋友了解它,使用它,特此翻译了一下TweenLite类文档中的说明文件,主要是对参数的说明,希望对大家有用. ...