自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HarmonyOS驅(qū)動(dòng)加載過(guò)程分析

系統(tǒng) OpenHarmony
本文主要分析HarmonyOS驅(qū)動(dòng)加載過(guò)程,在正式介紹之前,首先了解HarmonyOS驅(qū)動(dòng)架構(gòu)的組成、工作原理和機(jī)制,從而了解驅(qū)動(dòng)加載的細(xì)節(jié)。

[[399387]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

HarmonyOS驅(qū)動(dòng)概述

HarmonyOS驅(qū)動(dòng)框架采用C語(yǔ)言面向?qū)ο缶幊棠P蜆?gòu)建,通過(guò)平臺(tái)解耦、內(nèi)核解耦,來(lái)達(dá)到兼容不同內(nèi)核,統(tǒng)一平臺(tái)底座的目的,從而幫助開(kāi)發(fā)者實(shí)現(xiàn)驅(qū)動(dòng)的“一次開(kāi)發(fā)、多系統(tǒng)部署”。

為了達(dá)成這個(gè)目標(biāo), HarmonyOS驅(qū)動(dòng)框架提供了:

1. 操作系統(tǒng)適配層(OSAL,operating system abstraction layer):提供內(nèi)核操作相關(guān)接口進(jìn)行統(tǒng)一封裝,屏蔽不同系統(tǒng)操作接口。

2.平臺(tái)驅(qū)動(dòng)接口:提供Board部分驅(qū)動(dòng)(例如:I2C/SPI/UART總線等平臺(tái)資源)支持,同時(shí)對(duì)Board硬件操作接口進(jìn)行統(tǒng)一的適配抽象,開(kāi)發(fā)者只需開(kāi)發(fā)新硬件抽象接口,即可獲得新增Board部分驅(qū)動(dòng)支持。

3.驅(qū)動(dòng)模型:面向器件驅(qū)動(dòng),提供常見(jiàn)的驅(qū)動(dòng)抽象模型,主要達(dá)成兩個(gè)目的:

1)提供標(biāo)準(zhǔn)化的器件驅(qū)動(dòng),開(kāi)發(fā)者無(wú)需獨(dú)立開(kāi)發(fā),通過(guò)配置即可完成驅(qū)動(dòng)的部署。

2)提供驅(qū)動(dòng)模型抽象,屏蔽驅(qū)動(dòng)與不同系統(tǒng)組件間的交互,使得驅(qū)動(dòng)更具備通用性。

為了進(jìn)一步簡(jiǎn)化HarmonyOS驅(qū)動(dòng)開(kāi)發(fā),HarmonyOS驅(qū)動(dòng)框架支持多種驅(qū)動(dòng)加載方式:

1.支持驅(qū)動(dòng)動(dòng)態(tài)加載和靜態(tài)加載,解除驅(qū)動(dòng)代碼和框架間的直接代碼依賴(lài),使得驅(qū)動(dòng)程序可以獨(dú)立編譯和部署;

2.支持按需動(dòng)態(tài)加載方式,避免設(shè)備驅(qū)動(dòng)全量加載,可有效降低系統(tǒng)資源的占用。

本文主要分析HarmonyOS驅(qū)動(dòng)加載過(guò)程,在正式介紹之前,首先了解HarmonyOS驅(qū)動(dòng)架構(gòu)的組成、工作原理和機(jī)制,從而了解驅(qū)動(dòng)加載的細(xì)節(jié)。

●官網(wǎng)相關(guān)介紹:

https://device.harmonyos.com/cn/docs/develop/drive/oem_drive_hdfdev-0000001051715456

HarmonyOS驅(qū)動(dòng)架構(gòu)介紹

2.1 HarmonyOS驅(qū)動(dòng)架構(gòu)組成

HarmonyOS驅(qū)動(dòng)架構(gòu)主要由HDF驅(qū)動(dòng)框架、驅(qū)動(dòng)程序、驅(qū)動(dòng)配置文件和驅(qū)動(dòng)接口四個(gè)部分組成。

