Android——hal库加载操作流程
来源:互联网 发布:qt多窗口编程 编辑:程序博客网 时间:2024/06/05 03:12
系统是如何区分平台,加载操作指定平台的相应的HAL库文件的?
以加载audio.primary.msm8909.so为例:
高通平台,audio primary库文件是有两个的,但是具体加载哪一个呢?
audio.primary.default.so
audio.primary.msm8909.so
AudioFlinger开始的调用流程:
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
|——audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
|——static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
static int load_audio_interface(const char *if_name, audio_hw_device_t **dev){ const hw_module_t *mod; int rc; rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);//"audio" hal操作句柄,根据这个去加载hal,if_name为“primary” ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc)); if (rc) { goto out; } rc = audio_hw_device_open(mod, dev);//操作HAL的adev_open函数 ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc)); if (rc) { goto out; } if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) { ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version); rc = BAD_VALUE; goto out; } return 0;out: *dev = NULL; return rc;}
hardware/libhardware/hardware.c
int hw_get_module_by_class(const char *class_id, const char *inst, const struct hw_module_t **module){ int i = 0; char prop[PATH_MAX] = {0}; char path[PATH_MAX] = {0}; char name[PATH_MAX] = {0}; char prop_name[PATH_MAX] = {0}; if (inst) snprintf(name, PATH_MAX, "%s.%s", class_id, inst); else strlcpy(name, class_id, PATH_MAX); //从上面传下来的name值就是 "audio.primary" /* * Here we rely on the fact that calling dlopen multiple times on * the same .so will simply increment a refcount (and not load * a new copy of the library). * We also assume that dlopen() is thread-safe. */ /* First try a property specific to the class and possibly instance */ snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);//查找属性值是否“ro.hardware.audio.primary” 这个属性值其实并没有设置 if (property_get(prop_name, prop, NULL) > 0) { if (hw_module_exists(path, sizeof(path), name, prop) == 0) { goto found; } } /* Loop through the configuration variants looking for a module */ for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) { //鉴于上面的属性值并没有找到,就去查找数组variant_keys是否有相关设置 /* static const char *variant_keys[] = { "ro.hardware", /* This goes first so that it can pick up a different file on the emulator. */ "ro.product.board", "ro.board.platform", "ro.arch"}; */ if (property_get(variant_keys[i], prop, NULL) == 0) { continue; //如果当前遍历属性值没有设置,开启查找下一个属性值 } if (hw_module_exists(path, sizeof(path), name, prop) == 0) { //hw_module_exists实质是加上路径查找指定的库 goto found; } } /* Nothing found, try the default */ if (hw_module_exists(path, sizeof(path), name, "default") == 0) { goto found; } return -ENOENT;found: /* load the module, if this fails, we're doomed, and we should not try * to load a different variant. */ return load(class_id, path, module);}
那么以下属性值是在哪里赋值的呢
static const char *variant_keys[] = {
“ro.hardware”, /* This goes first so that it can pick up a different
file on the emulator. */
“ro.product.board”,
“ro.board.platform”,
“ro.arch” }; “ro.hardware.%s”
以当前所操作的机器来看:
[ro.hardware]: [qcom]
[ro.product.board]: [msm8909]
[ro.board.platform]: [msm8909]
“ro.arch” 没有被设置
ro.hardware.audio.primary 没有被设置
build/tools/buildinfo.sh中间:
echo “ro.board.platform=$TARGET_BOARD_PLATFORM”
device/jrdcom/projectname/BoardConfig.mk中间赋值:
TARGET_BOARD_PLATFORM := msm8909
到这里就很清楚了
AudioPolicyManager初始化的时候,通过如下代码,根据指定的配置文件加载相应的audio hal库文件:
AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled, static_cast<VolumeCurvesCollection *>(mVolumeCurves)); PolicySerializer serializer; if (serializer.deserialize(AUDIO_POLICY_XML_CONFIG_FILE, config) != NO_ERROR) { //AUDIO_POLICY_XML_CONFIG_FILE "/system/etc/audio_policy_configuration.xml" 。。。 }
最后,附上加载函数:
/** * Load the file defined by the variant and if successful * return the dlopen handle and the hmi. * @return 0 = success, !0 = failure. */static int load(const char *id, const char *path, const struct hw_module_t **pHmi){ int status = -EINVAL; void *handle = NULL; struct hw_module_t *hmi = NULL; /* * load the symbols resolving undefined symbols before * dlopen returns. Since RTLD_GLOBAL is not or'd in with * RTLD_NOW the external symbols will not be global */ handle = dlopen(path, RTLD_NOW);//操作文件 if (handle == NULL) { char const *err_str = dlerror(); ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown"); status = -EINVAL; goto done; } /* Get the address of the struct hal_module_info. */ const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym); if (hmi == NULL) { ALOGE("load: couldn't find symbol %s", sym); status = -EINVAL; goto done; } /* Check that the id matches */ if (strcmp(id, hmi->id) != 0) { ALOGE("load: id=%s != hmi->id=%s", id, hmi->id); status = -EINVAL; goto done; } hmi->dso = handle; /* success */ status = 0; done: if (status != 0) { hmi = NULL; if (handle != NULL) { dlclose(handle); handle = NULL; } } else { ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p", id, path, *pHmi, handle); } *pHmi = hmi; return status;}
- Android——hal库加载操作流程
- Android AudioFlinger加载HAL层流程
- android hal学习——测试整个流程
- android hal学习——测试整个流程【转】
- android button light 流程分析(二) — HAL & JNI
- android button light 流程分析(二) — HAL & JNI
- android button light 流程分析(二) — HAL & JNI
- Android HAL调用流程
- Android驱动开发【框架模型】———HAL分析(入口以及对外接口)和HAL设计流程
- android hal学习——编写hal代码
- android hal学习——编写hal代码【转】
- Android使用HAL操作硬件
- Android HAL的被调用流程
- Android HAL的被调用流程
- Android HAL的被调用流程
- Android HAL的被调用流程
- Android HAL的被调用流程
- Android HAL的被调用流程
- ios-自动计算文本框的宽度和高度
- C++中函数重载的实现
- uboot分析之cconsole_init_r函数
- maven的三种部署方式
- 判断一个数是否包含平方因子
- Android——hal库加载操作流程
- centos 7.3 安装配置python3.6.1
- ubuntu16.04 配置Java环境
- jrtplib 官方示例 example2 的问题
- php 隐藏index.php 404错误
- SQL基本语法---数据查询
- Android蓝牙4.0之玩爆智能穿戴、家具(一)
- 阿里云搭建mysql数据库。
- Spark Q&A : com/mysql/jdbc/Driver : Unsupported major.minor version 52.0