DB43-T 2260-2021 信息技术应用创新工程建设规范 第9部分:驱动开发通.用技术要求_第1页
DB43-T 2260-2021 信息技术应用创新工程建设规范 第9部分:驱动开发通.用技术要求_第2页
DB43-T 2260-2021 信息技术应用创新工程建设规范 第9部分:驱动开发通.用技术要求_第3页
DB43-T 2260-2021 信息技术应用创新工程建设规范 第9部分:驱动开发通.用技术要求_第4页
DB43-T 2260-2021 信息技术应用创新工程建设规范 第9部分:驱动开发通.用技术要求_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ICS01.140.20CCSL70信息技术应用创新工程建设规范第9部分:驱动开发通用技术要求EngineeringspecificationfortheApplicationInnovationProjectofInformationTechnologyPart9:GeneraltechnicalrequirementsofdriverdevelopingIDB43/T2260—2021前言 Ⅲ 2规范性引用文件 3术语和定义 4缩略语 25核内驱动总体要求 25.1编程要求 25.2设备驱动模型 35.3文件组织形式 35.4驱动程序实现 35.5第三方技术使用 46核内驱动具体要求 56.1字符设备驱动程序 56.2块设备驱动程序 66.3平台设备驱动程序 76.4网络设备驱动程序 96.5显示帧缓存设备驱动程序 6.6驱动程序的DKMS包制作 6.7驱动程序的调试验证 7常用外设开发要求 7.1打印机驱动开发 7.2扫描仪驱动开发 7.3手写液晶屏驱动开发 附录A(资料性)设备驱动分类 附录B(资料性)驱动程序实现函数示例 附录C(资料性)驱动程序可调用的内核函数接口 附录D(规范性)驱动程序相关的结构体 附录E(资料性)DKMS技术说明及示例 附录F(资料性)第三方内核模块打包 附录G(资料性)驱动程序的调试验证方法 附录H(资料性)打印机驱动库配置文件示例 DB43/T2260—2021本文件按照GB/T1.1—2020《标准化工作导则第1部分:标准化文件的结构和起草规则》的规定起草。请注意本文件的某些内容可能涉及专利。本文件的发布机构不承担识别专利的责任。《信息技术应用创新工程建设规范》分为以下几个部分:——第1部分:台式微型计算机通用技术要求;——第2部分:便携式微型计算机通用技术要求;——第3部分:服务器通用技术要求;——第4部分:操作系统通用技术要求;——第5部分:操作系统硬件兼容性通用技术要求;——第6部分:操作系统软件兼容性通用技术要求;——第7部分:办公套件通用技术要求;——第8部分:电子公文通用技术要求;——第9部分:驱动开发通用技术要求;——第10部分:应用开发通用技术要求;——第11部分:迁移适配通用技术要求;——第12部分:国产化信息系统建设质量管理规范;——第13部分:国产化信息系统运行维护规范;——第14部分:国产化信息系统建设验收规范;——第15部分:云计算通用技术要求。本部分为第9部分。本部分由湖南省国家密码管理局提出。本部分由湖南省工业和信息化厅归口。本部分起草单位:银河麒麟软件(长沙)有限公司、中国人民解放军国防科技大学、飞腾信息技术有限公司、湖南湘江鲲鹏信息科技有限责任公司、湖南中软信息系统有限公司、湖南长城科技信息有限公司、湖南国科微电子股份有限公司、长沙景嘉微电子股份有限公司、鹏城实验室。本部分主要起草人:张铎、吴庆波、孙立明、刘云、王琦、刘正元、王勇军、李唯实、王晓川、马俊、齐璇、蔡威、张月、吕超、董昱、曹泽文、付志鹏。DB43/T2260—2021V引言湖南省为深入贯彻国家网络强国战略,全面落实中央有关文件精神,部署开展湖南省信息技术应用创新工程建设,保障全省各级党政机关关键信息基础设施信息安全和信息系统安全可靠运行。针对自主可控产品体系初具规模,但相关产品和工程实施标准规范还很缺乏的现状,为了规范工程建设,加速工程进度,扩大建设结果,同时有力提升自主可控产业发展水平,确保信息安全,由湖南省国家密码管理局作为业务主管单位、湖南省工业和信息化厅作为技术归口单位,由中国人民解放军国防科技大学、中国电子信息产业集团有限公司等单位与湖南省合作制定了《信息技术应用创新工程建设规范》地方标准。《信息技术应用创新工程建设规范》主要由自主可控核心产品、典型应用、工程管理等方面的规范组成,重点解决应用创新工程建设当中产品选型、应用开发、工程实施等基础环节的实际问题,可为应用创新工程的用户使用单位、集成建设单位和相关产品研制单位,在产品和应用规范化、软硬件兼容适配、工程实施标准等方面提供一般性指引。《信息技术应用创新工程建设规范》未来将根据自主可控产业和应用创新工程的发展变化进行相应的必要调整和补充。DB43/T2260—20211信息技术应用创新工程建设规范第9部分:驱动开发通用技术要求本文件提出了国产操作系统驱动程序开发的编程要求、设备驱动模型、文件组织形式、驱动程序实现、第三方技术使用等总体要求,并针对字符设备、块设备、平台设备、网络设备、显示帧缓存设备的驱动程序框架和开发提出具体要求。本文件适用于国产操作系统上第三方驱动程序的开发,也为第三方驱动程序的调试验证提供指导。2规范性引用文件下列文件中的内容通过文中的规范性引用而构成本文件必不可少的条款。其中,注日期的引用文件,仅该日期对应的版本适用于本文件;不注日期的引用文件,其最新版本(包括所有的修改单)适用于本文件。GB/T15272—1994程序设计语言C3术语和定义下列术语和定义适用于本文件。3.1驱动程序driver驱动程序是硬件厂商根据操作系统编写的配置文件,操作系统通过驱动来与控制设备和进行通信。3.2设备device是计算机系统中输入、输出设备(包括外存储器)的统称。设备对数据和信息起着传输、转送和存储的作用。3.3总线bus是计算机各种功能部件之间传送信息的公共通信干线。3.4设备驱动模型devicedrivermodel设备驱动模型是操作系统内核为了管理硬件上的设备和对应的驱动程序所制定的一套软件体系。3.5平台总线platformbus3.6平台设备驱动模型platformdevicedrivermodel2DB43/T2260—2021平台设备驱动模型,即采用平台总线的方式对驱动程序和设备进行管理的设备驱动模型。3.7字符设备characterdevice字符设备是不可寻址的,仅提供数据的流式访问的设备。3.8块设备blockdevice块设备是以块为单位的、可以寻址的设备。块设备通常支持重定位操作,实现对数据的随机访问。3.9网络设备networkdevice网络设备通过网络适配器和特定的网络协议来完成网络访问的设备。3.10版本魔术信息vermagicinformation版本魔术信息是驱动程序内存储的、用来描述操作系统内核版本号以及基础内核配置的字符串。3.11导出符号exportsymbol导出符号是操作系统内核模块导出的、可供其他模块中的函数使用的全局变量或者函数。3.12GNU编译器套件GNUCompilerCollectionGNU编译器套件是由GNU开发的编程语言编译器,它包括C、C++、Objective-C、Fortran、Java、Ada和Go语言前端,也包括了这些语言的库(如libstdc++,libgcj等。)3.13OPPS信息OPPSInformation操作系统内核发生严重错误时所提示的信息,包括错误发生时的各个常用寄存器的值,调用的堆栈,以及出错的可能原因。4缩略语下列缩略语适用于本文件:ACPI:高级配置和电源管理接口(AdvancedConfigurationandPowerManagementInterface)CPU:中央处理器(CentralProcessingUnit)DKMS:动态内核模块支持(DynamicKernelModuleSupport)GNU:开源标准(GNU’sNotUnix)GPL:GNU通用公共许可证(GNUGeneralPublicLicense)I/O:输入/输出(Input/Output)NAPI:网络数据处理API(NewAPI)PMU:性能监视单元(PerformanceMonitoringUnit)5核内驱动总体要求5.1编程要求驱动程序代码应符合GB/T15272-1994和Linux内核编程的相关要求,并采用系统内核提供的代码DB43/T2260—20213检查脚本来检查驱动程序代码的合规性。为了保证内核升级时其内部调用符号的可用性,驱动程序代码分为内核框架层和核心代码逻辑层,其中内核框架层实现与内核对接的部分,而核心代码逻辑层实现驱动模块的核心功能,编写时应符合以下原则:a)不使用内核的API接口和数据结构;b)不使用内核的框架代码;c)不进行内核版本的判断处理;d)不使用宏进行同架构内CPU的判断处理;e)二进制文件只包含需要保护的代码。5.2设备驱动模型应基于设备驱动模型来进行驱动程序开发,设备驱动模型分类参见附录A,设备和驱动程序均应挂载到总线上,并通过总线来实现对驱动程序和设备的管理。5.3文件组织形式应采用独立目录存放驱动程序的代码文件,驱动程序目录:a)应包含Makefile驱动程序构建文件,用于驱动程序的自动化编译;b)应使用.c源码文件来保存驱动程序实现,若驱动程序的功能复杂,通过多个源码文件来分类存放驱动程序实现;linux/module.h和linux/kernel.h头文件,当需要调用内核功能时,驱动应使用上述头文件中提供的函数接口来请求内核功能;d)应使用Kconfig配置文件来描述驱动程序源码文件相关的内核配置菜单;e)宜使用Readme说明文档来介绍驱动程序的功能和使用方法。5.4驱动程序实现5.4.1入口函数驱动程序开发应定义和实现驱动程序的入口函数,驱动程序的入口函数应满足以下要求:a)应使用__init初始化修饰符来修饰入口函数;b)应完成驱动程序的注册和加载操作;c)应调用内核提供的驱动程序总线注册函数来完成驱动程序的注册;d)应通过具体的返回值来表示驱动程序是否加载成功,加载失败的返回值宜定义为负值,不同的负值对应不同的错误原因;e)应通过内核提供的module_init()模块初始化函数来声明驱动程序的入口函数。驱动程序入口函数示例见附录B.1。5.4.2出口函数驱动程序开发应定义和实现驱动程序的出口函数,驱动程序的出口函数应满足以下要求:a)应使用__exit退出修饰符来修饰出口函数;b)应完成驱动的卸载操作;c)应打印卸载相关信息,无需通过返回值来注明驱动程序的卸载是否成功;d)应通过内核提供的module_exit()模块退出函数来声明驱动程序的出口函数。DB43/T2260—20214驱动程序出口函数示例见附录B.2。5.4.3信息声明“模块描述”等信息,信息声明示例见附录B.3。5.4.4remove卸载函数驱动程序应实现remove卸载函数,在remove卸载函数中实现对驱动程序申请的设备、内存以及sys文件系统节点等资源的释放。卸载程序中的资源释放示例见附录B.4。若驱动程序中注册了回调函数,则remove卸载函数中应包含注销回调函数的操作。5.4.5核心数据结构的可扩展性应通过以下方式来实现驱动程序核心数据的可扩展性:a)在数据结构中添加reserved保留字段;b)在数据结构中添加表示私有数据的指针,扩展时只需要修改该指针所指向的数据结构,而无需修改核心数据结构。核心数据结构的可扩展性实现示例见附录B.5。5.4.6probe探测函数驱动程序应实现probe探测函数,用于完成设备驱动程序注册的最后收尾工作。在probe探测函数中进行硬件资源的获取、内存结构的映射以及设备的创建等操作时,应通过内核提供的内核操作函数接口进行,涉及的内核操作函数接口见附录C。5.4.7用户空间内存访问若驱动程序需访问用户空间内存,应在访问前先使用access_ok检验函数来检查用户空间内存指针5.4.8调试统计变量驱动程序开发时应添加必要的调试统计变量,以便于对驱动程序的调试测试。调试统计变量宜实现分级开关,以提供各种粒度的调试测试选项。5.4.9导出符号规范EXPORT_SYMBOL_GPL宏导出的符号适用于包含GPL许可的模块,EXPORT_SYMBOL宏导出的符号适用于任何模块。EXPORT_SYMBOL(func1);EXPORT_SYMBOL_GPL(func2);5.5第三方技术使用驱动程序开发若涉及对第三方技术的使用,应在驱动程序正式开发前对所涉及的第三方技术进行效率、兼容性、稳定性等方面的测试,确保第三方技术的使用不会对驱动程序的功能、性能造成不良影响。DB43/T2260—202156核内驱动具体要求6.1字符设备驱动程序6.1.1驱动程序框架字符设备驱动程序框架见图1。图1字符设备驱动程序框架字符设备驱动包括以下部分:a)设备文件操作函数接口:字符设备驱动通过file_operation结构体函数集向用户空间提供设备文件操作函数接口。file_operation结构体中的函数集用于实现驱动与/dev下的字符设备close(关闭)对/dev目录下字符设备节点进行操作时,会通过file_operation结构体中的对应函数来通知驱动实现对字符设备的对应操作。b)内核空间的字符设备驱动程序。驱动程序直接与字符设备硬件打交道,负责实现设备注册、设备操作等硬件操作功能。6.1.2开发要求函数接口为实现系统/dev下的字符设备节点与驱动程序的联通,字符设备驱动程序应提供并实现与llseek、read、write、open、close等文件操作函数接口所对应的函数实现,并通过file_operations文件操作结构体将文件操作函数与驱动程序内的函数实现相关联。file_operations文件操作结构体格式应符合附录D.1要求。驱动程序注册字符设备驱动程序应基于平台驱动模型注册,包含以下内容:DB43/T2260—20216a)应提前准备好驱动程序对应的主设备号,主设备号应使用内核已注册的主设备号之外的数值;b)应使用平台驱动结构platform_driver封装驱动程序信息;c)应使用平台驱动程序注册函数platform_driver_register(drv)将驱动程序注册到平台总线的驱动程序链表中。字符设备注册字符设备的注册应包含如下内容:a)预生成一个尚未被申请使用的设备号;b)预生成设备号的主设备号为对应的驱动程序的主设备号,从设备号应从0开始,宜根据驱动程序所匹配的设备数量按序取值,最大取值不超过1048575;c)应使用静态申请方式申请设备号;d)应对cdev结构体进行初始化,并将实现的file_operations函数结构体与cdev关联;e)针对注册的字符设备,应使用内核提供的函数组创建对应sys文件系统节点,且需对返回值做错误处理,若有多个从设备,应创建class类。驱动匹配字符设备驱动程序开发应同时通过设备树和ACPI两种方式来封装设备信息,并将封装后的信息分别添加到“驱动-设备”匹配队列中。6.2块设备驱动程序6.2.1驱动程序框架块设备驱动程序框架分为三个层次,见图2。图2块设备驱动程序框架a)通用块层:为各种类型的块设备建立一个统一的模型,接受上层发出的数据读写请求,并最终发出I/O请求。通用块层隐藏了底层硬件块设备的特性,为块设备提供了一个通用的抽象视图;DB43/T2260—20217b)输入输出调度层:接收通用块层发出的I/O请求,缓存请求并合并相邻的请求,根据设置好的调度算法,回调驱动层提供的请求处理函数,以处理具体的I/O请求;c)块设备驱动层:处理集体I/O请求,处理过程根据块设备类型的不同而有所不同。块设备驱动程序的一般处理流程应为:上层调用通用块层提供的接口提交I/O请求,这些请求首先被放入输入输出调度层的I/O调度队列,经过合并和排序,最终将转换后的I/O请求派发到具体块设备驱动准备的等待队列,由块设备驱动进一步处理。6.2.2开发要求函数接口块设备驱动程序的函数接口应符合以下要求:a)虚拟块设备的驱动程序可以不提供probe探测函数接口;b)若块设备驱动程序中需要对I/O请求进行特殊处理,则应提供并实现I/O处理函数;staticblk_qc_txxx_make_request(structrequest_qc)块设备驱动程序应实现I/O中断请求对应的中断处理函数接口,虚拟块设备的驱动程序可以不实现该函数接口;staticirqreturn_tgdrom_command_interrupt(intirq,void*dev_id);d)块设备驱动程序应提供并实现ioctl、open、close等基本块设备操作的设备操作函数接口。驱动程序加载块设备驱动程序的加载主要包括以下内容:a)应使用alloc_disk()块设备分配函数分配gendisk通用块设备结构体;b)可以通过内核提供的register_blkdev()块设备注册函数注册设备;c)若需要I/O调度,应使用请求队列进行数据传输;d)应初始化gendisk通用块设备结构体,并对结构体的成员赋初值;e)应使用add_disk()设备添加函数激活该块设备。驱动程序卸载块设备驱动程序的卸载主要包括以下内容:a)应使用del_gendisk()设备删除函数删除块设备,并使用put_disk()函数删除对块设备的引用;blkdev()块设备注销函数注销设备并释放对设备的引用。6.3平台设备驱动程序6.3.1驱动程序框架平台设备驱动程序可分为平台控制器驱动和平台设备驱动两个部分,驱动框架见图3。DB43/T2260—20218图3平台设备驱动程序子系统框架6.3.2开发要求函数接口.1对外接口平台设备驱动程序提供给应用层的接口应使用标准接口,提供的接口应有说明以及用例。提供的对外接口应采用dev节点方式或sysfs节点方式。.2电源管理接口平台设备驱动程序应提供设备的暂停、恢复流程和电源管理接口,以确保在系统休眠或待机时可以保存设备自身的寄存器的状态以及其他必要的上下文信息,以及确保系统恢复后设备能恢复到休眠或待机之前的状态。驱动及设备注册平台设备驱动程序应满足总线\设备\驱动的平台设备驱动模型,设备应注册在总线上.平台控制器驱动应注册成master主设备,控制器下设备驱动应注册成slave从设备,并使用master主设备提供的接口来完成收发功能。驱动程序和设备注册时,应使用系统内核提供的接口完成注册,包括:a)总线注册控制器驱动的接口;b)平台控制器设备驱动注册成总线master主设备的接口;c)控制器下设备驱动注册成总线slave从设备的接口;d)slave从设备使用master主设备xfer的接口。设备资源的描述和获取应使用标准的设备描述接口来描述和获取设备资源信息,包括物理地址\中断号\端口等其他可以描DB43/T2260—20219述的信息。驱动程序加载标准的驱动程序加载应包括以下内容:a)使用设备树或者acpitable匹配的加载方法;b)使用标准的总线设备函数接口模型;c)驱动程序应提供设备树和acpitable匹配节点的方法。6.4网络设备驱动程序6.4.1驱动程序框架网络设备驱动程序框架分为网络协议接口层、网络设备接口层、提供实际功能的网络驱动接口层以及设备媒介层四层,见图4。图4网络设备驱动程序框架a)网络协议接口层:向网络层协议提供统一的数据包收发接口,使得上层协议独立于具体的设备;b)网络设备接口层:向网络协议接口层提供的用于描述具体网络设备属性和操作的net_device结构体,该结构体是设备驱动功能层各函数的容器;c)网络驱动接口层:实现网络设备接口层net_device结构体中所声明的成员函数,驱使网络设备硬件完成相应动作的程序;d)设备媒介层是完成数据包发送和接收的物理实体,包括网络适配器和具体的传输媒介,根据设备驱动功能层中的函数在物理上驱动网络适配器等。6.4.2开发要求函数接口网络设备驱动程序开发应根据net_device网络设备结构体中声明的成员函数实现设备驱动功能层的相关函数接口,并将net_device网络设备结构体注册到系统内核中。网络设备驱动程序接口应包含初始化接口,发送接口和接收接口。DB43/T2260—20网络设备管理.1管理接口a)分配及初始化网络设备net_device;b)以太网的初始化;c)注册/注销网络设备net_device;d)开始/停止发送队列。.2数据结构网络设备驱动程序开发应使用内核提供的结构体来描述网络设备及设备操作,应包括以下结构体:a)sk_buff结构体是网络驱动程序框架中信息的载体,是网络分层模型中对数据进行层层打包以及层层解包的载体;b)net_device网络设备结构体用来描述一个网络设备,是设备接口层的核心,也是编写网络驱动程序的核心对象;c)net_device_ops网络设备操作结构体定义了网络设备的操作方法集,其格式应符合附录D.2要求。网络设备的中断处理网络设备的中断处理方式分为传统中断方式和NAPI处理方式两种,在进行网络设备中断处理时,应根据实际业务特点和需要,按这两种方式之一进行中断处理。6.5显示帧缓存设备驱动程序6.5.1驱动程序框架显示帧缓存设备驱动程序框架见图5。图5显示帧缓存设备驱动程序框架DB43/T2260—2021显示帧缓存设备驱动程序分为通用层和设备层两层:通用层代码为内核通用实现,在通用代码中会提供mmap、read、open、ioctl等通用函数接口,用户可以直接调用这些接口;设备层代码由驱动程序实现,应提供设备操作函数接口来实现对显卡设备的操作。6.5.2开发要求函数接口显示帧缓存设备驱动程序应提供并实现显示帧缓存设备的操作函数接口,以供内核实现对显示帧缓存设备的操作。应实现的显示帧缓存设备操作集结构体及应提供的设备操作函数接口格式应符合附录D.3。驱动程序注册应通过以下两种方式进行驱动程序注册:a)PCI设备的驱动程序应通过pci_register_driverPCI设备驱动程序注册函数注册。b)非PCI设备的驱动程序应通过platform_driver_register平台设备驱动程序注册函数注册。驱动程序加载显示帧缓存设备驱动程序在加载时,应允许通过模块参数控制其加载过程。module_param_named函数来进行参数传递。probe探测函数显示帧缓存设备驱动程序的probe探测函数应包含以下操作:a)定义所需结构体指针;b)获取中断号,根据硬件手册规范,申请中断资源request_irq;c)获取映射I/O端口/内存资源:先调用request_mem_region函数取得I/O端口/内存资源,然后通过ioremap函数将I/O端口/内存资源映射到虚拟地址空间;d)初始化fb_info帧缓存信息结构体;e)申请并映射显存资源:PCI设备使用显存应通过pci_resource_start函数来申请显存;非PCI设备使用DMA内存应通过dma_alloc_writecombine函数来申请DMA内存,并根据平台特性决定是否启用cache;f)硬件寄存器初始化;g)调用fb_check_var函数检查var相关参数是否符合要求;h)注册framebuffer帧缓存;i)创建硬件相关sys系统文件、节点等。remove卸载函数显示帧缓存设备驱动程序的remove卸载函数中应包含以下操作:a)注销framebuffer帧缓存;b)关闭硬件设备;c)解除显存映射;d)释放显存、中断、释放fb_info结构体内存以及I/O端口/内存资源。DB43/T2260—20216.6驱动程序的DKMS包制作6.6.1一般开发要求开发第三方驱动程序DKMS包应满足以下要求:a)第三方驱动程序应以DKMS软件包的方式发布;b)第三方驱动程序的核心代码可以闭源,但应保证生成的二进制模块的兼容性;c)宜通过包创建工具自动生成编译DKMS软件包所需的控制和配置文件;d)根据是否闭源,打包后的DKMS包应遵循如下命名规则:开源模块命名为:原始模块名-dkms_版本号_CPU架构.软件包格式;闭源模块命名为:原始模块名-dkms-closed_版本号_CPU架构.软件包格式。6.6.2核心代码闭源情况下的驱动程序开发在第三方驱动程序核心代码需要闭源的前提下,为保证内核升级时其内部调用的符号的可用性,驱动程序开发时应满足以下要求:a)除了在内核升级时保持不变的例如readl/writel/printk等最基本的工具函数外,不宜使用内核的API接口、数据结构和变量;b)不宜使用内核的常见的框架代码;c)内核版本一般是通过编译时的宏进行判断的,除非一个内核版本发布一个二进制文件,否则不应进行内核小版本号的判断处理;d)不应使用宏进行同架构内CPU的判断处理;e)应精简二进制部分的代码,只包含需要保护的代码。6.6.3核心代码的二进制封装应使用如下方法进行核心源码的二进制封装:a)应将核心逻辑层源码闭源,直接使用核心逻辑层源码编译生成的.o二进制文件;b)应使用xxd二进制显示和处理工具来将.o可执行文件转换成.o.hex十六进制编码文件后保存在源码目录中,并在编译时进行还原,以避免直接使用.o可执行文件生成ko动态链接文件时出现编译报错;c)当存在大量.o可执行文件需要转换时,宜编写脚本进行批量处理;d)编译时,应使用xxd工具将.o.hex十六进制编码文件还原成.o可执行文件,并通过make命令以生成ko动态链接文件;e)若.o可执行文件需要支持多个架构平台,应在源码目录下创建objs目录,并在目录中分架构路径存放对应的二进制文件。6.6.4驱动程序DKMS包制作制作和加载第三方驱动程序DKMS包的相关技术及步骤见附录E和附录F。驱动程序DKMS包制作应满足以下要求:a)应创建编包目录以及控制、配置文件;b)应复制源码以及封装二进制文件至编包目录中;c)应编写src/Makefile配置文件;d)应通过“dpkg-buildpackage-sa”命令来进行驱动程序DKMS包的编译。DB43/T2260—20216.7驱动程序的调试验证可使用printk系列函数、OOPS错误信息定位、FTrace分析函数以及perf性能统计工具来进行驱动程序的调试验证,使用方法及示例见附录G。7常用外设开发要求7.1打印机驱动开发7.1.1开发环境打印机驱动开发应在操作系统提供的统一的驱动开发环境中进行,开发环境提供了驱动编译所需要的组件及对应的参考版本号,形成统一的组件列表及组件号版本。打印机开发环境组件列表见表1。表1打印机开发环境组件123Qt4开发文件,用于打印驱动UI可视化交互开发4用于打印驱动软件开发,包含使用libcupsfilters567897.1.2运行环境打印机驱动应在操作系统提供的统一的运行环境中执行,不需单独安装运行环境,运行环境各组件和组件版本号,可以支撑多个打印机厂家多种设备的运行,操作系统版本宜向下兼容打印机驱动,减少驱动重复适配。打印机运行环境组件列表见表2。表2打印机运行环境组件1234DB43/T2260—2021表2打印机运行环境组件(续)56打印驱动程序可通过该库使用D-Bus进程间通信功能7.1.3配置信息当各打印机驱动开发商将驱动包安装到系统上或当操作系统集成这些驱动包时,打印机驱动厂商应提供相应的配置文件放置于指定目录下,以满足运行时的必要配置文件要求。配置文件应遵循以下要求:a)配置文件存放于/etc/kylin-printer/目录下,以.conf为后缀,配置文件名以各厂商名命名,如printer-xxx.conf;b)同一厂商的不同型号打印机,均写入该配置文件中,允许出现同一驱动库对应不同型号的打印机;c)有新驱动库安装入系统时,要求驱动包自行向该配置文件内追加内容;d)配置文件中应指明打印机的具体型号,以及该型号的驱动库存放在操作系统上的具体路径;e)驱动库应具有明确的标识符,安装于系统/usr/lib/kylin-printer/目录下,各厂商在此目录下建立以厂商名命名的目录,将其驱动库放置于其中。具体的配置格式实例见附录H。7.2扫描仪驱动开发7.2.1开发环境扫描仪驱动开发应在操作系统统一的驱动开发环境中进行,开发环境提供了驱动编译所需要的组件及对应的版本号,形成统一的组件列表及组件号版本。扫描仪开发环境组件列表见表3。表3扫描仪开发环境组件1234567用于获得系统库/模块的所有编译相关的信息,供扫描7.2.2运行环境扫描仪驱动应在操作系统统一的运行环境中执行,不需单独安装运行环境。运行环境应包含各组件名称和组件版本号,可支撑多个扫描仪厂家及多种扫描仪设备的运行;操作系统版本应向下兼容扫描仪DB43/T2260—2021驱动,减少扫描仪驱动在不同操作系统版本上多次适配。扫描仪运行环境组件列表见表4。表4扫描仪运行环境组件1237.3手写液晶屏驱动开发7.3.1开发环境手写液晶屏驱动开发应在操作系统统一的驱动开发环境中进行,开发环境提供了驱动编译所需要的组件及对应的版本号,形成统一的组件列表及组件号版本。手写液晶屏开发环境组件列表见表5。表5手写液晶屏开发环境组件1234567897.3.2运行环境手写液晶屏驱动应在操作系统统一的运行环境中执行,不需单独安装运行环境。运行环境应包含各组件名称和组件版本号,可支撑多个手写液晶屏厂家及多种手写液晶屏设备的运行;操作系统版本应向下兼容手写液晶屏驱动,减少手写液晶屏驱动在不同操作系统版本上多次适配。手写液晶屏运行环境组件列表见表6。表6手写液晶屏运行环境组件12DB43/T2260—2021设备驱动分类表A.1规定了设备驱动程序的类型和对应的常见设备。表A.1设备驱动分类DB43/T2260—2021驱动程序实现函数示例B.1示例1:驱动程序的入口函数驱动程序的入口函数的示例如下:{********编写驱动程序需要实现的}module_init(func_init);//声明B.2示例2:驱动程序的出口函数驱动程序的出口函数的示例如下:{***********关闭驱动程序初始化时占用的资源printk(“byebye%s!}module_exit(func_exit);//声明B.3示例3:驱动程序的信息声明驱动程序的信息声明的示例如下:MODULE_LICENSE("GPLMODULE_VERSION("版本");/MODULE_AUTHOR("作者");//MODULE_DESCRIPTION("对模块的描述");/B.4示例4:驱动卸载函数中的资源释放驱动卸载函数中的资源释放的示例如下:kfree(mem_devp);unregister_chrdev_region(MKDDB43/T2260—2021B.5示例5:核心数据结构的可扩展性实现实现核心数据结构的可扩展性的示例如下:/*扩展时只需要修改该指针所指向的数据结构,而无需修改void*private_data;}DB43/T2260—2021驱动程序可调用的内核函数接口表C.1规定了驱动程序可调用的内核函数接口。表C.1驱动程序中可调用的内核函数接口intregister_chrdev_rvoid__iomem*devm_ioreresource_size_tsize);resource_size_tsize);resource_size_tsize);voiddevm_iounmap(structdevice*dev,voidvoiddevm_ioremap_release(structdevice*dev,void*res);intplatform_get_irq(strucDB43/T2260—2021表C.1驱动程序中可调用的内核函数接口(续)staticinlinelong__must_chestructnet_device*alloc_etherdev(intsizeof_priv);分配及初始化net_devicevoidfree_netdev(structnet_device*dev);voidether_setup(strucvoidunregister_netdev(structnet_device*dev);voidnetif_start_queue(structnet_device*dev);voidnetif_stop_queue(structnet_device*dev);DB43/T2260—2021驱动程序相关的结构体D.1文件操作结构体字符设备驱动程序中的文件操作结构体的格式如下:/*文件操作结构体,声明了文件操作函数接口与驱动内的函数实现的关联,xx为对应驱};D.2网络设备操作结构体网络设备驱动程序中的网络设备操作结构体的格式如下:void*ndo_uninit)(structn/*超时时重新启动数据包发送过程或重新启动硬件等措施来恢复网络设};D.3显示帧缓存设备操作集结构体显示帧缓存设备驱动程序中的显示帧缓存设备操作集结构体的格式如下:DB43/T2260—2021};在各个接口函数中,显示帧缓存设备驱动程序应实现如下功能:a)fb_check_var函数●验证var中xres和yres参数是否能匹配,匹配失败则返回错误●设置时钟像素、水平同步和垂直同步等●根据BPP来设置R、G、B位域b)fb_set_par函数●判断var->bits_per_pixel,设置显示颜色模式●设置行长度、光标等其他硬件参数c)fb_pan_display函数●计算x、y偏移量●设置x、y偏移量d)fb_setcolreg函数●根据info->fix.visual值设置颜色●根据发送的blank信号来控制屏幕消隐的打开/关闭f)fb_fillrect函数●实现矩形绘制功能g)fb_copyarea函数●实现数据拷贝功能h)fb_imageblit函数●实现绘图功能DB43/T2260—2021DKMS技术说明及示例DKMS使用如下命令安装:注意:DKMS需要内核头文件。如果对应内核的头文件不存在,DKMS无法动态编译模块。E.2添加第三方模块第三方模块应放到“/usr/src”目录下面,命名格式为<module>-<module-version>。例如:cp210x模块,版本号为1.0,则完整的路径是:“/usr/src/cp210x-1.0”。E.2.2DKMS所需文件DKMS需要模块的DKMS配置文件、模块源码(或者源码编译出的“.o”文件)、Makefile文件。DKMS配置文件为dkms.conf,格式为:MAKE[0]="makeallKVERSION=$kernelBUILT_MODULE_NAME[0]="cDEST_MODULE_LOCATION[0]="Makefile文件如下:KVERSION:=$(shellunameall:$(MAKE)-C/lib/modules/$(KVERSclean:$(MAKE)-C/lib/modules/$(KVERSIOE.2.3DKMS处理流程具备DKMS的配置文件后,开始添加DKMS模块。DKMS模块的添加流程参见图E.1。图E.1DKMS模块添加流程DB43/T2260—2021使用如下命令查看DKMS的状态:E.2.3.1添加驱动添加cp210x模块,使用如下命令:也可以使用如下方式:然后查看状态,得到以下输出:此时cp210x模块处于added状态。E.2.3.2编译驱动编译cp210x模块,使用如下命令:也可以使用如下方式:然后查看状态,得到以下输出:cp210x,1.0,4.4.13-20此时cp210x模块处于built状态。E.2.3.3安装驱动安装cp210x模块,使用如下命令:也可以使用如下方式:然后查看状态,得到以下输出:E.2.3.4卸载驱动如果需要卸载第三方模块,使用如下命令:也可以使用如下方式:DB43/T2260—2021然后查看状态,得到以下输出:cp210x,1.0,4.4.13-20此时cp210x模块处于built状态。E.2.3.5移除驱动如果需要卸载第三方模块,使用如下命令:也可以使用如下方式:注意:--all参数是将指定模块从所有内核中移除。如果只想移除某个内核版本的指定模块,那么可以使用-k<kernel-version>参数移除与指定内核版本匹配的模块。然后查看状态:得到不包含cp210x模块的输出。如果系统中没有模块,则输出为空。E.2.3.6更换内核后自动编译模块如果需要系统在更新内核后能够自动编译模块,那么操作如下:ln-sf/usr/lib/dkms/dkms_autoinstalle注意:自动更新模块需要有与内核匹配的头文件。建议在内核安装后进行以下操作,预先将所有第三方模块编译完成。DB43/T2260—2021第三方内核模块打包F.1打包环境第三方内核模块使用DKMS技术加载到内核中。制作第三方内核模块需要使用DKMS包制作工具,生成制作软件包所需要的文件。F.2命名规则及制作流程F.2.1命名规则第三方内核模块包根据是否开源分为两类:——开源模块:无版权等敏感信息,内核适应性好,原始模块命名为“包名-dkms_版本号_arm64”;——闭源模块:版权比较敏感,只能提供二进制文件,适应性一般,原始模块命名为“包名-dkms-closed_版本号_arm64”。例如开源的原始模块名为cp210x.ko1.0版本,使用DKMS技术编出的第三方模块包包名为cp210x-dkms_1.0_arm64,包中的模块名为cp210x-dkms.ko。安装完第三方内核模块包后,第三方内核模块会放到“/lib/modules/内核版本号/extra/”目录下面。注意:使用kylin-dkms-creator工具生成编包目录,会根据输入参数自动追加dkms和closed。F.2.2制作流程第三方内核模块包的制作步骤如下:——使用kylin-dkms-creator创建编包目录;——复制源码或源码编译出的.o文件至编包目录中;——修改src/Makefile文件;——使用打包工具对编包目录进行打包。F.3kylin-dkms-creator工具详细说明安装kylin-dkms-creator工具:使用方式:Usageofkylin-dkms-creator:DB43/T2260—2021参数解释:-b开机自动加载模块;-c源码是否为闭源。若为闭源,则需要加入该选项;-d指定生成的源码包路径;-e指定开发者的邮箱;-i指定是否需要重新编译生成initrd(飞腾平台下由于initrd默认限制为16M,因此基本上会移除所有的非必要内核模块,所以此参数慎用);-m指定原始模块的名称,必填项;-n指定开发者姓名;-o指定编译模块需要的o文件列表,如:-o“a.o.dkmsb.o.dkmsc.o.dkms”;-v指定模块的版本号。注意:使用kylin-dkms-creator工具生成编包目录,会根据输入参数自动追加dkms和closed。使用cp210x驱动作为示例,完整的参数如下:developers@-d/home/dPackagedirectoryis"/home/developers/my-dkms/cp210x-dkms-closed-1.0".也可简化为:Packagedirectoryis"/tmp/build-dkms-package/cp210x-dkms-F.4使用示例F.4.1示例1:开源模块F.4.1.1前提例如cp210x模块。该模块有一个源文件:cp210x.c,编译时使用的Makefile文件如下:KDIR?=/lib/modules/$(shelluname-r)/bDB43/T2260—2021modules:clean:rm-rf*.o*.ko*.depend根据以上信息,通过kylin-dkms-creator工具制作使用dkms技术的软件包。F.4.1.2生成编包目录使用kylin-dkms-creator工具生成编包目录:[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-i-ndevelopers-edevelopers@-d/home/developers/my-dkms/输出:Everythingisdone.Packagedirectoryis"/home/developers/my-dkms/cp210x-dkms-1.0".F.4.1.3添加源码[kylin@Kylin~]$cpcp210x.c/home/developers/my-dkms/cp210x-dkms-1.0/srcF.4.1.4修改Makefile需要修改Makefile的“cp210x-dkms-objs”字段,改为cp210x.o。KERNELDIR?=/lib/modules/$(KERNELRELEAKERNELDIR?=/lib/modules/$(shelluname-r)modules:$(MAKE)-C$(KERNELDIR)clean:#install:#$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)moF.4.1.5编包返回编包目录,执行编包命令:编译完成后,第三方模块的dkms包位于编包目录的上一级目录中,名为:cp210x-dkms_1.0_arm64.***(格式为:模块名-dkms_版本号_体系结构.对应包后缀名)。DB43/T2260—2021F.4.2示例2:单二进制文件闭源模块F.4.2.1前提例如cp210x模块。该模块有一个源文件:cp210x.c,编译时使用的Makefile格式如下:KDIR?=/lib/modules/$(uname-r)/bmodules:clean:rm-rf*.o*.ko*.depend*.mod.o*.mod.cModule.手动编译后,生成了以下文件:cp210x.mod.c在这些文件中,系统只需要不涉密的.o文件:cp210x.o。F.4.2.2生成编包目录使用kylin-dkms-creator工具生成编包目录:developers@-d/home/dPackagedirectoryis"/home/developers/my-dkms/cp210x-dkms-closed-1.0".F.4.2.3添加.o文件将cp210x.o文件复制到编包目录下的src目录里面,重命名为.o.dkms:F.4.2.4检查Makefile需要检查Makefile的“cp210x-dkms-closed-objs”字段,前面的-o参数就是指定该字段的内容。注意:所有的“.o”文件应改成“.o.dkms”。完整Makefile如下:KERNELDIR?=/lib/modules/$(KERNELRELEAKERNELDIR?=/lib/modules/$(shelluname-r)DB43/T2260—2021modules:$(MAKE)-C$(KERNELDIR)clean:#install:F.4.2.5编包返回编包目录,执行编包命令:编译完成后,第三方模块的dkms包位于编包目录的上一级目录中,名为:cp210x-dkms-closed_1.0_arm64.***(格式为:模块名-dkms-closed_版本号_体系结构.对应包后缀名)。F.4.3示例3:多二进制文件闭源模块如示例2,多二进制文件的闭源模块,同样需要手动编译一遍,将需要的.o文件都复制到src目录下,并重命名为.o.dkms。注意:多二进制文件需要在-o参数中指定,例如:-o参数为:-o"a.o.dkmsb.o.dkm引号为英文半角引号。可人工检查src/Makefile的第二行字段,是否与需要的.o.dkms文件一致。F.4.4示例4:特殊Makefile需要特殊处理的内核模块,在编译时不能直接使用示例1、2、3中的Makefile。例如B模块编译依赖A模块的符号表。B模块在运行时需要依赖A模块的函数或者变量,此时B模块编译的时候需要引用保存A模块符号CRC值的文件:Module.symvers,编译时Makefile如下:KERNELDIR?=/lib/modules/$(shelluname-r)/bumodules:$(MAKE)-C$(KERNELDIR)M=$(PWD)KBUILD_EXTRA_SYMBOLS=./Mclean:在Makefile中多了一个参数,指定了保存A模块符号CRC值的文件。这种情况下,dkms包制作需要进行以下操作:DB43/T2260—2021——在编包目录的src目录下新建一个文件夹,名为:extra_symbols;——将A模块的Module.symvers文件复制到新建的extra_symbols目录中;——修改src目录下的Makefile,主要是修改编译命令,添加KBUILD_EXTRA_SYMBOLS参数。具体Makefile如下:KERNELDIR?=/lib/modules/$(KERNELRELEASKERNELDIR?=/lib/modules/$(shelluname-r)/bmodules:clean:#install:对于特殊Makefile,应将其对比标准Makefile的特殊之处移植到kylin-dkms-creator生成的Makefile中。注意:这里建立extra_symbols目录,并将Module.symvers文件复制到该目录中是为了防止在执行”makeclean”的时候Module.symvers被默认为编译中间文件而被删除。也可以使用以下方式解决:——重命名A模块的Module.symvers文件为A.symvers,并复制到src目录中;——修改Makefile中的“KBUILD_EXTRA_SYMBOLS”字段为“$(PWD)/A.symvers”。DB43/T2260—2021驱动程序的调试验证方法G.1利用printk系列函数利用printk系列函数是驱动中最为常用且最为行之有效的方式,它的使用方式与标准C的printf有些类似,但是也有很大的不同,可以在打印字符串的前面加上内核自定义的宏。内核一共定义了8种打印级别宏:宏定义用来表示需要打印的字符串的级别,值越小,级别越高,内核中有核外接口参数来控制是否将printk打印的字符串输出到控制台(包括屏幕、串口以及log日志文件等)。第一个6表示级别高于6的消息才会被输出到控制台,第二个4表示如果printk没有指定日志输出级别时,默认给他设置为4,第三个1表示最高可接受的日志级别为1,第四个7表示控制台日志级别的缺省值为7。为了简化代码,内核同样提供简化系列函数:printk(KERN_EMERGpr_fmt(fmt),##__VA_ARGS__)printk(KERN_ALERTpr_fmt(fmt),##__VA_ARGS__)printk(KERN_CRITpr_fmt(fmt),##__VA_ARGS__)printk(KERN_ERRpr_fmt(fmt),##__VA_ARGS__)printk(KERN_WARNINGpr_fmt(fmt),##__VA_ARGS__)printk(KERN_NOTICEpr_fmt(fmt),##__VA_ARGS__)printk(KERN_INFOpr_fmt(fmt),##__VA_ARGS__)printk(KERN_CONTfmt,##__VA_ARGS__)G.2利用OOPS信息定位OPPS信息是另外一种简便的调试方式,会将内核发生故障的现场打印出来,前提是需要计算机连DB43/T2260—2021接串口,或者机器配置了netconsole等远程串口服务。利用OOPS信息定位的方

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论