1)HDF驅(qū)動(dòng)框架提供統(tǒng)一的硬件資源管理,驅(qū)動(dòng)加載管理以及設(shè)備節(jié)點(diǎn)管理等功能。

驅(qū)動(dòng)框架采用的是主從模式設(shè)計(jì),由Device Manager和Device Host組成。

Device Manager提供了統(tǒng)一的驅(qū)動(dòng)管理,Device Manager啟動(dòng)時(shí)根據(jù)Device Information提供驅(qū)動(dòng)設(shè)備信息加載相應(yīng)的驅(qū)動(dòng)Device Host,并控制Host完成驅(qū)動(dòng)的加載。

Device Host提供驅(qū)動(dòng)運(yùn)行的環(huán)境,同時(shí)預(yù)置Host Framework與Device Manager進(jìn)行協(xié)同,完成驅(qū)動(dòng)加載和調(diào)用。根據(jù)業(yè)務(wù)的需求Device Host可以有多個(gè)實(shí)例。

說(shuō)明

◆ Device Host顧名思義就是驅(qū)動(dòng)宿主,提供驅(qū)動(dòng)運(yùn)行的環(huán)境。

◆ 當(dāng)驅(qū)動(dòng)部署在用戶(hù)態(tài)時(shí),Device Host可以由獨(dú)立的進(jìn)程進(jìn)行承載。

◆ 當(dāng)驅(qū)動(dòng)在部署在內(nèi)核態(tài)時(shí),Device Host僅表示邏輯隔離。

◆ Device Host的劃分原則:Device Host屬于一類(lèi)設(shè)備聚合,如Camera、Audio、Display等。

◆ 驅(qū)動(dòng)程序是部署在一個(gè)Device Host還是部署在不同的Device Host,主要考慮驅(qū)動(dòng)程序之間是否存在業(yè)務(wù)耦合性,如果兩個(gè)驅(qū)動(dòng)程序之間存在依賴(lài),可以考慮將這部分驅(qū)動(dòng)程序部署在統(tǒng)一Host。

2)驅(qū)動(dòng)程序實(shí)現(xiàn)驅(qū)動(dòng)的具體功能,每個(gè)驅(qū)動(dòng)由一個(gè)或者多個(gè)驅(qū)動(dòng)程序組成,每個(gè)驅(qū)動(dòng)程序都對(duì)應(yīng)著一個(gè)Driver Entry。Driver Entry主要完成驅(qū)動(dòng)的初始化和驅(qū)動(dòng)接口綁定功能。

3)驅(qū)動(dòng)配置文件.hcs主要由設(shè)備信息(Device Information)和設(shè)備資源(Device Resource)組成。

Device Information完成設(shè)備信息的配置,如配置接口發(fā)布策略,驅(qū)動(dòng)加載的方式等。

Device Resource完成設(shè)備資源的配置,如GPIO管腳、寄存器等資源信息的配置。

4)驅(qū)動(dòng)接口HDI(Hardware Driver interface)提供標(biāo)準(zhǔn)化的接口定義和實(shí)現(xiàn),驅(qū)動(dòng)框架提供IO Service和IO Dispatcher機(jī)制,使得不同部署形態(tài)下驅(qū)動(dòng)接口趨于形式一致。

當(dāng)驅(qū)動(dòng)部署在RTOS(Real-Time Operating System)輕量化操作系統(tǒng)時(shí),驅(qū)動(dòng)接口和驅(qū)動(dòng)程序之間采用的是Function Call方式調(diào)用,因此驅(qū)動(dòng)接口僅提供定義,驅(qū)動(dòng)接口實(shí)現(xiàn)由驅(qū)動(dòng)程序提供。

2.2 HDF驅(qū)動(dòng)框架工作原理

Device Manager提供了統(tǒng)一的驅(qū)動(dòng)加載管理機(jī)制和驅(qū)動(dòng)接口發(fā)布機(jī)制。

當(dāng)Device Host環(huán)境加載完成時(shí),Device Manager根據(jù)Device Information信息,請(qǐng)求Host加載相應(yīng)的驅(qū)動(dòng)程序,Device Host在收到請(qǐng)求時(shí),進(jìn)行以下操作:

