FreeBSD设备驱动管理介绍(BSP: Ti AM335x)

news/2024/7/7 19:35:55

这段时间一直在忙FreeBSD驱动移植的项目,因此对FreeBSD做了一定的了解,鉴于网上对于FreeBSD的设备驱动资料较少,在这里给出本人对于FreeBSD驱动管理的理解心得(主要是USB驱动管理),希望能对开源开发者有所帮助。

首先FreeBSD的官方开发手册是必备的:https://www.freebsd.org/doc/en/books/arch-handbook/

以及FreeBSD官方man page:https://www.freebsd.org/cgi/man.cgi 该网页可帮你查找你所不明白的函数的定义和作用



FreeBSD下设备采用树状的设备驱动开发方法:

如下图所示


每个设备驱动包括若干方法,方法的名字由系统预先定义。设备是指连接到系统中的某部分硬件,如扩展卡、卡所在的总线、连接到卡上的磁盘驱动器等。总线也是作为设备,并有相应的驱动程序。系统定义了一个设备root_bus,而所有其它设备则是根据自动配置动态创建。


FreeBSD

操作系统中,注册按先总线设备后叶设备的

顺序进行,设备的启动过程如图

FreeBSD

操作系统中,注册按先总线设备后叶设备的

顺序进行,设备的启动过程如图

在FreeBSD操作系统中,注册按先总线设备后叶设备的顺序进行,设备的启动过程如下图所示:

1.root_bus

2.nexus/simplebus

3.ACPI设备

4.PCI设备



系统统中的root_bus设备并不执行具体的设备驱动,它实际上是提供给其它设备一个根结点,以便所有的设备都能够通过它联系在一起,形成一个有机的整体。Nexus设备负责初始化系统资源的大小,同时提供ACPI资源链支持。

也就是说FreeBSD的设备驱动管理是按照树节点方法,一层一层往上挂载。文章后面会根据具体例子详细介绍设备树


FreeBSD下PCI总线类设备驱动程序框架:

这里采用PCI总线进行分析

PCI类设备驱动的组成主要包括以下4个部分: 
(1) DRIVER_MODULE;

(2) 结构driver_t;

(3) 设备标识表;

(4) 设备类。 


首先是DRIVER_MODULE设备宏,该定义非常重要:

每个设备驱动一般被定义为一个内核模块,声明方式如下:

DRIVER_MODULE(name,busname,driver,devclass,evh,arg)

name: 模块名 
busname: 挂接的总线(PCI、NEXUS、ISA等)    

driver: 驱动程序结构的变量    

devclass: 设备类 

evh: 驱动程序加载/卸载时的事件处理函数 

arg: evh的参数


比如USB中存储设备umass驱动的设备宏定义如下:

DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);

模块名是umass, 挂接的总线是uhub(uhub也是挂接在usbus总线上,而usbus挂接在musbotg总线上,最后musbotg挂接在usbss上,usbss挂接到最后的总线nexus上。完成了一个完整的设备树挂接),驱动变量是umass_driver,设备类是umass_devclass。



结构driver_t 
设备驱动由结构driver_t描述,driver_t定义如下: 
 struct driver{ 
const char *name;

kobj_method_t *method;

size_t size; 
u_int refs;

kobj_ops_t ops;

void *priv; }; 
name: 设备驱动名 
priv: 对应设备实例的私有数据,主要用于存放设备的私有数据结构 
methods: 定义操作该设备的方法 


数组中的每个元素是通过使用宏DEVMETHOD来声明的,如DEVMETHOD(device_probe,ata_pci_probe),其中第1个参数是系统保留的符号,第2个参数是驱动程序中的函数。至于数组中定义了哪些方法是由两方面决定的:设备所在的总线和设备的具体功能。驱动程序中的方法可以分为两类:设备接口和总线方法。

设备接口:

设备接口负责识别、检测、连接设备,另外还可以关闭、挂起、恢复设备。在这些接口中,部分接口因设备的不同而不同,需要单独实现,而有的接口有缺省实现。要根据设备的功能实现部分或全部的接口,设备不支持的接口没有必要实现也无法实现。主要的接口包括: 
device_identify: 仅用于不能自识别的总线,如ISA、ACPI,总线利用该操作识别设备并将其加入到总线中; 
device_probe: 为设备在设备类中寻找合适的驱动,确定能否操作该设备、是否有足够的资源; 
device_attach: 为该设备分配系统资源,将设备加入到系统中,注册设备的中断处理函数; 
device_shutdown: 关闭设备; device_suspend: 挂起设备; device_resume: 恢复设备;


总线方法:
总线方法是总线在处理该设备时所需要的方法,一般因总线不同而不同。系统提供了缺省的定义,用户可以根据设备的具体需要,遵照方法的语义另外定义部分方法,主要方法有: 
bus_print_child: 打印显示总线的一个子设备信息

bus_alloc_resource: 为总线的设备分配资源;

bus_release_resource: 为总线的设备释放资源; 

bus_activate_resource: 激活资源; 

bus_deactivate_resource: 实效资源; 

