linux系统中读写流程

下面根据我自己的理解,以读过程为例,简要的描述一下应用程序和硬件块设备之间进行数据交换的流程。
首先,应用程序调用库函数fread或者直接调用read系统调用产生读请求,在这里读请求可以理解成需要从文件的某个偏移处读取多长的数据到用户的缓冲区中。上面的两个函数会调用sys_read进入到内核中,从这里开始进程在系统空间中运行。sys_read又会调用具体的文件系统注册的函数对请求进行处理,首先查看请求对应的数据是否在该文件的PAGE CACHE中存在,如果请求的数据已经在PAGE CACHE中,则直接将数据返回给用户空间的缓冲区中,这次请求结束。如果不再PAGE CACHE中,文件系统将经过处理后的请求封装成bio请求格式,发送到块层。bio请求包括读请求的逻辑扇区地址(LBA),读到内存的地址和长度(可能包含多个内存片段)。块层首先查看该bio请求是否能合并到请求队列的某个请求中,若能则合并请求,若不能则为该bio生成一个新的request请求经过重排序后加入到请求队列中。到这里,请求已经到了请求队列中,等待进一步的处理。操作系统的后台线程会定期(还有其他可能触发的条件)的从请求队列中取下请求交给SCSI子系统进行处理,包括调用SCSI上层的块设备驱动准备SCSI命令、准备用于DMA的聚散列表等,最后通过SCSI底层也就是底层驱动将命令发送到设备端。底层驱动往往是通过PIO的方式写设备端的寄存器将命令发送下去,或者将命令的地址写到设备的某个寄存器中,设备再通过DMA的方式从该地址把命令读下去。最终的结果是命令在设备端被解析、执行,然后设备将读取的数据通过DMA的方式写到主机端内核缓冲区或者直接到用户空间缓存(聚散DMA方式),并通过中断的方式通知主机请求执行完成。在中断服务程序中会唤醒之前在该数据上等待的进程继续执行。这样整个请求处理结束,fread或者read函数执行完成,应用程序继续往下执行。
写过程与上门的流程基本类似,不太多说。

### Linux PCIe 设备读写驱动开发指南 #### 驱动框架概述 Linux内核提供了一套完整的API用于管理PCIe设备。这些接口允许开发者创建自定义驱动来控制特定硬件的功能[^1]。 对于PCIe设备而言,其基本操作通常涉及配置空间访问、内存映射I/O以及DMA传输等功能。为了实现上述功能,在编写驱动时需遵循一定的结构模式: - **模块初始化**:通过`module_init()`宏注册入口函数;该函数负责完成必要的资源分配并调用`pci_register_driver()` - **探测回调**:当检测到匹配的PCI设备时会触发此方法执行,主要工作包括设置中断处理程序、建立与用户态通信机制等。 - **移除逻辑**:利用`module_exit()`指定退出点以释放占用资源。 #### 实现具体读写行为 针对具体的取和写入动作,则依赖于几个核心的数据结构体及其成员变量来进行描述: - `struct pci_dev *pdev`: 表征单个物理上的PCI Express端点实例; - `resource_size_t start, end;`: 定义BAR(Base Address Register)所覆盖地址范围边界值; - `void __iomem *base_addr`: 经过重映射后的基址指针,便于后续直接寻址访问寄存器文件。 下面给出一段简单的代码片段展示如何基于以上概念构建一个能够向某一块显卡发送命令并通过轮询方式获取返回状态的应用场景模拟: ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/pci.h> static struct pci_device_id my_pci_ids[] = { { /* Vendor ID */ PCI_DEVICE(0x8086, 0x29A2), }, { } }; MODULE_DEVICE_TABLE(pci, my_pci_ids); static int __init hello_world_init(void){ printk(KERN_INFO "Hello world init\n"); return pci_register_driver(&my_pci_driver); } static void __exit hello_world_exit(void){ pci_unregister_driver(&my_pci_driver); printk(KERN_INFO "Goodbye world exit\n"); } ``` 这段伪代码仅作为示意用途,并未包含实际业务流程中的细节部分。真实的项目里还需要考虑错误恢复策略、多线程同步等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值