1)根據(jù)請(qǐng)求加載設(shè)備信息,查找并加載指定路徑下驅(qū)動(dòng)鏡像或從指定段地址(section)查找驅(qū)動(dòng)程序入口;

2)查找驅(qū)動(dòng)設(shè)備描述符,匹配對(duì)應(yīng)的設(shè)備驅(qū)動(dòng);

3)當(dāng)驅(qū)動(dòng)匹配成功時(shí),加載指定驅(qū)動(dòng)程序鏡像;

4)Host Framework在驅(qū)動(dòng)鏡像加載成功后,調(diào)用驅(qū)動(dòng)程序(Driver Entry)的綁定接口和初始化接口,實(shí)現(xiàn)與驅(qū)動(dòng)程序的服務(wù)對(duì)象綁定,同時(shí)初始化設(shè)備驅(qū)動(dòng)程序;

5)當(dāng)Device Information的配置中的服務(wù)策略要求對(duì)外暴露驅(qū)動(dòng)接口時(shí),驅(qū)動(dòng)框架就將驅(qū)動(dòng)程序的服務(wù)對(duì)象添加到對(duì)外發(fā)布的服務(wù)對(duì)象列表中,外部客戶(hù)端程序就可以通過(guò)此列表來(lái)查詢(xún)并訪問(wèn)相應(yīng)的服務(wù)接口。

2.3 驅(qū)動(dòng)接口工作機(jī)制

驅(qū)動(dòng)接口主要存在以下幾種實(shí)現(xiàn):

•當(dāng)驅(qū)動(dòng)以?xún)?nèi)核組件部署時(shí),客戶(hù)端程序訪問(wèn)驅(qū)動(dòng)程序需要通過(guò)system call方式調(diào)用,驅(qū)動(dòng)接口通過(guò)IO Service請(qǐng)求將消息通過(guò)system call方式調(diào)用到內(nèi)核,并將消息分發(fā)到IO Dispatcher處理。

•當(dāng)驅(qū)動(dòng)以用戶(hù)態(tài)服務(wù)形式部署時(shí),客戶(hù)端進(jìn)程訪問(wèn)驅(qū)動(dòng)進(jìn)程需要通過(guò)IPC方式通信,IO Service完成IPC通信的客戶(hù)端消息請(qǐng)求封裝,IO Dispatcher完成驅(qū)動(dòng)服務(wù)端消息請(qǐng)求封裝,客戶(hù)端消息通過(guò)IPC通信到達(dá)服務(wù)端并分發(fā)給IO Dispatcher處理。

為了使客戶(hù)端和服務(wù)端驅(qū)動(dòng)調(diào)用方式基本一致,驅(qū)動(dòng)框架提供IO Service和IO Dispatcher機(jī)制屏蔽了調(diào)用消息傳遞方式的差異。

驅(qū)動(dòng)接口實(shí)現(xiàn)統(tǒng)一采用遠(yuǎn)程調(diào)用方式,客戶(hù)端驅(qū)動(dòng)接口函數(shù)將請(qǐng)求序列化成內(nèi)存數(shù)據(jù),通過(guò)驅(qū)動(dòng)框架提供的IO Service將消息發(fā)送到服務(wù)端處理,服務(wù)端在收到請(qǐng)求消息時(shí)通過(guò)IO Dispatcher機(jī)制將消息分發(fā)給消息處理函數(shù)處理,處理函數(shù)將反序列化內(nèi)存數(shù)據(jù)解析成相應(yīng)的請(qǐng)求。這樣做的好處是,開(kāi)發(fā)者只需重點(diǎn)關(guān)注接口的定義,無(wú)需過(guò)多關(guān)注如何實(shí)現(xiàn)不同平臺(tái)上接口適配。

驅(qū)動(dòng)加載過(guò)程分析

HarmonyOS驅(qū)動(dòng)根據(jù)部署的不同方式,存在兩種驅(qū)動(dòng)加載方式:

