Signed-off-by: pxd2022 <pingxiandeng1@huawei.com>
8.0 KiB
驱动孵化进程 hdf_devhost
本文记录 hdf_devhost 的设计意图、核心架构、改动规则与代码路径。
进程定位
DevHostService(devhost)是标准系统用户空间驱动孵化进程:
- 进程隔离:每种host类型独立进程(
devhost_*),驱动崩溃不影响Manager或其他Host - 驱动动态加载:dlopen_ns/dlsym加载驱动.so,基于Manager下发的HCS配置指令
- 设备生命周期:创建→Bind→Init→发布服务→Release驱动实例
- 服务发布:IPC注册驱动服务到servmgr(SA-ID 5100)
- 电源管理:接收电源事件,通过PowerStateToken向各驱动传播
- IPC桥接:Stub接收Manager命令;DeviceServiceStub转发客户端IO请求到驱动Dispatch
- 本地服务观察:HdfServiceObserver支持FRIENDLY/PRIVATE策略host内互相订阅
host设置 PR_SET_PDEATHSIG(SIGKILL) 以在devmgr死亡时自动退出,servmgr死亡时 _exit(0)。
分层架构
IDevHostService (虚表: AddDevice, DelDevice, StartService, PmNotify, Dump)
|
DevHostService (框架层: hostId, hostName, devices DList, observer)
|
DevHostServiceFull (适配层: MessageTask + MessageLooper, 异步消息分发)
|
DevHostServiceStub (IPC层: HdfRemoteService* + hostSvcMutex)
对象工厂映射(devhost_object_config.c):
| Object ID | 创建函数 | 说明 |
|---|---|---|
| DEVMGR_SERVICE | DevmgrServiceProxyCreate | Manager代理(IPC客户端) |
| DEVSVC_MANAGER | DevSvcManagerProxyCreate | servmgr代理 |
| DEVHOST_SERVICE | DevHostServiceStubCreate | Host核心服务 |
| DRIVER_LOADER | HdfDriverLoaderFullCreate | dlopen加载器 |
| DEVICE_TOKEN | DeviceTokenStubCreate | 令牌IPC包装 |
| DEVICE_SERVICE | DeviceServiceStubCreate | 设备服务IPC包装 |
核心数据结构
| 结构 | 关键成员 | 说明 |
|---|---|---|
| DevHostService | hostId, hostName, devices(DList), observer | Host主对象 |
| HdfDeviceNode | deviceObject, driver, token, powerToken, policy, servName, devStatus, interfaceDesc | 设备节点核心结构 |
| HdfDriverEntry | moduleVersion, moduleName, Bind/Init/Release | 驱动入口(HDF_INIT注册) |
| HdfDriver | entry(HdfDriverEntry*), priv(dlopen handle) | 运行时驱动对象 |
| HdfDeviceInfo | deviceId, policy, preload, moduleName, svcName | HCS设备配置 |
| HdfDevice | devNodes(DList), devidIndex(动态ID从129起) | 逻辑设备(含多个节点) |
设备ID编码:MK_DEVID(hostId, deviceId, nodeId),动态节点ID从129分配。
ServicePolicy:NONE(0) / PUBLIC(1) / CAPACITY(2) / FRIENDLY(3 host内订阅) / PRIVATE(4 同devId订阅)
VDI:HdfVdiBase(CreateVdiInstance/DestoryVdiInstance) + HdfVdiObject(dlHandler+vdiBase),声明 HDF_VDI_INIT
进程启动流程
main() [devhost.c / drivers_peripheral/devhost/host/devhost.c]
-> ParseCommandLineArgs: -i hostId -n hostName -p procPri -s schedPri -m mallopt
-> InitializeHost: PDEATHSIG(SIGKILL), SetProcTitle, SetPriority, SetMallopt
-> StartHostService:
-> DevHostServiceNewInstance: Stub->Full->DevHostService 三层构造
-> DevHostDumpInit()
-> StartService:
-> DevmgrServiceClntAttachDeviceHost: IPC(重试100次×20ms)注册到devmgr
-> HdfSysEventNotifyRegister(POWER事件)
-> HdfPowerManagerInit()
-> looper->Start() [主事件循环]
[退出]: FreeInstance, PowerManagerExit, DumpDeInit
驱动加载机制
dlopen动态加载:dlopen_ns(moduleName, RTLD_LAZY) → dlsym(handle, "driverDesc") → HdfDriverEntry
驱动.so通过 HDF_INIT(g_xxxEntry) 导出全局 driverDesc 指针。
内核静态加载:链接器段 HDF_DRIVER_BEGIN()/END() 遍历(内核/LiteOS模式)。
VDI二级加载:HdfLoadVdi(libName) → realpath安全验证 → dlopen_ns + dlsym("hdfVdiDesc") → CreateVdiInstance
设备生命周期
AddDevice流程
IPC ADD_DEVICE → 反序列化HdfDeviceInfo → async MessageTask → DevHostServiceAddDevice:
- QueryOrAddDevice(查找/创建HdfDevice)
- driverLoader->GetDriver(moduleName) (dlopen加载)
- HdfDeviceNodeNewInstance(创建DeviceServiceStub+设置字段+读HCS属性)
- device->Attach: 动态devId分配(129起) → LaunchNode
LaunchNode序列:Bind(设置deviceObject.service) → Init(硬件初始化) → PublishService(IPC注册servmgr+本地observer) → AttachDevice(IPC通知devmgr)
DelDevice流程
IPC DEL_DEVICE → async → DevHostServiceDelDevice → HdfDeviceDetach → UnlaunchNode:
UnlaunchNode序列:Release(_rwlock保护) → RemoveService(IPC注销) → DetachDevice(IPC通知devmgr) → ReclaimDriver(MemFree不dlclose)
服务观察/订阅
HdfServiceObserver:hash key查找Record → Publish(设置publisher+NotifySubscribers) / Subscribe(创建Subscriber+如publisher存在立即回调)
驱动通过 HdfDeviceSubscribeService() → deviceObject→devNode→hostService→observer 调用。
IPC Stub/Proxy
| 组件 | 方向 | 功能 |
|---|---|---|
| DevHostServiceStub | devmgr→host | 3命令: AddDevice/DelDevice/Dump, mutex序列化 |
| DevmgrServiceProxy | host→devmgr | AttachDeviceHost(重试100次), Attach/DetachDevice |
| DevSvcManagerProxy | host→servmgr | Add/Update/Remove Service, 死亡检测→_exit(0) |
| DeviceServiceStub | 客户端→驱动 | rwlock保护下ioService->Dispatch(code,data,reply) |
| DeviceTokenStub | — | 最小IPC stub(dispatch返回HDF_SUCCESS),Binder身份对象 |
接口令牌检查:DeviceServiceStub强版本 HdfDeviceObjectCheckInterfaceDesc → HdfRemoteServiceCheckInterfaceToken
电源管理
系统事件映射:SUSPEND→POWER_STATE_SUSPEND, DISPLAY_OFF→DOZE_SUSPEND, RESUME→POWER_STATE_RESUME, DISPLAY_ON→DOZE_RESUME
传播:唤醒反向遍历(后设备先醒),休眠正向遍历(先设备先睡)
PowerStateToken两种模式:
- SYS_CTRL:系统事件推送,直接调用listener->Suspend/Resume/Doze
- DYNAMIC_CTRL:HdfSRef引用计数wake lock,Acquire(首次→Resume)/Release(末次→Suspend)
PSM状态:IDLE→ACTIVE(Resume)→INACTIVE(Suspend)
异步PM:HdfPmAcquire/ReleaseDeviceAsync → PM任务队列专用线程处理
Peripheral Devhost
可执行文件入口在 drivers_peripheral/devhost/host/devhost.c(同adapter/uhdf2/host/devhost.c)。
构建关系:可执行文件hdf_devhost(仅main入口, peripheral repo) + 共享库libhdf_host(框架+适配逻辑, core repo),运行时链接。
代码路径映射
| 层 | 目录 | 关键文件 |
|---|---|---|
| 框架层 | framework/core/host/ |
devhost_service.c(核心), hdf_device_node.c(设备生命周期), hdf_device_object.c(驱动API), hdf_driver_loader.c/ hdf_load_vdi.c(加载), hdf_service_observer.c(本地服务) |
| 接口层 | framework/core/shared/include/ |
devhost_service_if.h, power_state_token_if.h |
| Inner API | interfaces/inner_api/host/ |
hdf_device_desc.h(驱动API+HDF_INIT), hdf_device_node.h, hdf_device_info.h, hdf_pm.h, hdf_load_vdi.h |
| 适配层 | adapter/uhdf2/host/ |
devhost.c(main入口), devhost_service_stub.c(IPC stub), devmgr_service_proxy.c/devsvc_manager_proxy.c(IPC proxy), driver_loader_full.c(dlopen), device_service_stub.c(设备IO dispatch), devhost_object_config.c(工厂配置) |
| Peripheral | drivers_peripheral/devhost/ |
host/devhost.c(main入口), host/BUILD.gn(链接libhdf_host) |
改动规则
- Host代码分布在
framework/core/host/+adapter/uhdf2/host/,不要只改一侧 - 可执行文件入口在peripheral repo,框架逻辑在core repo libhdf_host
- 新增Manager-Host交互先在
framework/core/shared/include/定义接口 - 驱动.so必须导出
driverDesc符号(HDF_INIT);VDI导出hdfVdiDesc(HDF_VDI_INIT) - 服务发布分IPC(PUBLIC/CAPACITY→servmgr)和本地(FRIENDLY/PRIVATE→observer)
- DeviceServiceStub Dispatch在pthread_rwlock保护下,改IO分发需注意读写锁
- AddDevice/DelDevice通过MessageTask异步处理,不要改为同步(避免IPC死锁)
- PM有SYS_CTRL和DYNAMIC_CTRL两种模式,改PM逻辑先确认目标模式
- 新增对象类型在devhost_object_config.c Creator映射表注册