Linux ------- 内存映射(2)

本文详细解析了Linux设备驱动中的关键概念,包括设备文件、索引节点、主次设备号,以及文件操作结构体。深入探讨了open、close和mmap函数在驱动程序中的实现流程,揭示了内存映射的机制及其在设备驱动中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拓展:

关于这个过程,涉及一些术语

(1)设备文件:linux中对硬件虚拟成设备文件,对普通文件的各种操作均适用于设备文件

(2)索引节点:linux使用索引节点来记录文件信息(如文件长度、创建修改时间),它存储在磁盘中,读入内存后就是一个inode结构体,文件系统维护了一个索引节点的数组,每个元素都和文件或者目录一一对应。

(3)主设备号:如上面的999,表示设备的类型,比如该设备是lcd还是usb等

(4)次设备号:如上面的0,表示该类设备上的不同设备

(5)文件(普通文件或设备文件)的三个结构

        ①文件操作:struct file_operations

        ②文件对象:struct file

        ③文件索引节点:struct inode

关于驱动程序中内存映射的实现,先了解一下open和close的流程

(1)设备驱动open流程

①应用程序调用open("/dev/mmap_driver", O_RDWR);

②Open就会通过VFS找到该设备的索引节点(inode),mknod的时候会根据设备号把驱动程序的file_operations结构填充到索引节点中(关于mknod /dev/mmap_driver c 999 0,这条指令创建了设备文件,在安装驱动(insmod)的时候,会运行驱动程序的初始化程序(module_init),在初始化程序中,会注册它的主设备号到系统中(cdev_add),如果mknod时的主设备号999在系统中不存在,即和注册的主设备号不同,则上面的指令会执行失败,就创建不了设备文件)

③然后根据设备文件的索引节点中的file_operations中的open指针,就调用驱动的open方法了。

④生成一个文件对象files_struct结构,系统维护一个files_struct的链表,表示系统中所有打开的文件

⑤返回文件描述符fd,把fd加入到进程的文件描述符表中

(2)设备驱动close流程

应用程序调用close(fd),最终可调用驱动的close,为什么根据一个简单的int型fd就可以找到驱动的close函数?这就和上面说的三个结构(struct file_operations、struct file、struct inode)息息相关了,假如fd = 3

(3)设备驱动mmap流程

由open和close得知,同理,应用程序调用mmap最终也会调用到驱动程序中mmap方法

①应用程序test.mmap.c中mmap函数

void* mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

addr:映射后虚拟地址的起始地址,通常为NULL,内核自动分配

length:映射区的大小

prot:页面访问权限(PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE)

flags:参考网络资料

fd:文件描述符

offset:文件映射开始偏移量

②驱动程序的mmap_driver.c中mmap函数

上面说了,mmap的主要工作是把设备地址映射到进程虚拟地址,也即是一个vm_area_struct的结构体,这里说的映射,是一个很悬的东西,那它在程序中的表现是什么呢?——页表,没错,就是页表,映射就是要建立页表。进程地址空间就可以通过页表(软件)和MMU(硬件)映射到设备地址上了

virt_to_phys(buf),buf是在open时申请的地址,这里使用virt_to_phys把buf转换成物理地址,是模拟了一个硬件设备,即把虚拟设备映射到虚拟地址,在实际中可以直接使用物理地址。

 

总结

①从以上看到,内核各个模块错综复杂、相互交叉

②单纯一个小小驱动模块,就涉及了进程管理(进程地址空间)、内存管理(页表与页帧映射)、虚拟文件系统(structfile、structinode)

③并不是所有设备驱动都可以使用mmap来映射,比如像串口和其他面向流的设备,并且必须按照页大小进行映射。

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值