•動(dòng)態(tài)加載方式:采用傳統(tǒng)的so(共享庫(kù)) 加載方式,驅(qū)動(dòng)程序通過(guò)指定Symbol找到驅(qū)動(dòng)函數(shù)入口進(jìn)行加載。

•靜態(tài)加載方式:采用將驅(qū)動(dòng)程序通過(guò)Scatter編譯方式,編譯到指定的Section,再通過(guò)訪問(wèn)指定Section對(duì)應(yīng)的地址,找到驅(qū)動(dòng)函數(shù)入口進(jìn)行加載。

下面結(jié)合一個(gè)Sample示例代碼,講解驅(qū)動(dòng)加載過(guò)程,重點(diǎn)分析靜態(tài)加載方式下內(nèi)核態(tài)驅(qū)動(dòng)加載過(guò)程。

3.1 實(shí)現(xiàn)驅(qū)動(dòng)程序初始化接口

在HDF驅(qū)動(dòng)框架中,HdfDriverEntry對(duì)象被用來(lái)描述一個(gè)驅(qū)動(dòng)實(shí)現(xiàn)。

  1. struct HdfDriverEntry { 
  2.     int32_t moduleVersion; 
  3.     const char *moduleName; 
  4.     int32_t (*Bind)(struct HdfDeviceObject *deviceObject); 
  5.     int32_t (*Init)(struct HdfDeviceObject *deviceObject); 
  6.     void (*Release)(struct HdfDeviceObject *deviceObject); 
  7. }; 

 編寫(xiě)一個(gè)簡(jiǎn)單的驅(qū)動(dòng),首先需要實(shí)現(xiàn)驅(qū)動(dòng)程序(Driver Entry)入口中的三個(gè)主要接口:

•Bind接口:

實(shí)現(xiàn)驅(qū)動(dòng)接口實(shí)例化綁定,如果需要發(fā)布驅(qū)動(dòng)接口,會(huì)在驅(qū)動(dòng)加載過(guò)程中被調(diào)用,實(shí)例化該接口的驅(qū)動(dòng)服務(wù)并和DeviceObject綁定。

•Init接口:

實(shí)現(xiàn)驅(qū)動(dòng)的初始化,返回錯(cuò)誤將中止驅(qū)動(dòng)加載流程。

•Release接口:

實(shí)現(xiàn)驅(qū)動(dòng)的卸載,在該接口中釋放驅(qū)動(dòng)實(shí)例的軟硬件資源。

  1. int SampleDriverBind(struct HdfDeviceObject *deviceObject) 
  2.     HDF_LOGE("SampleDriverBind enter!"); 
  3.     static struct IDeviceIoService testService = { 
  4.         .Dispatch = SampleServiceDispatch, 
  5.         .Open = NULL
  6.         .Release = NULL
  7.     }; 
  8.     deviceObject->service = &testService; 
  9.     return HDF_SUCCESS; 
  10.   
  11. int SampleDriverInit(struct HdfDeviceObject *deviceObject) 
  12.     HDF_LOGE("SampleDriverInit enter"); 
  13.      return HDF_SUCCESS; 
  14.  
  15.  void SampleDriverRelease(struct HdfDeviceObject *deviceObject) 
  16.     HDF_LOGE("SampleDriverRelease enter"); 
  17.     return
  18.  
  19.  struct HdfDriverEntry g_sampleDriverEntry = { 
  20.     .moduleVersion = 1, 
  21.     .moduleName = "sample_driver"
  22.     .Bind = SampleDriverBind, 
  23.     .Init = SampleDriverInit, 
  24.     .Release = SampleDriverRelease, 
  25. }; 
  26.  
  27. HDF_INIT(g_sampleDriverEntry); 

 3.2 導(dǎo)出驅(qū)動(dòng)程序入口符號(hào)

