[X]关闭

资源分配及总线系统

文档创建者:东吴
浏览次数:21
最后更新:2025-01-02
一、资源分配
1、资源管理
(1)数据结构分析
    Linux提供通用的架构,用于在内存中构建数据结构。这些结构描述了系统中可用的资源,使得内核代码能够管理和分配资源。其中关键的数据结构resource源码如下:
image.jpg

image.jpg
用于连接parent,child,sibling成员规则如下:
a.每个子结点只有一个父结点
b.一个父节点可以有任意数目的子结点
c.同一个父结点的所有子结点,会连接到兄弟节点链表上面。
在内存中表示数据结构时,注意几个问题:
a.每个子节点都有指针指向父结点,但父结点只有一个指针指向第一个子结点。所有其它子结点都通过兄弟结点链表访问·
b.指向父结点的指针同样可以为NULL
(2)请求和释放资源
    为确保可靠地配置资源(无论何种类型),内核必须提供一种机制来分配和释放资源。一旦资源已经分配,则不能由任何其他驱动程序使用。
请求资源:内核提供了_request_resourse函数,用于请求一个资源区域。
image.jpg
    该函数用于分配request实例,在此函数当中也会进行检查(起始地址大于结束地址,请求无法使用),则放弃操作。Request_resource这个函数负责锁操作,主要工作由__request_resource完成。它连接地扫描现在的资源,将新资源添加到正确的位置,或发现与已经分配区域的冲突。完成所有操作之后,需要遍历兄弟结点的链表。如果所需要的资源区域是空闲的,则插入新的resource实例,这样就可以完成资源分配。如果区域不是空闲,则分配失败。
    在扫描特点父结点的子结点时,会在一个层次上扫描兄弟结点链表。内核不会扫描更底层的子结点链表。
    释放资源:直接调用release_resource函数释放使用中的资源。
image.jpg
2、I/O内存
    资源管理另一种重要分配方式是I/O内存分配,在所有平台上这都是与外设通信的主要方法(IA-32除外,其中I/O端口更为重要)。I/O内存不仅包括与扩展设备通信直接使用的内存区域,还包括系统中可用的物理内存和ROM存储器,以及包含在资源列表中的内存(可以使用proc文件系统中的iomem文件,显示所有的I/O内存)。
image.jpg
    所有分配的I/O内存地址,它们都要通过一棵资源树管理,树的根结点是全局内核变量iomem_resource.
    使用I/O内存时,分配内存区域并不是所需要的唯一操作。主要取决于总线系统和处理器类型,可能必需将扩展设备的地址空间映射到内核地址空间之后,才可以访问此设备(称为软件I/O映射)。这是通过使用ioremap内核函数适当设置系统页表实现。同样也可以使用体系结构当中的iounmap函数解除映射操作。
    将一个物理地址映射到处理器的虚拟地址空间中,使得内核可以使用该地址,就设备驱动程序而言,意味着扩展总线的地址空间映射到CPU的地址空间中,使得能够用普通内存访问函数来操作总线/设备。
3、I/O端口
    I/O端口是一种与设备和总线通信的流行方法,特别是在IA-32平台上。类似于I/O内存,按良好范例编写的驱动程序在访问所需的区域之前,相应的区域必须已经注册。糟糕的是,处理器无法检查注册是否已经完成。
    kernel/resource.c中的ioport_resource充当资源树的根结点。 proc文件系统中的ioports文件可以显示已经分配的端口地址。
image.jpg
二、总线系统
1、通用驱动程序模型
    现代总线系统在布局和结构的细节上可能有所不同,但也有许多共同之处,内核的数据结构即反映了这个事实。结构中的许多成员用于所有的总线(以及相关设备的数据结构中)。 在内核版本2.6开发期间,一个通用驱动程序模型(设备模型, device model)并入内核,以防止不必要的复制。所有总线共有的属性封装到特殊的、可以用通用方法处理的数据结构中,再关联到总线相关的成员。
设备表示的数据结构源码如下:
image.jpg

image.jpg
通用驱动程序模型也为设备驱动程序单独设计一种数据结构源码:
image.jpg
总线的表示(类型)源码如下:
image.jpg
注册过程(注册总线—>注册设备—>注册设备驱动程序)
注册总线:
image.jpg
注册设备:初始化设备的数据结构,并将它加入到数据结构的网络中
image.jpg
注册设备驱动程序:
    在进行一些检查和初始化工作之后,driver_register调用bus_add_driver将一个新驱动程序添加到一个总线来。驱动程序要有名字,然后注册到通用数据结构框架。
image.jpg

image.jpg
    如果总线支持自动探测,调用driver_attach,该函数迭代总线上所有设备,使用驱动程序的match函数进行检测,确定是否有某些设备树可使用该驱动程序管理。最后将该驱动程序添加到总线上注册的所有驱动程序的链表中。
2、PCI总线
    PCI是peripheral component interconnect的缩写,是英特尔公司开发的一种标准总 线,它迅速在系统组件和体系结构厂商中间确立了自身的地位,成为一种非常流行的总线。
PCI系统布局如下:
设备标识:系统某个PCI总线上的每个设备,都由一组3个编号标识;
总线编号:设备所有总线的编号,编号从0开始,PCI规范准许每个系统最多255个总线;
插槽编号:总线内核的一个唯一标识编号,一个总线最多能够附接32个设备;
功能编号:用于在一个扩展卡上,实现包括多个扩展设备的设备。
PCI总线数据结构如下:
image.jpg
设备管理数据结构源码如下:
image.jpg
驱动程序函数源码如下:
image.jpg
PCI驱动程序通过pci_register_driver注册
image.jpg
3、USB
    所有USB设备都划分到不同类型当中,在内核源码中,我们可以看到这样划分,各个驱动程序源码按照所属类型归纳到不同的目录:
image.jpg
USB标准定义4种不同传输模式:控制传输、块传输、中断传输及同步传输。
USB子系统有4种主要任务:
注册和管理现存的设备驱动程序;
为USB设备查找适当的驱动程序,以及初始化和配置;
在内核内存中表示设备树;
与设备通信(交换数据);
USB驱动源码如下:
image.jpg
USB设备树表示如下

image.jpg

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则