linux驱动概述
Posted lzd626
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux驱动概述相关的知识,希望对你有一定的参考价值。
1.Linux的应用程序是怎么调用驱动程序的?
2.应用程序的open是怎么与驱动的open对应起来的?(https://blog.csdn.net/dengdun6257/article/details/102283350)
应用层:
当应用程序调用open打开设备文件时会返回一个文件描述符,以供后续的应用程序使用;open原型为:int open(const char *pathname, int flags)
当打开之后调用read读取数据时:read原型为:ssize_t read(int fd, void *buf, size_t count)
映射过程:(https://www.linuxidc.com/Linux/2016-12/138520.htm)
注册设备时将实际的fops赋值给cdev的fops,并注册到cdev_map表,并与设备号映射(cdev_map是一个struct kobj_map类型的指针,其中包含着一个struct probe指针类型、大小为255的数组,数组的每个元素指向的一个probe结构封装了一个设备号和相应的设备对象(这里就是cdev),这个cdev_map封装了系统中的所有的cdev结构和对应的设备号,最多为255个字符设备。)
当应用层调用read时,会根据文件描述符得到设备节点文件对应的inode指针(主要包含设备号和cdev)和flip指针。inode指针中有设备号信息能够告诉操作系统应该使用哪一个设备驱动程序(主要是fops),flip指针中有fops信息(通过inode里的fops传给flip里的fops)
驱动层:
static int chrdev_open(struct inode *inode, struct file *filp);inode对应内核的设备文件,filp对应当前被打开的文件
static ssize_t chrdev_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt) ;设备打开后,就使用打开的文件进行后续的操作
3.系统调用是怎么运转的?(https://blog.csdn.net/gatieme/article/details/50779184)
一般地,系统调用都是通过软件中断实现的,x86系统上的软件中断由int $0x80指令产生,而128号异常处理程序就是系统调用处理程序system_call()
Linux中每个系统调用都有相应的系统调用号作为唯一的标识,内核维护一张系统调用表,sys_call_table,表中的元素是系统调用函数的起始地址,而系统调用号就是系统调用在调用表的偏移量
大部分系统调用都还需要一些外部的参数输人给内核空间和给用户空间返回值,都是通过寄存器传递
4.module_init怎么区别驱动是编译进内核还是模块?(https://blog.csdn.net/weixin_37571125/article/details/78665184)
模块代码有两种运行方式,一是静态编译连接进内核,在系统启动过程中进行初始化;一是编译成可动态加载的module,通过insmod动态加载重定位到内核。这两种方式可以在Makefile中通过obj-y或obj-m选项进行选择;
当我们选择将驱动编译成模块时,module_init中的MODULE宏就会被定义; 如果没有定义MODULE宏,那么驱动初始化函数就会带有.initcall6.init属性,那么在其编译时将会被安排到__initcall_start和__initcall_end范围之间。.init 或者 .initcalls 段的特点就是,当内核启动完毕后,这个段中的内存会被释放掉
以上是关于linux驱动概述的主要内容,如果未能解决你的问题,请参考以下文章