實(shí)現(xiàn)驅(qū)動(dòng)程序初始化后,需要將驅(qū)動(dòng)程序入口通過(guò)驅(qū)動(dòng)聲明宏導(dǎo)出,這樣驅(qū)動(dòng)框架才能在啟動(dòng)時(shí)識(shí)別到驅(qū)動(dòng)程序的存在,驅(qū)動(dòng)才能被加載:

  1. #define HDF_INIT(module)  HDF_DRIVER_INIT(module) 

 這里將HDF_INIT宏展開(kāi):

  1. #define HDF_SECTION __attribute__((section(".hdf.driver"))) 
  2. #define HDF_DRIVER_INIT(module) \ 
  3.     const size_t USED_ATTR module##HdfEntry HDF_SECTION = (size_t)(&(module)) 

 下面是實(shí)現(xiàn)原理:

可以看到HDF_INIT宏是定義了一個(gè)“驅(qū)動(dòng)模塊名+HdfEntry”的符號(hào)放到".hdf.driver" 所在section,該符號(hào)指向的內(nèi)存地址即為驅(qū)動(dòng)程序入口結(jié)構(gòu)體的地址。這個(gè)特殊的section將用于開(kāi)機(jī)啟動(dòng)時(shí)查找設(shè)備驅(qū)動(dòng)。

3.3 添加設(shè)備配置

在設(shè)備對(duì)應(yīng)的device_info.hcs添加sample驅(qū)動(dòng)的配置:

  1. sample_host :: host { 
  2.     hostName = "sample_host"
  3.     sample_device :: device { 
  4.         device0 :: deviceNode { 
  5.             policy = 2; 
  6.             priority = 100; 
  7.             preload = 1; 
  8.             permission = 0664; 
  9.             moduleName = "sample_driver"
  10.             serviceName = "sample_service"
  11.         } 
  12.     } 

 在配置中定義的device將在加載過(guò)程中產(chǎn)生一個(gè)設(shè)備實(shí)例,通過(guò)moduleName字段指定設(shè)備對(duì)應(yīng)的驅(qū)動(dòng)名稱(chēng),從而將設(shè)備與驅(qū)動(dòng)關(guān)聯(lián)起來(lái)。其中,設(shè)備與驅(qū)動(dòng)可以是一對(duì)多的關(guān)系,即可以實(shí)現(xiàn)一個(gè)驅(qū)動(dòng)支持多個(gè)同類(lèi)型設(shè)備。

3.4 驅(qū)動(dòng)啟動(dòng)過(guò)程

我們添加的驅(qū)動(dòng)是如何被執(zhí)行的呢?簡(jiǎn)單來(lái)說(shuō),在系統(tǒng)啟動(dòng)時(shí),驅(qū)動(dòng)框架先啟動(dòng),通過(guò)解析配置文件獲取到設(shè)備列表,通過(guò)讀取".hdf.driver"段讀取到驅(qū)動(dòng)程序(Driver Entry)列表,然后遍歷設(shè)備列表與驅(qū)動(dòng)程序列表進(jìn)行匹配,并加載匹配成功的驅(qū)動(dòng)。

驅(qū)動(dòng)框架有兩大核心管理者:

DeviceManager:負(fù)責(zé)設(shè)備的管理,包括設(shè)備加載、卸載和查詢(xún)等設(shè)備相關(guān)功能。

•DeviceServiceManager:負(fù)責(zé)管理設(shè)備發(fā)布的接口服務(wù),提供接口服務(wù)的發(fā)布和查詢(xún)等功能。

驅(qū)動(dòng)加載主要由DeviceManager主導(dǎo),首先DeviceManager要解析配置文件中的Host列表,根據(jù)Host列表中的信息來(lái)實(shí)例化對(duì)應(yīng)的Host對(duì)象。Host解析配置文件獲取到關(guān)聯(lián)的設(shè)備列表,遍歷設(shè)備列表去獲取與之匹配的驅(qū)動(dòng)程序名稱(chēng),然后基于驅(qū)動(dòng)程序名稱(chēng)遍歷前面提到的".hdf.driver" section獲得驅(qū)動(dòng)程序地址。

下面介紹具體過(guò)程。

3.4.1 獲取設(shè)備列表

配置文本編譯后會(huì)變成二進(jìn)制格式的配置文件,其中設(shè)備相關(guān)信息被存放在一個(gè)用“hdf_manager”標(biāo)記的device_info配置塊中,host的內(nèi)容以塊的形式在device_info塊中依次排列,host塊中記錄了host名稱(chēng)、啟動(dòng)優(yōu)先級(jí)和設(shè)備列表信息。設(shè)備信息中的moduleName字段將用于和驅(qū)動(dòng)程序入口中的moduleName進(jìn)行匹配,從而為設(shè)備匹配到正確的驅(qū)動(dòng)程序。

3.4.2 獲取驅(qū)動(dòng)程序列表

HDF驅(qū)動(dòng)框架通過(guò)驅(qū)動(dòng)程序入口符號(hào)的地址集中存放到一個(gè)特殊的section來(lái)實(shí)現(xiàn)對(duì)驅(qū)動(dòng)的索引,這個(gè)section的開(kāi)頭和末尾插入了_hdf_drivers_start、_hdf_drivers_end兩個(gè)特殊符號(hào),用于標(biāo)記這個(gè)section的范圍,兩個(gè)特殊符號(hào)之間的數(shù)據(jù)即為驅(qū)動(dòng)實(shí)現(xiàn)指針。

3.4.3 驅(qū)動(dòng)程序加載流程

Device Manager遍歷設(shè)備列表,當(dāng)查找到對(duì)應(yīng)驅(qū)動(dòng)實(shí)現(xiàn)時(shí),為設(shè)備創(chuàng)建Device對(duì)象實(shí)例,如果設(shè)備配置中的policy字段為需要對(duì)外發(fā)布驅(qū)動(dòng)接口(SERVICE_POLICY_CAPACITY),那么驅(qū)動(dòng)的Bind接口將首先被調(diào)用,用于關(guān)聯(lián)設(shè)備和服務(wù)實(shí)例。然后驅(qū)動(dòng)的Init接口將被調(diào)用,用于完成驅(qū)動(dòng)的相關(guān)初始化工作。如果驅(qū)動(dòng)被卸載或者因?yàn)橛布仍騃nit接口返回失敗,Release將被調(diào)用,用于釋放驅(qū)動(dòng)申請(qǐng)的各類(lèi)資源。

