您的位置:首页 > 运维架构 > Linux

linux驱动学习知识积累

2013-07-30 15:37 190 查看

一、基础知识扫盲

1、dev_t结构体

在内核中,dev_t结构体用来保存设备编号信息,在linux/type.h中定义,是一个32位的数,12位表示主设备号+20位的次设备号

?
2、file_opertions结构

该结构体定义在<linux/fs.h>中,用来建立驱动程序到设备编号的连接,其中每一个成员对应一个系统调用(这里就是所谓的API)。用户进程利用系统调用在对设备文件进行诸如读写操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构对应的函数指针,接着将控制权交给该函数,这就是API所完成的工作。

3、file和inode结构体

结构体file在<linux/fs.h>中定义,是一个内核结构,不会出现在用户进程中,与用户空间程序中的file没有任何联系,他表示一个打开的文件,不仅仅限于设备驱动程序,而结构体inode表示一个磁盘上的具体文件。对单个文件,可能会有多个表示打开的文件描述符的file结构, 但是它们都指向单个inode 结构。

4、cdev结构体

在/linux/cdev.h定义,专门用来表示字符设备。

struct cdev {

struct kobject kobj;

struct module *owner;

const struct file_operations -*ops;

struct list_head list;

dev_t dev;

unsigned int count;

};

5、注册和注销设备号的相关函数(register_chrdev_region和unregister_chrdev_region)

静态分配注册设备号,是指在事先知道设备主设备号的情况下,通过参数函数指定的第一个设备号而向系统申请分配一定数目的设备号。

?
动态分配注册设备号,是指通过参数仅设置一个次设备号和药分配的设备数目而系统动态分配所需的设备号。

?
?
?
?
6、加载和卸载模块

insmod命令和rmmod命令用于加载和卸载模块,使用insmod时,入口点函数是init_module()函数,这里实现设备的注册;使用rmmod命令时的入口函数是cleanup_module函数,在这里实现设备的卸载。(这里参照与非网的字符设备驱动编程)。

7、linux内核模式下的内存分配函数

在linux内核模式下,不能使用用户态的malloc()和free()函数申请和释放内存。进行内核编程时,最常用的的内存申请和释放函数为在linux/kernel.h中声明的kmalloc()和Kfree(),其原型为:

?
?
注:Kmalloc()一般用来分配小于128K的内存,而且必须是2的整数次方,并且不会对所获取的内存清零。如果要分配大块的内存,应使用面向页的技术。

另一种为vmalloc,分配的是内核虚拟地址,虽然是连续的,但是映射到的物理地址是不连续的,而且可能与物理地址不是一一对应的。其原型为:

?
8、用户态和内核太内存交互

由于内核态和用户态使用不同的内核定义,所以二者相互不能直接访问对方的内存。有一些函数在include/asm/uaccess.h中声明:

?
9、lsmod:用于显示当前系统中加载的模块

rmmod:用于卸载当前系统加载的模块

10、主设备号和次设备号

主设备号表明设备的类型,与一个确定的驱动程序对应,次设备号通常是用于标明不同的属性,例如不同的使用方法,不同的位置,不同的操作等,它标志着某个具体的物理设备。

11、什么是释放设备和关闭设备

释放设备表示当前进程释放某个设备,其他进程还可以使用该设备;如果当前进程关闭该设备,则其他进程需要重新打开该设备才能使用。

12、读写设备

读写设备的主要任务就是把内核空间的数据复制到用户空间,或者从用户空间复制到内核空间。其函数原型为:

?
13、io控制操作

大部分设备出了读写操作,还需要硬件配置和控制,具体函数为:在linux/fs.h中定义

?
14、打印消息

?
?
?
?
?
15、proc文件系统

linux内核提供了一种proc文件系统,可以在运行时访问内核内部数据结构,或许有关系统和进程的有用信息,在运行时通过改变内核参数来改变设置。与其他文件系统不同,/proc存在于内存中而不是在硬盘上。

16、memset

在一段内存中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。函数原型为:

?
17、try_module_get()宏

include/linux/module.h

?
18、printk中原始指针必须用%p输出

19、linux驱动中函数都设置成static的原因是:

linux内核十分宠大,代码量超过百万行。对于C语言的函数和全局变量的作用空间都是全局的,在另外一个文件中,使用extern关键字就可以实现对于其他文件中的全局变量

和函数的访问。因此,一旦源码中函数名称定义相同,就会出现编译出错。因此,需要引入一些封装的特性,限制源码中函数和变量作用的空间。在前面添加static关键字,

其作用范围将缩小到仅仅为当前的文件,而不是整个系统。因此在平时写驱动时,如果函数不需要被其他文件中引用,在前面添加static关键字是一个很好的习惯。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: