函数load也是实现在文件hardware/libhardware/hardware.c文件中,如下所示:

  1. static int load(const char *id,
  2. const char *path,
  3. const struct hw_module_t **pHmi)
  4. {
  5. int status;
  6. void *handle;
  7. struct hw_module_t *hmi;
  8. /*
  9. * load the symbols resolving undefined symbols before
  10. * dlopen returns. Since RTLD_GLOBAL is not or'd in with
  11. * RTLD_NOW the external symbols will not be global
  12. */
  13. handle = dlopen(path, RTLD_NOW);
  14. if (handle == NULL) {
  15. char const *err_str = dlerror();
  16. LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
  17. status = -EINVAL;
  18. goto done;
  19. }
  20. /* Get the address of the struct hal_module_info. */
  21. const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
  22. hmi = (struct hw_module_t *)dlsym(handle, sym);
  23. if (hmi == NULL) {
  24. LOGE("load: couldn't find symbol %s", sym);
  25. status = -EINVAL;
  26. goto done;
  27. }
  28. /* Check that the id matches */
  29. if (strcmp(id, hmi->id) != 0) {
  30. LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
  31. status = -EINVAL;
  32. goto done;
  33. }
  34. hmi->dso = handle;
  35. /* success */
  36. status = 0;
  37. done:
  38. if (status != 0) {
  39. hmi = NULL;
  40. if (handle != NULL) {
  41. dlclose(handle);
  42. handle = NULL;
  43. }
  44. } else {
  45. LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
  46. id, path, *pHmi, handle);
  47. }
  48. *pHmi = hmi;
  49. return status;
  50. }
        在Linux系统中,后缀名为"so"的文件为动态链接库文件,可能通过函数dlopen来加载到内存中。硬件抽象层模块编写规范规定每一个硬件抽象层模块都必须导出一个符号名称为HAL_MODULE_INFO_SYM_AS_STR的符号,而且这个符号必须是用来描述一个类型为hw_module_t的结构体的。
        HAL_MODULE_INFO_SYM_AS_STR是一个宏,定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:
  1. #define HAL_MODULE_INFO_SYM_AS_STR  "HMI"

将Gralloc模块加载到内存中来之后,就可以调用函数dlsym来获得它所导出的符号HMI。由于这个符号指向的是一个hw_module_t结构体,因此,最后函数load就可以强制地将这个符号转换为一个hw_module_t结构体指针,并且保存在输出参数pHmi中返回给调用者。调用者获得了这个hw_module_t结构体指针之后,就可以创建一个gralloc设备或者一个fb设备。

模块Gralloc实现在目录hardware/libhardware/modules/gralloc中,它导出的符号HMI定义在文件hardware/libhardware/modules/gralloc/gralloc.cpp文件中,如下所示:

  1. static struct hw_module_methods_t gralloc_module_methods = {
  2. open: gralloc_device_open
  3. };
  4. struct private_module_t HAL_MODULE_INFO_SYM = {
  5. base: {
  6. common: {
  7. tag: HARDWARE_MODULE_TAG,
  8. version_major: 1,
  9. version_minor: 0,
  10. id: GRALLOC_HARDWARE_MODULE_ID,
  11. name: "Graphics Memory Allocator Module",
  12. author: "The Android Open Source Project",
  13. methods: &gralloc_module_methods
  14. },
  15. registerBuffer: gralloc_register_buffer,
  16. unregisterBuffer: gralloc_unregister_buffer,
  17. lock: gralloc_lock,
  18. unlock: gralloc_unlock,
  19. },
  20. framebuffer: 0,
  21. flags: 0,
  22. numBuffers: 0,
  23. bufferMask: 0,
  24. lock: PTHREAD_MUTEX_INITIALIZER,
  25. currentBuffer: 0,
  26. };

HAL_MODULE_INFO_SYM也是一个宏,它的值是与宏HAL_MODULE_INFO_SYM_AS_STR对应的,它也是定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:
图1 private_module_t结构体定义

结构体private_module_t的第一个成员变量base指向一个gralloc_module_t结构体,而gralloc_module_t结构体的第一个成员变量common又指向了一个hw_module_t结构体,这意味着,指向一个private_module_t结构体的指针同时可以用作一个gralloc_module_t或者hw_module_t结构体提针来使用。事实上,这是使用C语言来实现的一种继承关系,等价于结构体private_module_t继承结构体gralloc_module_t,而结构体gralloc_module_t继承hw_module_t结构体。这样,我们就可以把在Gralloc模块中定义的符号HAL_MODULE_INFO_SYM看作是一个hw_module_t结构体。