總結(jié)

本次和大家分享了HarmonyOS驅(qū)動(dòng)的主要設(shè)計(jì)思想,重點(diǎn)分析了內(nèi)核態(tài)驅(qū)動(dòng)加載的過(guò)程,關(guān)于HarmonyOS驅(qū)動(dòng)其他內(nèi)容,后續(xù)會(huì)有更多技術(shù)文章向大家持續(xù)分享,敬請(qǐng)期待。

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2021-09-07 15:48:28

鴻蒙HarmonyOS應(yīng)用

2022-04-20 20:28:40

HDF 驅(qū)動(dòng)框架鴻蒙操作系統(tǒng)

2012-11-06 10:19:18

Java自定義加載Java類(lèi)

2014-04-29 13:16:42

OpenGLAndroid庫(kù)加載過(guò)程

2009-12-24 13:46:23

Linux驅(qū)動(dòng)

2022-01-10 08:50:13

URL前端頁(yè)面

2021-09-02 15:27:54

鴻蒙HarmonyOS應(yīng)用

2012-03-01 10:51:37

JavaJVM

2009-04-22 17:18:29

Vxworks驅(qū)動(dòng)加載step by ste

2009-08-04 10:46:04

2020-10-19 09:09:46

Class文件加載過(guò)程

2009-07-20 13:58:07

MySQL JDBC驅(qū)

2021-10-08 06:50:32

Linux驅(qū)動(dòng)掛載

2023-10-31 16:00:51

類(lèi)加載機(jī)制Java

2022-09-05 08:03:28

MySQL崩潰恢復(fù)

2013-07-05 10:56:21

2023-05-31 08:39:04

redis事件驅(qū)動(dòng)

2024-08-09 11:50:00

2021-11-08 10:24:16

Html頁(yè)面加載

2012-09-19 15:06:45

Lucene
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)