Android Hardwarw/libhardware/hardware.c[h] 代码注释

Hardwarw/libhardware/hardware.c[h]

 

Android中为了给用户提供统一的硬件接口和硬件形态,在Linux kernel和用户空间之间,实现了一个HAL,硬件抽象层。这使得Android中的framework只需要关心HAL中的东西,而不用关心具体的硬件实现。

 

HAL将硬件抽象为三个不同的概念,分别是modulemethoddevice,这三个抽象概念在hardware.h中进行了描述。

 

Libhardware主要完成加载不同的HAL模块。

 

 

 

HAL模块的源代码路径在harware中,对于不同的hardwareHAL,其对应的lib命名规则:id.variant.so,比如gralloc.msm7k.so,这个id就是grallocmsm7kvariant

variant 的取值范围是在该文件中的定义的variant_keys对应的值。

46 "ro.hardware", /* This goes first so that it can pick up a different

47 file on the emulator. */

48 "ro.product.board",

49 "ro.board.platform",

50 "ro.arch"

 

id的取值可以在hardware/libhardware/include/hareware下的各个.h文件中查找。

 

 

为了方便理解,以下的注释对源文件做了相应的调整。注释用斜体字。

 

 

30 /** Base path of the hal modules */

31 #define HAL_LIBRARY_PATH1 "/system/lib/hw"

32 #define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

33

注释:寻找加载的模块路径

 

34 /**

35 * There are a set of variant filename for modules. The form of the filename

36 * is "<MODULE_ID>.variant.so" so for the led module the Dream variants

37 * of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:

38 *

39 * led.trout.so

40 * led.msm7k.so

41 * led.ARMV6.so

42 * led.default.so

43 */

44

45 static const char *variant_keys[] = {

46 "ro.hardware", /* This goes first so that it can pick up a different

47 file on the emulator. */

48 "ro.product.board",

49 "ro.board.platform",

50 "ro.arch"

51 };

52

53 static const int HAL_VARIANT_KEYS_COUNT =

54 (sizeof(variant_keys)/sizeof(variant_keys[0]));

55

注释:查找variant的取值范围。

 

注释:id是要获取的硬件模块的id名,module用于返回所需要的hw_module_t

120 int hw_get_module(const char *id, const struct hw_module_t **module)

121 {

122 int status;

123 int i;

124 const struct hw_module_t *hmi = NULL;

125 char prop[PATH_MAX];

126 char path[PATH_MAX];

127

128 /*

129 * Here we rely on the fact that calling dlopen multiple times on

130 * the same .so will simply increment a refcount (and not load

131 * a new copy of the library).

132 * We also assume that dlopen() is thread-safe.

133 */

134

135 /* Loop through the configuration variants looking for a module */

136 for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {

137 if (i < HAL_VARIANT_KEYS_COUNT) {

138 if (property_get(variant_keys[i], prop, NULL) == 0) {

139 continue;

140 }

141 snprintf(path, sizeof(path), "%s/%s.%s.so",

142 HAL_LIBRARY_PATH1, id, prop);

143 if (access(path, R_OK) == 0) break;

144

145 snprintf(path, sizeof(path), "%s/%s.%s.so",

146 HAL_LIBRARY_PATH2, id, prop);

147 if (access(path, R_OK) == 0) break;

148 } else {

149 snprintf(path, sizeof(path), "%s/%s.default.so",

150 HAL_LIBRARY_PATH1, id);

151 if (access(path, R_OK) == 0) break;

152 }

153 }

154

注释:通过Android property system获取variant对应的property值,比如是msm7komap3。将取到的prop值和id,拼接成名字,查看有没有相应的文件,比如/system/lib/hw/gralloc.omap3.so。如果找到,则跳出循环,如果没有找到,则找到默认的,比如gralloc.default.so

 

155 status = -ENOENT;

156 if (i < HAL_VARIANT_KEYS_COUNT+1) {

157 /* load the module, if this fails, we're doomed, and we should not try

158 * to load a different variant. */

159 status = load(id, path, module);

160 }

161

162 return status;

163 }