hw_module_t结构体有一个重要的成员变量methods,它的类型为hw_module_methods_t,它用来描述一个HAL模块的操作方法列表。结构体hw_module_methods_t只定义有一个操作方法open,用来打开一个指定的设备。在Gralloc模块中,用来打开指定设备的函数被指定为gralloc_device_open,通过这个函数就可以打开Gralloc模块中的gralloc或者fb设备,后面我们再详细分析。

本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967062,如需转载请自行联系原作者

Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(2)...相关推荐

  1. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析

    前面在介绍Android系统的开机画面时提到,Android设备的显示屏被抽象为一个帧缓冲区,而Android系统中的SurfaceFlinger服务就是通过向这个帧缓冲区写入内容来绘制应用程序的用户 ...

  2. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(10)...

    7. 图形缓冲区的注销过程        图形缓冲区使用完成之后,就需要从当前进程中注销.前面提到,注销图形缓冲区是由Gralloc模块中的函数gralloc_unregister_buffer来实现 ...

  3. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(9)...

             5. 图形缓冲区的释放过程         前面提到,用户空间的应用程序用到的图形缓冲区是由Gralloc模块中的函数gralloc_free来释放的,这个函数实现在文件hardwa ...

  4. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(8)...

       4. 分配图形缓冲区         前面提到,用户空间的应用程序用到的图形缓冲区是由Gralloc模块中的函数gralloc_alloc来分配的,这个函数实现在文件hardware/libha ...

  5. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(5)...

        3. fb设备的打开过程         在Gralloc模块中,fb设备的ID值定义为GRALLOC_HARDWARE_FB0.GRALLOC_HARDWARE_FB0是一个宏,定义在文件h ...

  6. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(4)...

            成员变量fd指向一个文件描述符,这个文件描述符要么指向帧缓冲区设备,要么指向一块匿名共享内存,取决于它的宿主结构体private_handle_t描述的一个图形缓冲区是在帧缓冲区分配的 ...

  7. Android帧布局(Frame Layout)

    Android帧布局(Frame Layout) FrameLayout是最简单的一个布局管理器.FrameLayout为每个加入其中的组件创建一个空白区域(一帧),这些组件根据layout_grav ...

  8. 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)

    更多技术干货,欢迎扫码关注博主微信公众号:HowieXue,共同探讨软件知识经验,关注就有海量学习资料免费领哦: 目录 0背景 1.手机USB接口通信特点 1.1 使用方便 1.2 通用性强 1.3 ...

  9. Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(Frame Buffer)的管理分析

    在前文中,我们分析了SurfaceFlinger服务的启动过程.SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化.由于系统的硬件帧缓冲区一般只有一个,并且不是谁都可以随 ...

最新文章

  1. C++中的虚函数表介绍
  2. 《深入理解 Java 内存模型》读书笔记(下)(干货,万字长文)
  3. 虚拟机里面安装Openfiler 2.99
  4. c语言题目1120,九度题目1120:全排列
  5. CSS基本操作详解及截图演示
  6. JAVA标准包不存在_JAVA中引入自建包时提示包不存在
  7. python 对象_python中对象可不可以
  8. H5案例分析和场景应用
  9. 数据库变为可疑_SQL数据库可疑解决方法
  10. 【dp】【斜率优化】土地购买
  11. markdown 语法
  12. 宋朝五子登科家族金榜进士涂大任后裔在松滋
  13. 智能电视:在红海之上造蓝海
  14. NetworkManager的命令行工具nmcli
  15. 最简单的视频网站(JavaEE+FFmpeg)
  16. Linux网络服务之----DHCP篇
  17. 有关python的比赛_用 Python 写一个 Kaggle 比赛排行榜的爬虫
  18. python脚本,检测域名是否被注册
  19. 在Pinterest网站开展品牌营销7种方式
  20. SRM系统对于企业的意义

热门文章

  1. linux中的fork方法(python)
  2. ios 动画设计_动画和讲故事在设计中的力量
  3. 胖子脸:库珀·布莱克100年
  4. 如何高效学习前端新知识,我推荐这些~
  5. 2017年,这两个大数据岗位一定会火!
  6. jmeter多用户登录跨线程组操作传值
  7. Spring AOP源码解析——AOP动态代理原理和实现方式
  8. 3月第4周全球域名商TOP15:万网第四 涨幅居亚
  9. http://blog.csdn.net/myan/article/details/1906
  10. redhat enterprise linux 5 上安装openoffice3.0 1