转自:http://hi.baidu.com/xdyang1986/blog/item/1681d3d4ef4a63d251da4bd5.html
这个函数的主要功能是根据模块ID寻找硬件模块动态链接库德地址,然后调用load去打开动态链接库并从中获取硬件模块结构体地址。具体的源码如下:
代码@/hardware/libhardware/hardware.c
-
int hw_get_module(const char *id, const struct hw_module_t **module)
-
-
120 {
-
-
121 int status;
-
-
122 int i;
-
-
123 const struct hw_module_t *hmi = NULL;
-
-
124 char prop[PATH_MAX];
-
-
125 char path[PATH_MAX];
-
-
-
-
135 for (i=0 ; i
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
* 47 "ro.product.board",
-
-
* 48 "ro.board.platform",
-
-
* 49 "ro.arch"
-
-
* 50 };
-
-
*这里我们记住这个数组,下面我就将用到它。
-
-
*/
-
-
136 if (i < HAL_VARIANT_KEYS_COUNT) {
-
-
137 if (property_get(variant_keys[i], prop, NULL) == 0) {
-
-
138 continue;
-
-
139 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
140 snprintf(path, sizeof(path), "%s/%s.%s.so",
-
-
141 HAL_LIBRARY_PATH, id, prop);
-
-
-
-
-
-
-
-
142 } else {
-
-
-
-
-
-
-
-
143 snprintf(path, sizeof(path), "%s/%s.default.so",
-
-
144 HAL_LIBRARY_PATH, id);
-
-
145 }
-
-
146 if (access(path, R_OK)) {
-
-
147 continue;
-
-
148 }
-
-
149
-
-
150 break;
-
-
151 }
-
-
152
-
-
153 status = -ENOENT;
-
-
154 if (i < HAL_VARIANT_KEYS_COUNT+1) {
-
-
155
-
-
-
-
157 status = load(id, path, module);
-
-
158 }
-
-
159
-
-
return status;
-
-
161 }
int hw_get_module(const char *id, const struct hw_module_t **module)
120 {
121 int status;
122 int i;
123 const struct hw_module_t *hmi = NULL;
124 char prop[PATH_MAX];
125 char path[PATH_MAX];
/* Loop through the configuration variants looking for a module */
135 for (i=0 ; i
代码@/hardware/libhardware/hardware.c
这个代码其实很简单。load相应库。并把它们的HMI保存到module中
-
static int load(const char *id,
-
-
const char *path,
-
-
const struct hw_module_t **pHmi)
-
-
{
-
-
int status;
-
-
void *handle;
-
-
struct hw_module_t *hmi;
-
-
handle = dlopen(path, RTLD_NOW);
-
-
if (handle == NULL) {
-
-
char const *err_str = dlerror();
-
-
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
-
-
status = -EINVAL;
-
-
goto done;
-
-
}
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
int status;
void *handle;
struct hw_module_t *hmi;
handle = dlopen(path, RTLD_NOW);//打开相应的库
if (handle == NULL) {
char const *err_str = dlerror();
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
-
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
-
-
hmi = (struct hw_module_t *)dlsym(handle, sym);
-
-
if (hmi == NULL) {
-
-
LOGE("load: couldn't find symbol %s", sym);
-
-
status = -EINVAL;
-
-
goto done;
-
-
}
-
-
-
-
if (strcmp(id, hmi->id) != 0) {
-
-
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
-
-
status = -EINVAL;
-
-
goto done;
-
-
}
-
-
hmi->dso = handle;
-
-
-
-
status = 0;
-
-
done:
-
-
if (status != 0) {
-
-
hmi = NULL;
-
-
if (handle != NULL) {
-
-
dlclose(handle);
-
-
handle = NULL;
-
-
}
-
-
} else {
-
-
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
-
-
id, path, *pHmi, handle);
-
-
}
-
-
*pHmi = hmi;
-
-
return status;
-
-
}
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);//找到库中的HMI函数的地址(据snownight0102说,HMI不是一个函数,我还不是很清楚,等待解释)
if (hmi == NULL) {
LOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {//只是一个check
LOGE("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 {
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;//把这个返回过去
return status;
}
以上为转载
以下为hardware/libhardware/hardware.c
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#include
-
-
#include
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define LOG_TAG "HAL"
-
#include
-
-
-
#define HAL_LIBRARY_PATH "/system/lib/hw"
-
-
-
-
-
-
-
-
-
-
-
-
-
static const char *variant_keys[] = {
-
"ro.hardware",
-
-
"ro.product.board",
-
"ro.board.platform",
-
"ro.arch"
-
};
-
-
static const int HAL_VARIANT_KEYS_COUNT =
-
(sizeof(variant_keys)/sizeof(variant_keys[0]));
-
-
-
-
-
-
-
static int load(const char *id,
-
const char *path,
-
const struct hw_module_t **pHmi)
-
{
-
int status;
-
void *handle;
-
struct hw_module_t *hmi;
-
-
-
-
-
-
-
handle = dlopen(path, RTLD_NOW);
-
if (handle == NULL) {
-
char const *err_str = dlerror();
-
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
-
status = -EINVAL;
-
goto done;
-
}
-
-
-
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
-
hmi = (struct hw_module_t *)dlsym(handle, sym);
-
if (hmi == NULL) {
-
LOGE("load: couldn't find symbol %s", sym);
-
status = -EINVAL;
-
goto done;
-
}
-
-
-
if (strcmp(id, hmi->id) != 0) {
-
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
-
status = -EINVAL;
-
goto done;
-
}
-
-
hmi->dso = handle;
-
-
-
status = 0;
-
-
done:
-
if (status != 0) {
-
hmi = NULL;
-
if (handle != NULL) {
-
dlclose(handle);
-
handle = NULL;
-
}
-
} else {
-
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
-
id, path, *pHmi, handle);
-
}
-
-
*pHmi = hmi;
-
-
return status;
-
}
-
-
int hw_get_module(const char *id, const struct hw_module_t **module)
-
{
-
int status;
-
int i;
-
const struct hw_module_t *hmi = NULL;
-
char prop[PATH_MAX];
-
char path[PATH_MAX];
-
-
-
-
-
-
-
-
-
-
for (i=0 ; i
-
if (i < HAL_VARIANT_KEYS_COUNT) {
-
if (property_get(variant_keys[i], prop, NULL) == 0) {
-
continue;
-
}
-
snprintf(path, sizeof(path), "%s/%s.%s.so",
-
HAL_LIBRARY_PATH, id, prop);
-
} else {
-
snprintf(path, sizeof(path), "%s/%s.default.so",
-
HAL_LIBRARY_PATH, id);
-
}
-
if (access(path, R_OK)) {
-
continue;
-
}
-
-
break;
-
}
-
-
status = -ENOENT;
-
if (i < HAL_VARIANT_KEYS_COUNT+1) {
-
-
-
status = load(id, path, module);
-
}
-
-
return status;
-
}
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include
#include
#include
#include
#include
#include
#include
#define LOG_TAG "HAL"
#include
/** Base path of the hal modules */
#define HAL_LIBRARY_PATH "/system/lib/hw"
/**
* There are a set of variant filename for modules. The form of the filename
* is ".variant.so" so for the led module the Dream variants
* of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:
*
* led.trout.so
* led.msm7k.so
* led.ARMV6.so
* led.default.so
*/
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"
};
static const int HAL_VARIANT_KEYS_COUNT =
(sizeof(variant_keys)/sizeof(variant_keys[0]));
/**
* 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;
void *handle;
struct hw_module_t *hmi;
/*
* 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();
LOGE("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) {
LOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
LOGE("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 {
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;
return status;
}
int hw_get_module(const char *id, const struct hw_module_t **module)
{
int status;
int i;
const struct hw_module_t *hmi = NULL;
char prop[PATH_MAX];
char path[PATH_MAX];
/*
* 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.
*/
/* Loop through the configuration variants looking for a module */
for (i=0 ; i
阅读(1097) | 评论(0) | 转发(0) |