注释:如果找到了相应的库,则进行加载,否则返回-ENOENT

 

 

 

56 /**

57 * Load the file defined by the variant and if successful

58 * return the dlopen handle and the hmi.

59 * @return 0 = success, !0 = failure.

60 */

61 static int load(const char *id,

62 const char *path,

63 const struct hw_module_t **pHmi)

64 {

65 int status;

66 void *handle;

67 struct hw_module_t *hmi;

68

69 /*

70 * load the symbols resolving undefined symbols before

71 * dlopen returns. Since RTLD_GLOBAL is not or'd in with

72 * RTLD_NOW the external symbols will not be global

73 */

74 handle = dlopen(path, RTLD_NOW);

75 if (handle == NULL) {

76 char const *err_str = dlerror();

77 LOGE("load: module=%s/n%s", path, err_str?err_str:"unknown");

78 status = -EINVAL;

79 goto done;

80 }

81

注释:打开对应的lib动态库,获取句柄。这里的打开要注意是实时解析符号。就是说libhardware中能使用所打开的id.variant.so中的符号。

 

82 /* Get the address of the struct hal_module_info. */

83 const char *sym = HAL_MODULE_INFO_SYM_AS_STR;

注释:hardware.h中定义,代表的是hardware module info

112 #define HAL_MODULE_INFO_SYM_AS_STR "HMI"

 

 

84 hmi = (struct hw_module_t *)dlsym(handle, sym);

85 if (hmi == NULL) {

86 LOGE("load: couldn't find symbol %s", sym);

87 status = -EINVAL;

88 goto done;

89 }

90

注释:导出sym对应的地址,解析为hw_module_t

这里的sym如何能解释为hw_module_t

/out/target/product/generic/system/lib/hw/找到任意.so,比如gralloc.default.so,通过readelf读取符号表: readelf sensors.goldfish.so -s,截取相关的内容:

19: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_mutex_lock

20: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_mutex_unlock

21: 00000000 0 FUNC GLOBAL DEFAULT UND free

22: 00002180 448 OBJECT GLOBAL DEFAULT 14 HMI

查看对应gralloc中的定义,会有一个HAL_MODULE_INFO_SYM,这个会导出为HMI

78 struct private_module_t HAL_MODULE_INFO_SYM = {

79 base: {

80 common: {

81 tag: HARDWARE_MODULE_TAG,

82 version_major: 1,

83 version_minor: 0,

84 id: GRALLOC_HARDWARE_MODULE_ID,

85 name: "Graphics Memory Allocator Module",

86 author: "The Android Open Source Project",

87 methods: &gralloc_module_methods

88 },

89 registerBuffer: gralloc_register_buffer,

90 unregisterBuffer: gralloc_unregister_buffer,

91 lock: gralloc_lock,

92 unlock: gralloc_unlock,

93 },

94 framebuffer: 0,

95 flags: 0,

96 numBuffers: 0,

97 bufferMask: 0,

98 lock: PTHREAD_MUTEX_INITIALIZER,

99 currentBuffer: 0,

100 };

 

 

 

 

91 /* Check that the id matches */

92 if (strcmp(id, hmi->id) != 0) {

93 LOGE("load: id=%s != hmi->id=%s", id, hmi->id);

94 status = -EINVAL;

95 goto done;

96 }

97

98 hmi->dso = handle;

99

100 /* success */

101 status = 0;

102

103 done:

104 if (status != 0) {

105 hmi = NULL;

106 if (handle != NULL) {

107 dlclose(handle);

108 handle = NULL;

109 }

110 } else {

111 LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",

112 id, path, *pHmi, handle);

113 }

114

115 *pHmi = hmi;

116

117 return status;

118 }

119  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值