bus_setup_intr: 注册设备中断处理函数; 

bus_teardown_intr: 注销设备中断处理函数;


设备类数据结构

一类设备一般具有相似的属性,如网卡设备一般都同网络协议栈交互,所有的声卡也都具有相似的属性。设备类数据结构主要包括一个驱动程序结构链表和一个设备数组,具体的定义如下所示: 
struct devclass{ 
    TAILQ_ENTRY(devclass)  link;     

driver_list_t   drivers;     

char  *name;     

device_t  *devices;     

int  maxuint; }; 
设备类主要用于系统管理设备驱动使用,用户自己可以为设备声明设备类,并没有严格的规定,例如在ata驱动程序中声明了一个设备类的实例: 
static devclass_t ata_pci_devclass; 
DRIVER_MODULE(atapci,pci,ata_pci_driver,ata_pci_devclass,0,0);



接下来结合FreeBSD中关于Ti AM335x处理器的USB驱动源码对FreeBSD设备驱动管理进行详细分析:

代码块源文件位于/sy/arm/ti/am335x目录下:

首先要知道AM335x USB在FreeBSD下的设备树:

simplebus->root bus

usbss->simplebus:AM335x的usb sub system模块 负责两个usb0、usb1

musbotg->usbss:AM335x的usb模块采用otg进行控制,也就是既可作为host端,也可以作为device端

usbus->musbotg:usbus是usb control模块,也就是usb 控制器模块

uhub->usbus:uhub是总线模块,一般usb设备都是通过它进行挂接,keyboard、usb storage等

umass->uhub:umass就是usb storage的设备驱动,这已经涉及到最后的usb底层驱动了


以上就是各个USB模块的挂接情况:

源码挂接代码如下:

usbss:

DRIVER_MODULE(usbss, nexus, usbss_driver, usbss_devclass, 0, 0);
musb
DRIVER_MODULE(musbotg, nexus, musbotg_driver, musbotg_devclass, 0, 0);

uhub:
DRIVER_MODULE(uhub, usbus, uhub_driver, uhub_devclass, 0, 0);
DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, NULL, 0);

umass:

DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);


转载于:https://www.cnblogs.com/sichenzhao/p/9320278.html


http://lihuaxi.xjx100.cn/news/252650.html

相关文章

2018年终总结

转眼间,2018年就要过去了,又可以来总结一年的得失了。 今年可以说是充满了收获与挑战的一年,一年的工作基本上是围绕着node来进行的,前端相关的东西是做的越来越少。 工作相关的 今年应该说是换工位频率非常高的一年,东…

基于HTML5的Google水下搜索

这次愚人节的时候,Google推出了水下搜索,当然,这只是一个愚人的小把戏,不过效果非常不错,进入页面后,第一眼是一个水面的效果,水下的鲨鱼在游来游去,然后Google logo和搜索框从水面上…

Play.ht训练出播客乔布斯/用嘴做视频?Meta出品/我国牵头发布首个自动驾驶测试场景领域国际标准...

本周,业界有哪些新鲜事?核心硬件Linux 6.1为LoongArch CPU带来新功能日前,Linux 6.1为LoongArch CPU带来新的附加功能。早在5.19版本中,Linux便实现对LoongArch CPU 的初步支持,此后开发人员坚持填补功能特性上的短板&…

【MATLAB】稀疏矩阵(含有大量0元素的矩阵)

1、稀疏矩阵的储存方式 对于稀疏矩阵,MATLAB仅储存矩阵所有非零元素的值及其位置(行号和列号)。 2、稀疏矩阵的生成 1)利用sparse函数从满矩阵转换得到稀疏矩阵函数名称表示意义sparse(A)由非零元素和下标建立稀疏矩阵A。如果A已是…

如何通过一行代码下载B站视频?

文章目录如何通过一行代码下载B站视频?Step1:安装you-getStep2:下载B站视频总结如何通过一行代码下载B站视频? You-Get 是一个基于 Python 3 的下载工具。使用 You-Get 可以很轻松的下载网络上的视频、图片及音乐。 下面我们介绍…

javassist学习笔记

2019独角兽企业重金招聘Python工程师标准>>> 介绍:www.javassist.org/ javassist、ASM 对比 1、javassist是基于源码级别的API比基于字节码的ASM简单。 2、基于javassist开发,不需要了解字节码的一些知识,而且其封装的一些工具类可…

Makefile (2) gdb

gdb调试 1.用debug的方式编译 -g 2.打上断点 3.单步调试 step into 进入函数里面step over 运行整个函数step return 跳出当前函数 4.继续运行 5.打印和监控值 下面是栗子: 1 #include <stdlib.h>2 #include <stdio.h>3 ​4 static int add(int i) //创…

缓冲区

为什么80%的码农都做不了架构师&#xff1f;>>> 缓冲区主要有2个操作&#xff1a; read操作write操作这2个操作&#xff0c;必须要线程安全的。 read操作流程&#xff1a; write操作流程 转载于:https://my.oschina.net/xbsk/blog/52571