米联客技术答疑系统
微信客服01
微信客服02
微信客服03
QQ售前
QQ售后
提交问题
常见问题
联系我们
客服时间
周一至周五
8:00~18:00
[X]关闭
联系在线客服
首页
BBS
技术答疑系统
VIP视频课程
VIP板卡资料包
VIP会员购买
米联客-天猫店
米联客-京东店
发表
发布文章
提问答疑
搜索
您还未登录
登录后即可体验更多功能
立即登录
我的收藏
提问答疑
我要投稿
客服中心
工单中心
操作系统Linux
主题分类
学习提问
自学笔记
经验总结
资料分享
资源分配及总线系统
文档创建者:
东吴
浏览次数:
21
最后更新:
2025-01-02
操作系统Linux
21 人阅读
|
0 人回复
一、资源分配
1、资源管理
(1)数据结构分析
Linux提供通用的架构,用于在内存中构建数据结构。这些结构描述了系统中可用的资源,使得内核代码能够管理和分配资源。其中关键的数据结构resource源码如下:
用于连接parent,child,sibling成员规则如下:
a.每个子结点只有一个父结点
b.一个父节点可以有任意数目的子结点
c.同一个父结点的所有子结点,会连接到兄弟节点链表上面。
在内存中表示数据结构时,注意几个问题:
a.每个子节点都有指针指向父结点,但父结点只有一个指针指向第一个子结点。所有其它子结点都通过兄弟结点链表访问·
b.指向父结点的指针同样可以为NULL
(2)请求和释放资源
为确保可靠地配置资源(无论何种类型),内核必须提供一种机制来分配和释放资源。一旦资源已经分配,则不能由任何其他驱动程序使用。
请求资源:内核提供了_request_resourse函数,用于请求一个资源区域。
该函数用于分配request实例,在此函数当中也会进行检查(起始地址大于结束地址,请求无法使用),则放弃操作。Request_resource这个函数负责锁操作,主要工作由__request_resource完成。它连接地扫描现在的资源,将新资源添加到正确的位置,或发现与已经分配区域的冲突。完成所有操作之后,需要遍历兄弟结点的链表。如果所需要的资源区域是空闲的,则插入新的resource实例,这样就可以完成资源分配。如果区域不是空闲,则分配失败。
在扫描特点父结点的子结点时,会在一个层次上扫描兄弟结点链表。内核不会扫描更底层的子结点链表。
释放资源:直接调用release_resource函数释放使用中的资源。
2、I/O内存
资源管理另一种重要分配方式是I/O内存分配,在所有平台上这都是与外设通信的主要方法(IA-32除外,其中I/O端口更为重要)。I/O内存不仅包括与扩展设备通信直接使用的内存区域,还包括系统中可用的物理内存和ROM存储器,以及包含在资源列表中的内存(可以使用proc文件系统中的iomem文件,显示所有的I/O内存)。
所有分配的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文件可以显示已经分配的端口地址。
二、总线系统
1、通用驱动程序模型
现代总线系统在布局和结构的细节上可能有所不同,但也有许多共同之处,内核的数据结构即反映了这个事实。结构中的许多成员用于所有的总线(以及相关设备的数据结构中)。 在内核版本2.6开发期间,一个通用驱动程序模型(设备模型, device model)并入内核,以防止不必要的复制。所有总线共有的属性封装到特殊的、可以用通用方法处理的数据结构中,再关联到总线相关的成员。
设备表示的数据结构源码如下:
通用驱动程序模型也为设备驱动程序单独设计一种数据结构源码:
总线的表示(类型)源码如下:
注册过程(注册总线—>注册设备—>注册设备驱动程序)
注册总线:
注册设备:初始化设备的数据结构,并将它加入到数据结构的网络中
注册设备驱动程序:
在进行一些检查和初始化工作之后,driver_register调用bus_add_driver将一个新驱动程序添加到一个总线来。驱动程序要有名字,然后注册到通用数据结构框架。
如果总线支持自动探测,调用driver_attach,该函数迭代总线上所有设备,使用驱动程序的match函数进行检测,确定是否有某些设备树可使用该驱动程序管理。最后将该驱动程序添加到总线上注册的所有驱动程序的链表中。
2、PCI总线
PCI是peripheral component interconnect的缩写,是英特尔公司开发的一种标准总 线,它迅速在系统组件和体系结构厂商中间确立了自身的地位,成为一种非常流行的总线。
PCI系统布局如下:
设备标识:系统某个PCI总线上的每个设备,都由一组3个编号标识;
总线编号:设备所有总线的编号,编号从0开始,PCI规范准许每个系统最多255个总线;
插槽编号:总线内核的一个唯一标识编号,一个总线最多能够附接32个设备;
功能编号:用于在一个扩展卡上,实现包括多个扩展设备的设备。
PCI总线数据结构如下:
设备管理数据结构源码如下:
驱动程序函数源码如下:
PCI驱动程序通过pci_register_driver注册
3、USB
所有USB设备都划分到不同类型当中,在内核源码中,我们可以看到这样划分,各个驱动程序源码按照所属类型归纳到不同的目录:
USB标准定义4种不同传输模式:控制传输、块传输、中断传输及同步传输。
USB子系统有4种主要任务:
注册和管理现存的设备驱动程序;
为USB设备查找适当的驱动程序,以及初始化和配置;
在内核内存中表示设备树;
与设备通信(交换数据);
USB驱动源码如下:
USB设备树表示如下
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
上一个主题
下一个主题
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页