设备驱动程序的纪录
废话不多说
第一个就是设备编号 每个驱动都是必不可少的这个;
设编号就是简单的一个数字而已;就是一个32 位的整形数字
其中的12位是 主设备号
剩下的20 位为次设备号;
加入 设备号为 a
主设备号为b
次设备号为c
那么三者之间的转换 linux内核给我们准备了 三个 宏定义
int b = MAJOR(a);
int c=MINOR(a);
int a=MKDEV(a,b);
明白了上面的转换 下面就不会迷糊了很简单了
分配和释放设备编号;
分配就是 用
int register_chr_dev( a ,unsigined int count,char *name);
这个第一个参数就不用我多解释了
第二个就是连续的设备个数 最后一个就是出现 在proc/devices/name
///上面的这个函数的意思 就是我选好了一个设备号 我就拿去注册 不管别人用过了 没有就去注册当然大部分是没有注册的当然也不能排除 不幸运的时候这个好吗已经用过了 ;
那这个时候就会返回错误了
如果咱们不 想浪费这个脑子去想这个设备编号 那么就有一个 函数帮助我们了;
int alloc_register_chrdev( int *a, unsigned int count ,char *name);//这个函数比较牛B就是自动给你分配一个可以用的 而且注册一家伙;
a指针当然是返回的参数了 就是 分配并注册好了的设备编号了 ;
因为这个以后是要用到的;
释放设备编号 是函数 void unregister_chrdev_region(dev_t first,unsigned int count );
NEXT
文件操作
经典结构 ops; 这个很面熟把 并不是这个结构的名字叫这个 只是很多的书里面用这定义变量 坎杜噢了就知道这个市这个仪式 了
里面有超级多的 孩子 你们有兴趣的话可以看一下LDD3 这本书里面写的比较详细;不过不同的设备常用的有意义就那么几个记着就够了;file_operations ;当然是定义在 linux/fs.h 头文件里了;
文件结构
有了文件的操作结构当然 也要有文件结构了要不然炒作个P呢?
file 这个结构根用户空间的FILE 没有一点点地关系
file只是一个结构而且是内核空间的 不会出现在用户空间的;file代表 着一个打开的文件 他的意义 在于 通用不仅仅限制于设备驱动;
他由 内核在open的时降生 并且把自己的 打开方方式 ===什么杂七杂八的属性 方法什么的 其实这个就是上面说的 ops;、
当内核拿到 这ops的时候就知道怎么给 这个文件交往了 ;所以说呢 ops 是file 的 一个属性
同时呢 这个跟前面的设备编号 有什么联系呢?/ 设备编号就是设备的编号 设备呢 是 文件的一个分支 于是就有联系了
设备编号到底是怎么绘事 其实呢……………… 看下面就知道了;
其中呢参数
NEXRT
inode 我今天才知道是个什么咚咚;
内核呢用file 表示已经打开的文件呢 可是文件就好比一个东西呀 可能被同时很多东西用着 这就 意味着 一个真实的文件 会有 〉=0 个file结构 在内核里面;
这个真实的文件 内核怎么表示的呢 就是用的inode;
inode 表示一个真实的文件 肯定就有文件的所有属性了 ;当然设备文件 也包含在这个真实的inode里面 说呢 可以 从inode 里面找到真实的设备编号;
也就是inode结构的 一个孩子了;
同样呢 是有 两个宏定义 来取出 主次设备号 就是 iminor( inode); 和 imajor(inode);
inode呢 还有另外一个重要的结构就是
cdev * i_cdev 也就当 inode 指向一个字符设备的时候 这个字段就包含指向struct cdev 结构的指针;
NEXT
字符设备的注册
cdev 结构包含在cdev.h 头文件里面;
这里严重说明 cdev说到底 还是一个文件就是一个文件 所以呢就拥有文件的特性 ;
LDD3 原文里面是这么说的 我们用cdev 表示一个字符设备 ;前面说过 设备就是 特别的文件而已;
所以文件结构的 东西也就 类似于 等于包含于 或者 被包含于 file 结构 ;
cdev 的创建 有俩方式;
大一个比方
如果内核中的inode 是一个人的化那么
cdev 结构的初始化 就是 创造身躯;
当然创造有两种方式 一种是 动态的在程序 运行中创建 一种是 先定一个初始化好 ;
如果是 静态创建的 就是用cdev_init(struct *cdev ,file_operations *fopts);
于是就把 灵魂ops 赋予了这个身躯;
另一种呢 就用struct cdev *my_cdev = cdev_alloc();来分配一个结构;
当然赋予灵魂就直接贴在身上就好了 my_cdev->ops = &myfileops;
创建以后呢 就把这个活生生的 设备诞生在内核里面把 让一个inode来表示他的存在;
用函数int cdev_add(struct cdev *cc_dev ,dev_t num ,unsigned int counts );
看看这个函数的参数 是不是很 熟悉呢 就是有前面的 设备好好号 还有多少个 一般都是一个所以呢 1;
于是就能说明一个问题 哈 设备号是内河里面 对设备的编号 于是呢 这个就前后 对应了 原来 内核就是这么回事呢;
这么来管理 设备文件的 ;