版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
15冊合訂本——第1部分:臺式微型計算機通用技術要求;——第2部分:便攜式微型計算機通用技術要求;——第3部分:服務器通用技術要求;——第4部分:操作系統(tǒng)通用技術要求;567891011——第12部分:國產(chǎn)化信息系統(tǒng)建設質量管理規(guī)范;1314——第15部分:云計算通用技術要求。 信息技術應用創(chuàng)新工程建設規(guī)范第9部分:驅動開發(fā)通用技術要求目 次前言 Ⅲ引言 Ⅴ圍 1范引文件 1語定義 1略語 2內(nèi)動體求 2編要求 2設驅模型 3文組形式 3驅程實現(xiàn) 3第方術用 4內(nèi)動體求 5字設驅程序 5塊備動序 6平設驅程序 7網(wǎng)設驅程序 9顯幀存?zhèn)涑绦?10驅程的DKMS制作 12驅程的試證 13用設發(fā)求 13打機動發(fā) 13掃儀動發(fā) 14手液屏動發(fā) 15附錄A(料)設驅動類 16附錄B(料)驅程序現(xiàn)數(shù)例 17附錄C(料)驅程序調(diào)的核數(shù)口 19附錄D(范)驅程序關結體 21附錄E(料)DKMS技術明示例 23附錄F(料)第方內(nèi)模打包 26附錄G(料)驅程序調(diào)驗方法 32附錄H(料)打機驅庫置件例 36I前 言GB/T1.1—20201請注意本文件的某些內(nèi)容可能涉及專利。本文件的發(fā)布機構不承擔識別專利的責任?!缎畔⒓夹g應用創(chuàng)新工程建設規(guī)范》分為以下幾個部分:——第1部分:臺式微型計算機通用技術要求;——第2部分:便攜式微型計算機通用技術要求;——第3部分:服務器通用技術要求;——第4部分:操作系統(tǒng)通用技術要求;567891011——第12部分:國產(chǎn)化信息系統(tǒng)建設質量管理規(guī)范;1314——第15部分:云計算通用技術要求。本部分為第9部分。IIIPAGEPAGE11PAGEPAGE10信息技術應用創(chuàng)新工程建設規(guī)范9本文件適用于國產(chǎn)操作系統(tǒng)上第三方驅動程序的開發(fā),也為第三方驅動程序的調(diào)試驗證提供指導。(GB/T15272—1994程序設計語言C下列術語和定義適用于本文件。3.1驅動程序driver驅動程序是硬件廠商根據(jù)操作系統(tǒng)編寫的配置文件,操作系統(tǒng)通過驅動來與控制設備和進行通信。3.2設備device是計算機系統(tǒng)中輸入、輸出設備(包括外存儲器)的統(tǒng)稱。設備對數(shù)據(jù)和信息起著傳輸、轉送和存儲的作用。3.3總線bus是計算機各種功能部件之間傳送信息的公共通信干線。3.4設備驅動模型devicedrivermodel設備驅動模型是操作系統(tǒng)內(nèi)核為了管理硬件上的設備和對應的驅動程序所制定的一套軟件體系。3.5平臺總線platformbus3.6平臺設備驅動模型platformdevicedrivermodel平臺設備驅動模型,即采用平臺總線的方式對驅動程序和設備進行管理的設備驅動模型。3.7字符設備characterdevice字符設備是不可尋址的,僅提供數(shù)據(jù)的流式訪問的設備。3.8塊設備blockdevice塊設備是以塊為單位的、可以尋址的設備。塊設備通常支持重定位操作,實現(xiàn)對數(shù)據(jù)的隨機訪問。3.9網(wǎng)絡設備networkdevice網(wǎng)絡設備通過網(wǎng)絡適配器和特定的網(wǎng)絡協(xié)議來完成網(wǎng)絡訪問的設備。3.10版本魔術信息vermagicinformation版本魔術信息是驅動程序內(nèi)存儲的、用來描述操作系統(tǒng)內(nèi)核版本號以及基礎內(nèi)核配置的字符串。3.11導出符號exportsymbol導出符號是操作系統(tǒng)內(nèi)核模塊導出的、可供其他模塊中的函數(shù)使用的全局變量或者函數(shù)。3.12GNU編譯器套件GNUCompilerCollectionGNUGNUCCObjective-CFortranJava、AdaGolibstdc++,libgcj)3.13OPPS信息OPPSInformation下列縮略語適用于本文件:ACPI:高級配置和電源管理接口(AdvancedConfigurationandPowerManagementInterface)CPU:中央處理器(CentralProcessingUnit)DKMS:動態(tài)內(nèi)核模塊支持(DynamicKernelModuleSupport)GNU:開源標準(GNU’sNotUnix)GPL:GNU通用公共許可證(GNUGeneralPublicLicense)I/O:輸入/輸出(Input/Output)NAPI:網(wǎng)絡數(shù)據(jù)處理API(NewAPI)PMU:性能監(jiān)視單元(PerformanceMonitoringUnit)GB/T15272-1994Linux檢查腳本來檢查驅動程序代碼的合規(guī)性。a)不使用內(nèi)核的API接口和數(shù)據(jù)結構;b)不使用內(nèi)核的框架代碼;CPUe)應采用獨立目錄存放驅動程序的代碼文件,驅動程序目錄:Makefileclinux/init.h、linux/module.hlinux/kernel.hKconfigReadme驅動程序開發(fā)應定義和實現(xiàn)驅動程序的入口函數(shù),驅動程序的入口函數(shù)應滿足以下要求:a)應使用init初始化修飾符來修飾入口函數(shù);應通過內(nèi)核提供的module_initB.1。驅動程序開發(fā)應定義和實現(xiàn)驅動程序的出口函數(shù),驅動程序的出口函數(shù)應滿足以下要求:a)應使用exit退出修飾符來修飾出口函數(shù);應通過內(nèi)核提供的module_exit驅動程序出口函數(shù)示例見附錄B.2。B.3。removeremoveremoveB.4。若驅動程序中注冊了回調(diào)函數(shù),則remove卸載函數(shù)中應包含注銷回調(diào)函數(shù)的操作。應通過以下方式來實現(xiàn)驅動程序核心數(shù)據(jù)的可擴展性:a)在數(shù)據(jù)結構中添加reserved保留字段;b)在數(shù)據(jù)結構中添加表示私有數(shù)據(jù)的指針,擴展時只需要修改該指針所指向的數(shù)據(jù)結構,而無需修改核心數(shù)據(jù)結構。核心數(shù)據(jù)結構的可擴展性實現(xiàn)示例見附錄B.5。probe驅動程序應實現(xiàn)probe探測函數(shù),用于完成設備驅動程序注冊的最后收尾工作。probe。access_ok驅動程序開發(fā)時應添加必要的調(diào)試統(tǒng)計變量,以便于對驅動程序的調(diào)試測試。調(diào)試統(tǒng)計變量宜實現(xiàn)分級開關,以提供各種粒度的調(diào)試測試選項。驅動程序應使用內(nèi)核提供的EXPORT_SYMBOL_GPL宏或EXPORT_SYMBOL宏來導出符號。EXPORT_SYMBOL_GPL宏導出的符號適用于包含GPL許可的模塊,EXPORT_SYMBOL宏導出的符號適用于任何模塊。示例:驅動導出符號的兩種方式EXPORT_SYMBOL(func1);EXPORT_SYMBOL_GPL(func2);EXPORT_SYMBOL(func1);EXPORT_SYMBOL_GPL(func2);1。圖1字符設備驅動程序框架字符設備驅動包括以下部分:file_operationfile_operation/dev寫、close(對/devfile_operation/devllseek、readwrite、open、closefile_operationsfile_operations文件操作結構體格式應符合附錄D.1要求。字符設備驅動程序應基于平臺驅動模型注冊,包含以下內(nèi)容:a)應提前準備好驅動程序對應的主設備號,主設備號應使用內(nèi)核已注冊的主設備號之外的數(shù)值;b)應使用平臺驅動結構platform_driver封裝驅動程序信息;c)platform_driver_register(drv字符設備的注冊應包含如下內(nèi)容:01048575;cdevfile_operationscdevsysclassACPI塊設備驅動程序框架分為三個層次,見圖2。圖2塊設備驅動程序框架I/OI/OI/OI/OI/OI/OI/O塊設備驅動程序的函數(shù)接口應符合以下要求:probeI/OI/O示例:I/O處理函數(shù)接口staticblk_qc_txxx_make_request(structrequest_queue*q,structbio*bio);staticblk_qc_txxx_make_request(structrequest_queue*q,structbio*bio);I/O示例:中斷處理函數(shù)接口staticirqreturn_tgdrom_command_interrupt(intirq,void*dev_id);staticirqreturn_tgdrom_command_interrupt(intirq,void*dev_id);ioctl、openclose示例:設備操作函數(shù)接口int(*ioctl)(structblock_device*,fmode_t,unsigned,unsignedlong);int(*ioctl)(structblock_device*,fmode_t,unsigned,unsignedlong);/*Ioctl接口*/int(*open)(structblock_device*,fmode_t); /*Open*/void(*release)(structgendisk*,fmode_t); /*Close*/塊設備驅動程序的加載主要包括以下內(nèi)容:a)alloc_diskgendiskregister_blkdev(I/Od)gendiskadd_disk(塊設備驅動程序的卸載主要包括以下內(nèi)容:del_gendisk應使用blkdev()塊設備注銷函數(shù)注銷設備并釋放對設備的引用。平臺設備驅動程序可分為平臺控制器驅動和平臺設備驅動兩個部分,驅動框架見圖3。圖3平臺設備驅動程序子系統(tǒng)框架平臺設備驅動程序提供給應用層的接口應使用標準接口,提供的接口應有說明以及用例。提供的對外接口應采用dev節(jié)點方式或sysfs節(jié)點方式。設備masterslavemaster驅動程序和設備注冊時,應使用系統(tǒng)內(nèi)核提供的接口完成注冊,包括:a)總線注冊控制器驅動的接口;masterslaveslavemasterxfer應使用標準的設備描述接口來描述和獲取設備資源信息,包括物理地址\中斷號\端口等其他可以描述的信息。標準的驅動程序加載應包括以下內(nèi)容:a)acpitablec)驅動程序應提供設備樹和acpitable匹配節(jié)點的方法。4。圖4網(wǎng)絡設備驅動程序框架a)net_device結構體,該結構體是設備驅動功能層各函數(shù)的容器;net_devicenet_devicenet_device網(wǎng)絡設備驅動程序接口應包含初始化接口,發(fā)送接口和接收接口。net_device;注銷網(wǎng)絡設備d)網(wǎng)絡設備驅動程序開發(fā)應使用內(nèi)核提供的結構體來描述網(wǎng)絡設備及設備操作,應包括以下結構體:a)sk_buff結構體是網(wǎng)絡驅動程序框架中信息的載體,是網(wǎng)絡分層模型中對數(shù)據(jù)進行層層打包以及層層解包的載體;net_devicenet_device_opsD.2要求。NAPI顯示幀緩存設備驅動程序框架見圖5。圖5顯示幀緩存設備驅動程序框架mmapreadopenioctl應通過以下兩種方式進行驅動程序注冊:PCIpci_register_driverPCIPCIplatform_driver_register顯示幀緩存設備驅動程序在加載時,應允許通過模塊參數(shù)控制其加載過程。在驅動開發(fā)時,可用的模塊參數(shù)應使用MODULE_PARM_DESC宏來進行聲明,并通過module_param_named函數(shù)來進行參數(shù)傳遞。probeproberequest_irq;I/O/request_mem_regionI/O/ioremapI/O/fb_infopci_resource_startPCIDMAdma_alloc_writecombineDMAcache;fb_check_varvarframebufferi)創(chuàng)建硬件相關sys系統(tǒng)文件、節(jié)點等。removeremoveframebufferb)關閉硬件設備;c)解除顯存映射;d)釋放顯存、中斷、釋放fb_info結構體內(nèi)存以及I/O端口/內(nèi)存資源。DKMSDKMSDKMSb)第三方驅動程序的核心代碼可以閉源,但應保證生成的二進制模塊的兼容性;c)宜通過包創(chuàng)建工具自動生成編譯DKMS軟件包所需的控制和配置文件;d)根據(jù)是否閉源,打包后的DKMS包應遵循如下命名規(guī)則:開源模塊命名為:原始模塊名-dkms_版本號_CPU架構.軟件包格式;閉源模塊命名為:原始模塊名-dkms-closed_版本號_CPU架構.軟件包格式。readl/writel/printkAPICPU應使用如下方法進行核心源碼的二進制封裝:oxxdoo.hexoko.oxxd.o.hexomakeko.oobjsDKMSDKMSE。DKMSsrc/Makefiled)應通過“dpkg-buildpackage-sa”命令來進行驅動程序DKMS包的編譯。printkOOPSFTraceperf。1。表1打印機開發(fā)環(huán)境組件序號組件名稱組件描述組件參考版本號1libcups2-dev通用UNIX打印系統(tǒng)cups開發(fā)庫2.2.22libcupsimage2-dev通用UNIX打印系統(tǒng)cups圖像開發(fā)庫2.2.23libqt4-devQt4開發(fā)文件,用于打印驅動UI可視化交互開發(fā)4.8.74libcupsfilters-dev用于打印驅動軟件開發(fā),包含使用libcupsfilters開發(fā)驅動程序的頭文件1.13.45qt4-qmake用于打印驅動軟件Qt4編譯4.8.76libusb-1.0.0-dev用于打印驅動與USB設備通信開發(fā)1.0.207libjpeg-dev用于打印驅動對圖片進行壓縮和解壓8c-28libnotify4用于在操作系統(tǒng)下提示打印機狀態(tài)信息0.7.6-29autoconf用于對開源模塊源碼生成自動配置編譯文件2.69-610gcc/g++用于打印驅動程序源代碼GNUC/C++編譯4:5.3.111qt5-qmake用于打印驅動軟件Qt5編譯5.6.12。表2打印機運行環(huán)境組件序號組件名稱組件描述組件參考版本號1CUPS打印服務系統(tǒng),打印驅動運行在該系統(tǒng)上2.2.22Qt4為使用Qt開發(fā)的程序提供運行時環(huán)境4.8.73Qt5為使用Qt開發(fā)的程序提供運行時環(huán)境5.6.14system-config-printer提供打印機設備管理、任務管理等功能1.5.7表2打印機運行環(huán)境組件(續(xù))序號組件名稱組件描述組件參考版本號5libjpeg提供圖片壓縮和解壓功能8c-26dbus打印驅動程序可通過該庫使用D-Bus進程間通信功能1.10.6配置文件應遵循以下要求:/etc/kylin-printer/.confprinter-xxx.conf;/usr/lib/kylin-printer/下建立以廠商名命名的目錄,將其驅動庫放置于其中。具體的配置格式實例見附錄H。。表3掃描儀開發(fā)環(huán)境組件序號組件名稱組件描述組件參考版本號1libsane-dev用于掃描儀驅動開發(fā)1.0.25+201505282libusb-1.0.0-dev用于掃描儀驅動與USB設備通信開發(fā)1.0.203libjpeg-dev用于掃描儀驅動對圖片進行壓縮和解壓8c-24autoconf用于對開源模塊源碼生成自動配置編譯文件2.69-65gcc/g++用于掃描儀驅動程序源代碼編譯4:5.3.16git用于掃描儀驅動源代碼庫管理1:2.7.47pkg-config用于獲得系統(tǒng)庫/模塊的所有編譯相關的信息,供掃描儀驅動開發(fā)參考和引用0.29.1驅動,減少掃描儀驅動在不同操作系統(tǒng)版本上多次適配。掃描儀運行環(huán)境組件列表見表4。表4掃描儀運行環(huán)境組件序號組件名稱組件描述組件版本號1libsane通用掃描儀接口1.0.25+201505282libsane-common通用掃描儀接口1.0.25+201505283libusb-1.0.0用于掃描儀驅動與USB設備通信開發(fā)1.0.20。表5手寫液晶屏開發(fā)環(huán)境組件序號組件名稱組件描述組件參考版本號1libqt4-devQt4用于手寫液晶屏驅動軟件開發(fā)4.8.72qt4-qmakeQt4用于手寫液晶屏驅動軟件編譯4.8.73libusb-1.0.0-dev用于手寫液晶屏驅動與USB設備通信開發(fā)1.0.204autoconf用于對開源模塊源碼生成自動配置編譯文件2.69-65gcc/g++用于手寫液晶屏驅動程序源代碼編譯4:5.3.16git用于手寫液晶屏驅動源代碼庫管理1:2.7.47pkg-config用于獲得系統(tǒng)庫/模塊的所有編譯相關的信息,供打印驅動開發(fā)參考和引用0.29.18openssl用于手寫液晶屏驅動軟件開發(fā)1.0.2g-19libqt5-devQt5用于手寫液晶屏驅動軟件編譯5.6.110qt5-qmakeQt5用于手寫液晶屏驅動軟件編譯5.6.16。表6手寫液晶屏運行環(huán)境組件序號組件名稱組件描述組件參考版本號1Qt4Qt4提供手寫液晶屏設備管理、任務管理等功能4.8.72Qt5Qt5提供手寫液晶屏設備管理、任務管理等功能5.6.1附錄A()表A.1規(guī)定了設備驅動程序的類型和對應的常見設備。表A.1設備驅動分類設備驅動類型對應的常見設備字符設備驅動鼠標、鍵盤、觸摸屏、攝像頭、LED設備、聲卡、打印機、IIC、SPI等塊設備驅動硬盤、磁盤、U盤、SD卡等平臺設備驅動I2C、IIS、RTC、看門狗等網(wǎng)絡設備驅動有線網(wǎng)卡、無線網(wǎng)卡、Bridge等顯示幀緩存設備驅動顯存抽象后的一種設備附錄B(資料性)驅動程序實現(xiàn)函數(shù)示例1驅動程序的入口函數(shù)的示例如下:staticintstaticintinitfunc_init(void){printk(“hellomodule!\n”);********編寫驅動程序需要實現(xiàn)的基礎功能*****pci_register_driver(&driver);//在pci總線上注冊驅動return0;//0:加載成功!非0:加載失??!}module_init(func_init);//聲明入口函數(shù)2驅動程序的出口函數(shù)的示例如下:staticvoidstaticvoidexitfunc_exit(void){***********關閉驅動程序初始化時占用的資源***********printk(“byebye%s!\n”,“module”);}module_exit(func_exit);//聲明出口函數(shù)3驅動程序的信息聲明的示例如下:MODULE_LICENSE("GPL");MODULE_VERSION("版本");//可選MODULE_AUTHOR("作者");//可選MODULE_LICENSE("GPL");MODULE_VERSION("版本");//可選MODULE_AUTHOR("作者");//可選MODULE_DESCRIPTION("對模塊的描述");//可選4驅動卸載函數(shù)中的資源釋放的示例如下:/*內(nèi)存資源的釋放*//*內(nèi)存資源的釋放*/for(i=0;i<MEMDEV_NR_DEVS;i++)kfree(mem_devp[i].data);kfree(mem_devp);cdev_del(&cdev); //注銷字符設備unregister_chrdev_region(MKDEV(mem_major,0),MEMDEV_NR_DEVS);//釋放設備號/*刪除sys文件系統(tǒng)對應的字符設備節(jié)點*/for(i=0;i<MEMDEV_NR_DEVS;i++)device_destroy(class_memdev,MKDEV(mem_major,i));class_destroy(class_memdev);5實現(xiàn)核心數(shù)據(jù)結構的可擴展性的示例如下:structsimple{structsimple{***********核心數(shù)據(jù)***********/*指向私有數(shù)據(jù)的指針*//*擴展時只需要修改該指針所指向的數(shù)據(jù)結構,而無需修改核心數(shù)據(jù)結構*/void*private_data;}附錄C(資料性)驅動程序可調(diào)用的內(nèi)核函數(shù)接口表C.1規(guī)定了驅動程序可調(diào)用的內(nèi)核函數(shù)接口。表C.1驅動程序中可調(diào)用的內(nèi)核函數(shù)接口內(nèi)核函數(shù)接口函數(shù)說明MKDEV(ma,mi)intregister_chrdev_region(dev_tfrom,unsignedcount,constchar*name);設備號申請函數(shù)voidcdev_init(structcdev*cdev,conststructfile_operations*fops);cdev結構初始化函數(shù)intcdev_add(structcdev*p,dev_tdev,unsignedcount);將cdev加入cdev設備組class_create(owner,name)注冊sys設備類structdevice*device_create(structclass*class,structdevice*parent,dev_tdevt,void*drvdata,constchar*fmt,...);注冊sys設備(組)staticinlinebooldevice_property_read_bool(structdevice*dev,constchar*propname);staticinlineintdevice_property_read_u8(structdevice*dev,constchar*propname,u8*val);staticinlineintdevice_property_read_u16(structdevice*dev,constchar*propname,u16*val);staticinlineintdevice_property_read_u32(structdevice*dev,constchar*propname,u32*val);staticinlineintdevice_property_read_u64(structdevice*dev,constchar*propname,u64*val);從ACPIDSDT表或設備樹中獲取設備屬性voidiomem*devm_ioremap(structdevice*dev,resource_size_toffset,resource_size_tsize);voidiomem*devm_ioremap_nocache(structdevice*dev,resource_size_toffset,resource_size_tsize);voidiomem*devm_ioremap_wc(structdevice*dev,resource_size_toffset,resource_size_tsize);獲取iomem資源voiddevm_iounmap(structdevice*dev,voidiomem*addr);voiddevm_ioremap_release(structdevice*dev,void*res);釋放iomem資源structresource*platform_get_resource(structplatform_device*,unsignedint,unsignedint);硬件地址資源的獲取intplatform_get_irq(structplatform_device*dev,unsignedintnum);硬件中斷資源的獲取voidiomem*devm_ioremap_resource(structdevice*dev,structresource*res);ioremap(addr,size);iounmap(voidiomem*);地址資源映射函數(shù)staticinlinestructclk*devm_clk_get(structdevice*dev,constchar*id);staticinlinestructclk*clk_get(structdevice*dev,constchar*id);時鐘資源獲取staticinlineintclk_prepare_enable(structclk*clk);時鐘使能staticinlinevoidclk_disable_unprepare(structclk*clk);時鐘失效staticinlineunsignedlongclk_get_rate(structclk*clk);獲取時鐘頻率staticinlineintclk_set_rate(structclk*clk,unsignedlongrate);設置時鐘頻率表C.1驅動程序中可調(diào)用的內(nèi)核函數(shù)接口(續(xù))內(nèi)核函數(shù)接口函數(shù)說明staticinlinelongmust_checkPTR_ERR(forceconstvoid*ptr);staticinlineboolmust_checkIS_ERR(forceconstvoid*ptr);錯誤處理相關structnet_device*alloc_etherdev(intsizeof_priv);structnet_device*alloc_netdev(intsizeof_priv,constchar*name,unsignedcharname_assign_type,void(*setup)(structnet_device*));分配及初始化net_device對象voidfree_netdev(structnet_device*dev);釋放net_device對象voidether_setup(structnet_device*dev);以太網(wǎng)的初始化intregister_netdev(structnet_device*dev);注冊net_device的接口voidunregister_netdev(structnet_device*dev);注銷net_device的接口voidnetif_start_queue(structnet_device*dev);開啟網(wǎng)絡發(fā)送隊列voidnetif_stop_queue(structnet_device*dev);停止網(wǎng)絡發(fā)送隊列附錄D(規(guī)范性)驅動程序相關的結構體字符設備驅動程序中的文件操作結構體的格式如下:/*文件操作結構體,聲明了文件操作函數(shù)接口與驅動內(nèi)的函數(shù)實現(xiàn)的關聯(lián),xx為對應驅動名稱。*/staticconststructfile_operationsft_xx_fops={/*文件操作結構體,聲明了文件操作函數(shù)接口與驅動內(nèi)的函數(shù)實現(xiàn)的關聯(lián),xx為對應驅動名稱。*/staticconststructfile_operationsft_xx_fops={.owner=THIS_MODULE,.llseek=ft_xx_llseek,.read=ft_xx_read,.write=ft_xx_write,.open=ft_xx_open,.release=ft_xx_release,.mmap=ft_xx_mmap,};網(wǎng)絡設備驅動程序中的網(wǎng)絡設備操作結構體的格式如下:structnet_device_ops{structnet_device_ops{int(*ndo_init)(structnet_device*dev);void*ndo_uninit)(structnet_device*dev);/*I/OIRQ、DMAint(*ndo_open)(structnet_device*dev);/*停止網(wǎng)絡接口設備,與open()函數(shù)的作用相反*/int(*ndo_stop)(structnet_device*dev);/*啟動數(shù)據(jù)包的發(fā)送*/netdev_tx_t(*ndo_start_xmit)(structsk_buff*skb,structnet_device*dev);void(*ndo_change_rx_flags)(structnet_device*dev,intflags);void(*ndo_set_rx_mode)(structnet_device*dev);/*設置設備的MAC地址*/int(*ndo_set_mac_address)(structnet_device*dev,void*addr);int(*ndo_validate_addr)(structnet_device*dev);/*進行設備特定的I/O控制*/int(*ndo_do_ioctl)(structnet_device*dev,structifreq*ifr,intcmd);/*配置接口,也可用于改變設備的I/O地址和中斷號*/int(*ndo_set_config)(structnet_device*dev,structifmap*map);int(*ndo_change_mtu)(structnet_device*dev,intnew_mtu);int(*ndo_neigh_setup)(structnet_device*dev,structneigh_parms*);/*超時時重新啟動數(shù)據(jù)包發(fā)送過程或重新啟動硬件等措施來恢復網(wǎng)絡設備到正常狀態(tài)*/void(*ndo_tx_timeout)(structnet_device*dev);};顯示幀緩存設備驅動程序中的顯示幀緩存設備操作集結構體的格式如下:/*顯示幀緩存設備操作結構體,xx為對應驅動名稱*/staticstructfb_opsxxx_ops={/*顯示幀緩存設備操作結構體,xx為對應驅動名稱*/staticstructfb_opsxxx_ops={.owner =THIS_MODULE,.fb_check_var =s3c2410fb_check_var,.fb_set_par =s3c2410fb_set_par,.fb_blank =s3c2410fb_blank,.fb_setcolreg =s3c2410fb_setcolreg,.fb_fillrect =cfb_fillrect,.fb_copyarea =cfb_copyarea,.fb_imageblit =cfb_imageblit,};在各個接口函數(shù)中,顯示幀緩存設備驅動程序應實現(xiàn)如下功能:a)fb_check_var函數(shù)varxresyresBPPR、GBb)fb_set_parvar->bits_per_pixelc)fb_pan_display、y、yd)fb_setcolreginfo->fix.visualblank/g)fb_copyareah)fb_imageblit附錄E(資料性)DKMS技術說明及示例安裝DKMS使用如下命令安裝:[kylin@Kylin~]$sudoapt-getinstalldkms[kylin@Kylin~]$sudoapt-getinstalldkms注意:DKMS需要內(nèi)核頭文件。如果對應內(nèi)核的頭文件不存在,DKMS無法動態(tài)編譯模塊。<module>-<module-version1.“/ur/s/cp21x-1DKMSPACKAGE_NAME="cp210x"PACKAGE_VERSION="1.0"CLEAN="makeclean"MAKE[0]="makeallKVERSION=$kernelver"BUILT_MODULE_NAME[0]="cp210x"DEST_MODULE_LOCATION[0]="/updates"AUTOINSTALL="yes"DKMSDKMS.o、MakefilePACKAGE_NAME="cp210x"PACKAGE_VERSION="1.0"CLEAN="makeclean"MAKE[0]="makeallKVERSION=$kernelver"BUILT_MODULE_NAME[0]="cp210x"DEST_MODULE_LOCATION[0]="/updates"AUTOINSTALL="yes"Makefile文件如下:obj-m:=cp210x.oKVERSION:=$(shelluname-r)all:obj-m:=cp210x.oKVERSION:=$(shelluname-r)all:$(MAKE)-C/lib/modules/$(KVERSION)/buildM=$(PWD)modulesclean:$(MAKE)-C/lib/modules/$(KVERSION)/buildM=$(PWD)cleanDKMS具備DKMS的配置文件后,開始添加DKMS模塊。DKMS模塊的添加流程參見圖E.1。卸載已添加狀態(tài)僅源碼目錄狀態(tài)已建立狀態(tài)已安裝狀態(tài)添加 建立已添加狀態(tài)僅源碼目錄狀態(tài)已建立狀態(tài)已安裝狀態(tài)移除E.1DKMS使用如下命令查看DKMS的狀態(tài):[kylin@Kylin~]#dkmsstatus[kylin@Kylin~]#dkmsstatus添加cp210x模塊,使用如下命令:[kylin@Kylin~]#dkmsaddcp210x/1.0[kylin@Kylin~]#dkmsaddcp210x/1.0[kylin@Kylin~]#格式:dkmsadd<module>/<module-version>也可以使用如下方式:[kylin@Kylin~]#dkmsadd-mcp210x-v1.0[kylin@Kylin~]#dkmsadd-mcp210x-v1.0[kylin@Kylin~]#格式:dkmsadd-m<module>-v<module-version>然后查看狀態(tài),得到以下輸出:[kylin@Kylin~]#dkmsstatuscp210x,1.0:added[kylin@Kylin~]#dkmsstatuscp210x,1.0:added此時cp210x模塊處于added狀態(tài)。編譯cp210x模塊,使用如下命令:[kylin@Kylin~]#dkmsbuildcp210x/1.0[kylin@Kylin~]#dkmsbuildcp210x/1.0[kylin@Kylin~]#格式:dkmsbuild<module>/<module-version>也可以使用如下方式:[kylin@Kylin~]#dkmsbuild-mcp210x-v1.0[kylin@Kylin~]#dkmsbuild-mcp210x-v1.0[kylin@Kylin~]#格式:dkmsbuild-m<module>-v<module-version>然后查看狀態(tài),得到以下輸出:[kylin@Kylin~]#dkmsstatus[kylin@Kylin~]#dkmsstatuscp210x,1.0,4.4.13-20161212.kylin.5.server,aarch64:built此時cp210x模塊處于built狀態(tài)。安裝cp210x模塊,使用如下命令:[kylin@Kylin~]#dkmsinstallcp210x/1.0[kylin@Kylin~]#dkmsinstallcp210x/1.0[kylin@Kylin~]#格式:dkmsinstall<module>/<module-version>也可以使用如下方式:[kylin@Kylin~]#dkmsinstall-mcp210x-v1.0[kylin@Kylin~]#dkmsinstall-mcp210x-v1.0[kylin@Kylin~]#格式:dkmsinstall-m<module>-v<module-version>然后查看狀態(tài),得到以下輸出:[kylin@Kylin~]#dkmsstatus[kylin@Kylin~]#dkmsstatuscp210x,1.0,4.4.13-20161212.kylin.5.server,aarch64:installed此時cp210x模塊處于installed狀態(tài)。如果需要卸載第三方模塊,使用如下命令:[kylin@Kylin~]#dkmsuninstallcp210x/1.0[kylin@Kylin~]#dkmsuninstallcp210x/1.0[kylin@Kylin~]#格式:dkmsuninstall<module>/<module-version>也可以使用如下方式:[kylin@Kylin~]#dkmsuninstall-mcp210x-v1.0[kylin@Kylin~]#dkmsuninstall-mcp210x-v1.0[kylin@Kylin~]#格式:dkmsuninstall-m<module>-v<module-version>然后查看狀態(tài),得到以下輸出:[kylin@Kylin~]#dkmsstatus[kylin@Kylin~]#dkmsstatuscp210x,1.0,4.4.13-20161212.kylin.5.server,aarch64:built此時cp210x模塊處于built狀態(tài)。如果需要卸載第三方模塊,使用如下命令:[kylin@Kylin~]#dkmsremovecp210x/1.0–all[kylin@Kylin~]#dkmsremovecp210x/1.0–all[kylin@Kylin~]#格式:dkmsremove<module>/<module-version>--all也可以使用如下方式:[kylin@Kylin~]#dkmsremove-mcp210x-v1.0–all[kylin@Kylin~]#dkmsremove-mcp210x-v1.0–all[kylin@Kylin~]#格式:dkmsremove-m<module>-v<module-version>--all-k<kernel-version>然后查看狀態(tài):[kylin@Kylin~]#dkmsstatus[kylin@Kylin~]#dkmsstatus得到不包含cp210x模塊的輸出。如果系統(tǒng)中沒有模塊,則輸出為空。如果需要系統(tǒng)在更新內(nèi)核后能夠自動編譯模塊,那么操作如下:ln-sf/usr/lib/dkms/dkms_autoinstaller/etc/init.d/dkms_autoinstallersystemctldaemon-reloadln-sf/usr/lib/dkms/dkms_autoinstaller/etc/init.d/dkms_autoinstallersystemctldaemon-reloadsystemctlenabledkms_autoinstaller注意:自動更新模塊需要有與內(nèi)核匹配的頭文件。建議在內(nèi)核安裝后進行以下操作,預先將所有第三方模塊編譯完成。forKernelin`ls/lib/modules/`dodkmsautoinstall-k$KernelforKernelin`ls/lib/modules/`dodkmsautoinstall-k$Kerneldone附錄F(資料性)第三方內(nèi)核模塊打包第三方內(nèi)核模塊使用DKMS技術加載到內(nèi)核中。制作第三方內(nèi)核模塊需要使用DKMS包制作工具,生成制作軟件包所需要的文件。第三方內(nèi)核模塊包根據(jù)是否開源分為兩類:dkms_am6——閉源模塊:版權比較敏感,只能提供二進制文件,適應性一般,原始模塊命名為“包名-dkmscloed_a6cp210x.ko1.0DKMScp210x-dkms.ko。/lib/modules/注意:使用kylin-dkms-creator工具生成編包目錄,會根據(jù)輸入?yún)?shù)自動追加dkms和closed。第三方內(nèi)核模塊包的制作步驟如下:——使用kylin-dkms-creator創(chuàng)建編包目錄;——復制源碼或源碼編譯出的.o文件至編包目錄中;——修改src/Makefile文件;——使用打包工具對編包目錄進行打包。kylin-dkms-creator安裝kylin-dkms-creator工具:[kylin@Kylin~]$sudoapt-getinstallkylin-dkms-creator[kylin@Kylin~]$sudoapt-getinstallkylin-dkms-creator使用方式:[kylin@Kylin~]$kylin-dkms-creator--helpUsageofkylin-dkms-creator:[kylin@Kylin~]$kylin-dkms-creator--helpUsageofkylin-dkms-creator:-bAutomaticallyloadmoduleatboot-cClosedsource-dstringBuildPackageDir(default"./build-dkms-package")-estringDeveloperemail(default"\hDeveloper@")-iNeedremakeinitrd-mstringModulename(required)-nstring-nstringDevelopername(default"Developer")-ostringNeeded.ofilesto.ko-vstringModuleversion(default"1.0")參數(shù)解釋:-b開機自動加載模塊;-c源碼是否為閉源。若為閉源,則需要加入該選項;-d指定生成的源碼包路徑;-e指定開發(fā)者的郵箱;-iinitrd;-m指定原始模塊的名稱,必填項;-n指定開發(fā)者姓名;-o指定編譯模塊需要的o-o“a.dkms.o.kmsc.odkm-v指定模塊的版本號。注意:使用kylin-dkms-creator工具生成編包目錄,會根據(jù)輸入?yún)?shù)自動追加dkms和closed。模塊原始名版本號生成的包名安裝到系統(tǒng)中的模塊名開源cp210x.ko1.0cp210x-dkms_1.0_arm64cp210x-dkms.ko閉源cp210x.ko1.0cp210x-dkms-closed_1.0_arm64cp210x-dkms-closed.ko使用cp210x驅動作為示例,完整的參數(shù)如下:[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-b-i-c-o“cp210x.o.dkms”-ndevelopers[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-b-i-c-o“cp210x.o.dkms”-ndevelopers-e\hdevelopers@-d/home/developers/my-dkms/輸出:Everythingisdone.Everythingisdone.Packagedirectoryis"/home/developers/my-dkms/cp210x-dkms-closed-1.0".也可簡化為:[kylin@Kylin~]$kylin-dkms-creator-mcp210x[kylin@Kylin~]$kylin-dkms-creator-mcp210x輸出:Everythingisdone.Everythingisdone.Packagedirectoryis"/tmp/build-dkms-package/cp210x-dkms-1.0".1前提例如cp210x模塊。該模塊有一個源文件:cp210x.c,編譯時使用的Makefile文件如下:ifneq($(KERNELRELEASE),)ifneq($(KERNELRELEASE),)obj-m:=cp210x.oelseKDIR?=/lib/modules/$(shelluname-r)/buildPWD:=$(shellpwd)modules:modules:$(MAKE)-C$(KDIR)M=$(PWD)modulesall:modulesclean:rm-rf*.o*.ko*.depend*.mod.o*.mod.cModule.*modules.*.*.cmd.tmp_versionsendif根據(jù)以上信息,通過kylin-dkms-creator工具制作使用dkms技術的軟件包。使用kylin-dkms-creator工具生成編包目錄:[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-i-ndevelopers-e[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-i-ndevelopers-e\hdevelopers@-d/home/developers/my-dkms/輸出:Everythingisdone.Everythingisdone.Packagedirectoryis"/home/developers/my-dkms/cp210x-dkms-1.0".將cp210x.c文件復制到編包目錄下的src目錄下:[kylin@Kylin~]$cpcp210x.c/home/developers/my-dkms/cp210x-dkms-1.0/src[kylin@Kylin~]$cpcp210x.c/home/developers/my-dkms/cp210x-dkms-1.0/srcMakefile需要修改Makefile的“cp210x-dkms-objs”字段,改為cp210x.o。obj-m:=cp210x-dkms.ocp210x-dkms-objs:=cp210x.oifneq($(KERNELRELEASE),)obj-m:=cp210x-dkms.ocp210x-dkms-objs:=cp210x.oifneq($(KERNELRELEASE),)KERNELDIR?=/lib/modules/$(KERNELRELEASE)/buildelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildendifPWD:=$(shellpwd).PHONY:allall:cleanmodules#install.PHONY:modulesmodules:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)modules.PHONY:cleanclean:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)clean#.PHONY:install#install:# $(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)modules_install編包返回編包目錄,執(zhí)行編包命令:[kylin@Kylin~]$cd/home/developers/my-dkms/cp210x-dkms-1.0/[kylin@Kylin~]$dpkg-buildpackage-sa[kylin@Kylin~]$cd/home/developers/my-dkms/cp210x-dkms-1.0/[kylin@Kylin~]$dpkg-buildpackage-sa編譯完成后,第三方模塊的dkms包位于編包目錄的上一級目錄中,名為:cp210x-dkms_1.0_arm64.***(-dkms__。2前提例如cp210x模塊。該模塊有一個源文件:cp210x.c,編譯時使用的Makefile格式如下:ifneq($(KERNELRELEASE),)ifneq($(KERNELRELEASE),)obj-m:=cp210x.oelseKDIR?=/lib/modules/$(uname-r)/buildPWD:=$(shellpwd)modules:$(MAKE)-C$(KDIR)M=$(PWD)modulesall:modulesclean:rm-rf*.o*.ko*.depend*.mod.o*.mod.cModule.*modules.*.*.cmd.tmp_versionsendif手動編譯后,生成了以下文件:cp210x.mod.ccp210x.mod.ccp210x.oModule.symverscp210x.ko cp210x.mod.omodules.order在這些文件中,系統(tǒng)只需要不涉密的.o文件:cp210x.o。使用kylin-dkms-creator工具生成編包目錄:[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-c-ocp210x.o.dkms-ndevelopers-e[kylin@Kylin~]$kylin-dkms-creator-mcp210x-v1.0-c-ocp210x.o.dkms-ndevelopers-e\hdevelopers@-d/home/developers/my-dkms/輸出:Everythingisdone.Everythingisdone.Packagedirectoryis"/home/developers/my-dkms/cp210x-dkms-closed-1.0".添加.o將cp210x.o文件復制到編包目錄下的src目錄里面,重命名為.o.dkms:[kylin@Kylin~]$cpcp210x.o/home/developers/my-dkms/cp210x-dkms-closed-1.0/src/cp210x.o.dkms[kylin@Kylin~]$cpcp210x.o/home/developers/my-dkms/cp210x-dkms-closed-1.0/src/cp210x.o.dkmsMakefileMakefilecp210x-dkms-closed-objs-o.o.dk完整Makefile如下:obj-m:=cp210x-dkms-closed.oobj-m:=cp210x-dkms-closed.ocp210x-dkms-closed-objs:=cp210x.o.dkmsifneq($(KERNELRELEASE),)KERNELDIR?=/lib/modules/$(KERNELRELEASE)/buildelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildEndifPWD:=$(shellpwd)PWD:=$(shellpwd).PHONY:allall:cleanmodules#install.PHONY:modulesmodules:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)modules.PHONY:cleanclean:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)clean#.PHONY:install#install:# $(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)modules_install編包返回編包目錄,執(zhí)行編包命令:[kylin@Kylin~]$cd/home/developers/my-dkms/cp210x-dkms-closed-1.0/[kylin@Kylin~]$dpkg-buildpackage-sa[kylin@Kylin~]$cd/home/developers/my-dkms/cp210x-dkms-closed-1.0/[kylin@Kylin~]$dpkg-buildpackage-sa編譯完成后,第三方模塊的dkms包位于編包目錄的上一級目錄中,名為:cp210dk-cose_1.arm64**-dkmscloed_。3.osrc.o.dkms。注意:多二進制文件需要在-o參數(shù)中指定,例如:需要的二進制:a.ob.oc.o需要的二進制:a.ob.oc.o-o參數(shù)為:-o"a.o.dkmsb.o.dkmsc.o.dkms"引號為英文半角引號??扇斯z查src/Makefile的第二行字段,是否與需要的.o.dkms文件一致。4Makefile需要特殊處理的內(nèi)核模塊,在編譯時不能直接使用示例1、2、3中的Makefile。ifneq($(KERNELRELEASE),)obj-m:=B.oelseKERNELDIR?=/lib/modules/$(shelluname-r)/build/PWD :=$(shellpwd)modules:$(MAKE)-C$(KERNELDIR)M=$(PWD)KBUILD_EXTRA_SYMBOLS=./Module.symversmodulesclean:rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versionsmodules.orderendifBABAifneq($(KERNELRELEASE),)obj-m:=B.oelseKERNELDIR?=/lib/modules/$(shelluname-r)/build/PWD :=$(shellpwd)modules:$(MAKE)-C$(KERNELDIR)M=$(PWD)KBUILD_EXTRA_SYMBOLS=./Module.symversmodulesclean:rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versionsmodules.orderendifMakefileACRCdkms——在編包目錄的src目錄下新建一個文件夾,名為:extra_symbols;——將A模塊的Module.symvers文件復制到新建的extra_symbols目錄中;obj-m:=B-dkms.oB-dkms-objs:=B.oifneq($(KERNELRELEASE),)KERNELDIR?=/lib/modules/$(KERNELRELEASE)/buildelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildendifPWD:=$(shellpwd).PHONY:allall:cleanmodules#install.PHONY:modulesmodules:$(MAKE)-Cobj-m:=B-dkms.oB-dkms-objs:=B.oifneq($(KERNELRELEASE),)KERNELDIR?=/lib/modules/$(KERNELRELEASE)/buildelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildendifPWD:=$(shellpwd).PHONY:allall:cleanmodules#install.PHONY:modulesmodules:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)KBUILD_EXTRA_SYMBOLS=$(PWD)/extra_symbols/Module.symversmodules.PHONY:cleanclean:$(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)clean#.PHONY:install#install:# $(MAKE)-C$(KERNELDIR)SUBDIRS=$(PWD)modules_installMakefileMakefilekylin-dkms-creatorextra_symbolsModule.symversModule.symvers——重命名A模塊的Module.symvers文件為A.symvers,并復制到src目錄中;akeileKBUIL_EXRA_YMBL“$PWD/A.ymv附錄G(資料性)驅動程序的調(diào)試驗證方法printkprintf(KERN_ALERT“HelloWorld\n”);利用printkCprintfprintf(KERN_ALERT“HelloWorld\n”);內(nèi)核一共定義了8種打印級別宏:#defineKERN_EMERG#defineKERN_EMERG"<0>"#defineKERN_ALERT"<1>"#defineKERN_CRIT"<2>"#defineKERN_ERR"<3>"#defineKERN_WARNING"<4>"#defineKERN_NOTICE"<5>"#defineKERN_INFO"<6>"#defineKERN_DEBUG"<7>"#cat/proc/sys/kernel/printk6 4 1 7printk#cat/proc/sys/kernel/printk6 4 1 7第一個664printk41177。為了簡化代碼,內(nèi)核同樣提供簡化系列函數(shù):#definepr_emerg(fmt,...)#definepr_emerg(fmt,...)\printk(KERN_EMERGpr_fmt(fmt),##VA_ARGS)#definepr_alert(fmt,...)\printk(KERN_ALERTpr_fmt(fmt),##VA_ARGS)#definepr_crit(fmt,...)\printk(KERN_CRITpr_fmt(fmt),##VA_ARGS)#definepr_err(fmt,...)\printk(KERN_ERRpr_fmt(fmt),##VA_ARGS)#definepr_warning(fmt,...)\printk(KERN_WARNINGpr_fmt(fmt),##VA_ARGS)#definepr_notice(fmt,...)\printk(KERN_NOTICEpr_fmt(fmt),##VA_ARGS)#definepr_info(fmt,...)\printk(KERN_INFOpr_fmt(fmt),##VA_ARGS)#definepr_cont(fmt,...)\printk(KERN_CONTfmt,##VA_AR
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑與市政工程質量安全第三方巡查方案與流程
- 腹腔鏡結直腸癌根治術對老年結直腸癌患者術后胃腸功能恢復的影響
- 二零二五年度個人金融理財產(chǎn)品購買擔保協(xié)議3篇
- 房地產(chǎn)行業(yè)房地產(chǎn)銷售培訓心得
- 2025版環(huán)保產(chǎn)業(yè)項目可行性評估范本匯編3篇
- 二零二五版物流裝備租賃及維護服務合同2篇
- 《企業(yè)安全管理》課件
- 二零二五年度房地產(chǎn)分銷代理創(chuàng)新模式合同范文
- 二零二五年度房地產(chǎn)土地一級開發(fā)代理服務合同
- 二零二五版物流園區(qū)物業(yè)承包合作協(xié)議3篇
- 各種標本采集的技術-痰標本的采集(護理技術)
- 2024年湖南中考道德與法治試卷真題答案解析(精校打?。?/a>
- 實驗室的設計規(guī)劃
- 2024-2030年中國假睫毛行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略分析報告
- HG+20231-2014化學工業(yè)建設項目試車規(guī)范
- 第3篇 助跑 項目六 異形芯片分揀與安裝講解
- 2024年越南天然食用香料與色素行業(yè)現(xiàn)狀及前景分析2024-2030
- 匯款賬戶變更協(xié)議
- 實體瘤療效評價標準(RECIST11)
- 教案-中國書法史
- 隧道施工-緒論(使用)
評論
0/150
提交評論