在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)

时间:2022-07-11 23:37:19
Android系统硬件驱动程序的另一种实现 ---- 在硬件抽象层中增加硬件模块来和内核驱动程序交互。


结合老罗的博客,我自己分析总结一下:::


1. 在~/Android_4.2.2_SourceCode/hardware/libhardware/include/hardware下新建hello.h

内容如下:

#ifndef ANDROID_HELLO_INTERFACE_H  
#define ANDROID_HELLO_INTERFACE_H
#include <hardware/hardware.h>

__BEGIN_DECLS

/*定义模块ID*/
#define HELLO_HARDWARE_MODULE_ID "hello"

/*硬件模块结构体*/
struct hello_module_t {
struct hw_module_t common;
};

/*硬件接口结构体*/
struct hello_device_t {
struct hw_device_t common;
int fd; // 设备文件描述符
int (*set_val)(struct hello_device_t* dev, int val);
int (*get_val)(struct hello_device_t* dev, int* val);
};

__END_DECLS

#endif

这里按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体以及硬件接口结构体。在硬件接口结构体中,fd表示设备文件描述符,对应我们将要处理的设备文件"/dev/hello",set_val和get_val为该HAL对上提供的函数接口。


2. 新建~/Android_4.2.2_SourceCode/hardware/libhardware/modules/hello目录,并添加

hello.c内容如下:

#define LOG_TAG "HelloStub"  

#include <hardware/hardware.h>
#include <hardware/hello.h>
#include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>


#define DEVICE_NAME "/dev/hello"
#define MODULE_NAME "Hello"
#define MODULE_AUTHOR "huangh0624@gmail.com"

/*设备打开和关闭接口*/
static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
static int hello_device_close(struct hw_device_t* device);

/*设备访问接口*/
static int hello_set_val(struct hello_device_t* dev, int val);
static int hello_get_val(struct hello_device_t* dev, int* val);

/*模块方法表*/
static struct hw_module_methods_t hello_module_methods = {
open: hello_device_open
};

/*模块实例变量*/
/* 实例变量名必须为HAL_MODULE_INFO_SYM,
* tag也必须为HARDWARE_MODULE_TAG,这是Android硬件抽象层规范规定的*/
struct hello_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: HELLO_HARDWARE_MODULE_ID,
name: MODULE_NAME,
author: MODULE_AUTHOR,
methods: &hello_module_methods,
}
};

static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {
struct hello_device_t* dev;dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));

if(!dev) {
ALOGE("Hello Stub: failed to alloc space");
return -EFAULT;
}

memset(dev, 0, sizeof(struct hello_device_t));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = (hw_module_t*)module;
dev->common.close = hello_device_close;
dev->set_val = hello_set_val;dev->get_val = hello_get_val;

if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
ALOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);
return -EFAULT;
}

*device = &(dev->common);
ALOGI("Hello Stub: open /dev/hello successfully.");

return 0;
}

static int hello_device_close(struct hw_device_t* device) {
struct hello_device_t* hello_device = (struct hello_device_t*)device;

if(hello_device) {
close(hello_device->fd);
free(hello_device);
}

return 0;
}

static int hello_set_val(struct hello_device_t* dev, int val) {
ALOGI("Hello Stub: set value %d to device.", val);

write(dev->fd, &val, sizeof(val));

return 0;
}

static int hello_get_val(struct hello_device_t* dev, int* val) {
if(!val) {
ALOGE("Hello Stub: error val pointer");
return -EFAULT;
}

read(dev->fd, val, sizeof(*val));

ALOGI("Hello Stub: get value %d from device", *val);

return 0;
}

注意:老罗博客里面全是LOGI, LOGE,被我改为ALOGI, ALOGE。因为
#include <cutils/log.h>
引用的文件地址为:~/Android_4.2.2_SourceCode/system/core/include/cutils/log.h

这里我发现没有LOGI,只有ALOGI。应该是android版本更新改变了一些宏定义而已。。。。


3. 该目录下新建Android.mk文件

内容如下:

      LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := hello.c
LOCAL_MODULE := hello.default
include $(BUILD_SHARED_LIBRARY)

4. 编译

编译前需要初始化相关工具:

$ cd ~/Android_4.2.2_SourceCode

$ source ./build/envsetup.sh

然后就可以使用mmm工具了

继续

~/Android_4.2.2_SourceCode$ mmm hardware/libhardware/modules/hello

下面是截取的编译过程 :

make:进入目录'/home/hwh/Android_4.2.2_SourceCode'
target thumb C: hello <= hardware/libhardware/modules/hello/hello.c
target SharedLib: hello (out/target/product/generic/obj/SHARED_LIBRARIES/hello_intermediates/LINKED/hello.so)
target Symbolic: hello (out/target/product/generic/symbols/system/lib/hw/hello.so)
target Strip: hello (out/target/product/generic/obj/lib/hello.so)
Install: out/target/product/generic/system/lib/hw/hello.so
make:离开目录“/home/hwh/Android_4.2.2_SourceCode”
然后我们去
~/Android_4.2.2_SourceCode/out/target/product/generic/system/lib/hw/hello.so发现了hello.so文件,说明编译成功。

5. 重新打包Android系统镜像system.img

~/Android_4.2.2_SourceCode $ make snod
 重新打包后,system.img就包含我们定义的硬件抽象层模块hello.default了。


写道这里,其实遗漏一个部分,就是老罗说的,除非root的系统,才能访问我们的hello.so文件。但是是否真的不能访问,我需要验证。

待我验证完毕后,再添加老罗说的那部分。。




// 下面是老罗写的文章

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

地址:http://blog.csdn.net/luoshengyang/article/details/6573809

 在Android硬件抽象层(HAL)概要介绍和学习计划一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法。简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。接着,在Ubuntu上为Android系统编写Linux内核驱动程序一文中举例子说明了如何在Linux内核编写驱动程序。在这一篇文章中,我们将继续介绍Android系统硬件驱动程序的另一方面实现,即如何在硬件抽象层中增加硬件模块来和内核驱动程序交互。在这篇文章中,我们还将学习到如何在Android系统创建设备文件时用类似Linux的udev规则修改设备文件模式的方法。

      一. 参照在Ubuntu上为Android系统编写Linux内核驱动程序一文所示,准备好示例内核驱动序。完成这个内核驱动程序后,便可以在Android系统中得到三个文件,分别是/dev/hello、/sys/class/hello/hello/val和/proc/hello。在本文中,我们将通过设备文件/dev/hello来连接硬件抽象层模块和Linux内核驱动程序模块。

      二. 进入到在hardware/libhardware/include/hardware目录,新建hello.h文件:

      USER-NAME@MACHINE-NAME:~/Android$ cd hardware/libhardware/include/hardware

      USER-NAME@MACHINE-NAME:~/Android/hardware/libhardware/include/hardware$ vi hello.h

      hello.h文件的内容如下:

      

[cpp] view plaincopy
  1. #ifndef ANDROID_HELLO_INTERFACE_H  
  2. #define ANDROID_HELLO_INTERFACE_H  
  3. #include <hardware/hardware.h>  
  4.   
  5. __BEGIN_DECLS  
  6.   
  7. /*定义模块ID*/  
  8. #define HELLO_HARDWARE_MODULE_ID "hello"  
  9.   
  10. /*硬件模块结构体*/  
  11. struct hello_module_t {  
  12.     struct hw_module_t common;  
  13. };  
  14.   
  15. /*硬件接口结构体*/  
  16. struct hello_device_t {  
  17.     struct hw_device_t common;  
  18.     int fd;  
  19.     int (*set_val)(struct hello_device_t* dev, int val);  
  20.     int (*get_val)(struct hello_device_t* dev, int* val);  
  21. };  
  22.   
  23. __END_DECLS  
  24.   
  25. #endif  

      这里按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体以及硬件接口结构体。在硬件接口结构体中,fd表示设备文件描述符,对应我们将要处理的设备文件"/dev/hello",set_val和get_val为该HAL对上提供的函数接口。

      三. 进入到hardware/libhardware/modules目录,新建hello目录,并添加hello.c文件。 hello.c的内容较多,我们分段来看。

      首先是包含相关头文件和定义相关结构:

      

[cpp] view plaincopy
  1. #define LOG_TAG "HelloStub"  
  2.   
  3. #include <hardware/hardware.h>  
  4. #include <hardware/hello.h>  
  5. #include <fcntl.h>  
  6. #include <errno.h>  
  7. #include <cutils/log.h>  
  8. #include <cutils/atomic.h>  
  9.   
  10. #define DEVICE_NAME "/dev/hello"  
  11. #define MODULE_NAME "Hello"  
  12. #define MODULE_AUTHOR "shyluo@gmail.com"  
  13.   
  14. /*设备打开和关闭接口*/  
  15. static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);  
  16. static int hello_device_close(struct hw_device_t* device);  
  17.   
  18. /*设备访问接口*/  
  19. static int hello_set_val(struct hello_device_t* dev, int val);  
  20. static int hello_get_val(struct hello_device_t* dev, int* val);  
  21.   
  22. /*模块方法表*/  
  23. static struct hw_module_methods_t hello_module_methods = {  
  24.     open: hello_device_open  
  25. };  
  26.   
  27. /*模块实例变量*/  
  28. struct hello_module_t HAL_MODULE_INFO_SYM = {  
  29.     common: {  
  30.         tag: HARDWARE_MODULE_TAG,  
  31.         version_major: 1,  
  32.         version_minor: 0,  
  33.         id: HELLO_HARDWARE_MODULE_ID,  
  34.         name: MODULE_NAME,  
  35.         author: MODULE_AUTHOR,  
  36.         methods: &hello_module_methods,  
  37.     }  
  38. };  

      这里,实例变量名必须为HAL_MODULE_INFO_SYM,tag也必须为HARDWARE_MODULE_TAG,这是Android硬件抽象层规范规定的。

      定义hello_device_open函数:

      

[cpp] view plaincopy
  1. static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {  
  2.     struct hello_device_t* dev;dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));  
  3.       
  4.     if(!dev) {  
  5.         LOGE("Hello Stub: failed to alloc space");  
  6.         return -EFAULT;  
  7.     }  
  8.   
  9.     memset(dev, 0, sizeof(struct hello_device_t));  
  10.     dev->common.tag = HARDWARE_DEVICE_TAG;  
  11.     dev->common.version = 0;  
  12.     dev->common.module = (hw_module_t*)module;  
  13.     dev->common.close = hello_device_close;  
  14.     dev->set_val = hello_set_val;dev->get_val = hello_get_val;  
  15.   
  16.     if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {  
  17.         LOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);  
  18.         return -EFAULT;  
  19.     }  
  20.   
  21.     *device = &(dev->common);  
  22.     LOGI("Hello Stub: open /dev/hello successfully.");  
  23.   
  24.     return 0;  
  25. }  

      DEVICE_NAME定义为"/dev/hello"。由于设备文件是在内核驱动里面通过device_create创建的,而device_create创建的设备文件默认只有root用户可读写,而hello_device_open一般是由上层APP来调用的,这些APP一般不具有root权限,这时候就导致打开设备文件失败:

      Hello Stub: failed to open /dev/hello -- Permission denied.       解决办法是类似于Linux的udev规则,打开Android源代码工程目录下,进入到system/core/rootdir目录,里面有一个名为ueventd.rc文件,往里面添加一行:       /dev/hello 0666 root root       定义hello_device_close、hello_set_val和hello_get_val这三个函数:       [cpp] view plaincopy
  1. static int hello_device_close(struct hw_device_t* device) {  
  2.     struct hello_device_t* hello_device = (struct hello_device_t*)device;  
  3.   
  4.     if(hello_device) {  
  5.         close(hello_device->fd);  
  6.         free(hello_device);  
  7.     }  
  8.       
  9.     return 0;  
  10. }  
  11.   
  12. static int hello_set_val(struct hello_device_t* dev, int val) {  
  13.     LOGI("Hello Stub: set value %d to device.", val);  
  14.   
  15.     write(dev->fd, &val, sizeof(val));  
  16.   
  17.     return 0;  
  18. }  
  19.   
  20. static int hello_get_val(struct hello_device_t* dev, int* val) {  
  21.     if(!val) {  
  22.         LOGE("Hello Stub: error val pointer");  
  23.         return -EFAULT;  
  24.     }  
  25.   
  26.     read(dev->fd, val, sizeof(*val));  
  27.   
  28.     LOGI("Hello Stub: get value %d from device", *val);  
  29.   
  30.     return 0;  
  31. }  

      四. 继续在hello目录下新建Android.mk文件:       LOCAL_PATH := $(call my-dir)       include $(CLEAR_VARS)      LOCAL_MODULE_TAGS := optional      LOCAL_PRELINK_MODULE := false      LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw      LOCAL_SHARED_LIBRARIES := liblog      LOCAL_SRC_FILES := hello.c      LOCAL_MODULE := hello.default      include $(BUILD_SHARED_LIBRARY)      注意,LOCAL_MODULE的定义规则,hello后面跟有default,hello.default能够保证我们的模块总能被硬象抽象层加载到。      五. 编译:      USER-NAME@MACHINE-NAME:~/Android$ mmm hardware/libhardware/modules/hello      编译成功后,就可以在out/target/product/generic/system/lib/hw目录下看到hello.default.so文件了。      六. 重新打包Android系统镜像system.img:      USER-NAME@MACHINE-NAME:~/Android$ make snod      重新打包后,system.img就包含我们定义的硬件抽象层模块hello.default了。      虽然我们在Android系统为我们自己的硬件增加了一个硬件抽象层模块,但是现在Java应用程序还不能访问到我们的硬件。我们还必须编写JNI方法和在Android的Application Frameworks层增加API接口,才能让上层Application访问我们的硬件。在接下来的文章中,我们还将完成这一系统过程,使得我们能够在Java应用程序中访问我们自己定制的硬件。 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!
39
0
查看评论
41楼 only09030301112013-05-24 15:19发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
*device = &(dev->common); 这个不对吧,应该是这样吧*device = dev
Re: 罗升阳2013-05-25 01:12发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复only0903030111:一样的,common是dev是第一个成员变量,它们的地址是一样的。
40楼 jay07252013-04-07 13:49发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
罗老师,想问下。我在HAL里调用system和mkfifo等系统函数,由APK来调用。但是没有执行system和mkfifo函数的权限。请问在哪个位置修改权限?
谢谢!
Re: 罗升阳2013-04-07 14:21发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复jay0725:1. 将你的APP放在Android源代码工程环境下编译,在AndroidManifest.xml加入android:sharedUserId="android.uid.system",并且在Android.mk加入LOCAL_CERTIFICATE := platform。或者:
2. root你的手机,并且赋予你的APP这个root权限。
两种方法都不好实现,要是好实现,就没有安全性而言了。
Re: jay07252013-04-23 11:28发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:谢谢罗老师!
按照方法试了下,mkfifo有效果,但是用system("mkdir xxxx");
还是没有效果。
39楼 all80232013-04-06 15:43发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
楼主你好,我编译的友善之臂提供的android源码,在out/target/product/smdk210/system/lib/hw下没有生成led.default.so。我找了一下在out/target/product/smdk210/obj路径下生成了led.default.so。请问这个库算是编译成功了吗?我在写android应用程序时把这个库导入了工程里,APK程序运行的时候提示找不到这个库,能帮忙啊分析一下吗?
38楼 binglansong2013-03-13 17:56发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
罗老师你好,我在编译的时候,出现过这两种情况,第一次是提示:没有什么可以做的为“all_modules”。我查看了xbin那个目录,发现里面已经有一个我想要生成ledapp(可能是开发板中源码自带了一个),所以想是不是因为已经生成了app所以没有可以做的,我剪切出来,再mmm,进入目录后的提示只有一行:Istall:out/target/product/tq210/system/xbin/ledapp 。这个没有其他的生成过程的提示。又一次编译的时候提示:进入目录“/。/。/。/device/embedsky/tq210/device.mk:41:”*** commands commence before first target. 停止。因为这个生成的.so文件要复制到另一个文件夹下,我去查看那个文件夹,发现本来就有将要生成的.so文件,但是这次剪掉后还是出现同样的提示。请问是什么问题呢。谢谢罗老师
37楼 longyi01072013-01-10 23:43发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
老罗,你好,看到这里我有一个疑问:
android HAL层设计是用来让厂商不用公布驱动程序的源码的?
但目前看到好像驱动程序的源码还是在添加在内核里,所以还是要公布出来,是吗?
Re: 罗升阳2013-01-11 09:28发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复longyi0107:前面有介绍:http://blog.csdn.net/luoshengyang/article/details/6567257
Re: longyi01072013-01-11 21:02发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:仔细体会了下,有点感觉了。呵呵~
内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了,这样就可以把商业秘密隐藏起来了。也正是由于这个分层的原因,Android被踢出了Linux内核主线代码树中。大家想想,Android放在内核空间的驱动程序对硬件的支持是不完整的,把Linux内核移植到别的机器上去时,由于缺乏硬件抽象层的支持,硬件就完全不能用了
36楼 longkg2012-11-21 17:34发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
罗老师你好,我现在想将framebuffer里面的数据直接拷贝出来,那么本地层如何通过jni接口直接往java层传递一连串的字符串呢?
Re: 罗升阳2012-11-21 21:12发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复longkg:传它符串和传其它值是一样的嘛,你可以看一下JNI的数据类型有哪些,怎么用。
35楼 孙培雨2012-11-02 16:01发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
我下的4.1的,log.h里面已经没有LOGI、LOGE函数了,变成ALOGI、ALOGE了。
Re: 罗升阳2012-11-02 21:13发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复sudev:那就要改一下这里的代码了,不过即使这些变了,基本原理也还是一样的~
Re: 孙培雨2012-11-07 20:58发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:恩,是的!
34楼 百無一用是書生2012-10-23 21:52发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
这几天把这一系列的实做给练习了一便,感觉不错,遇到的问题就是/dev/hello权限的问题。下边主要是对/dev/hello权限的修改提供一下自己的笨方法。仅供参考。
方法1。devices.h这个文件修改还是不能解决的可以去改/system/core/rootdir/init.rc ,加上chmod 777 /dev 和chmod 777 /dev/hello.注意有的时候你可能要改提供商的init.rc,一股可能在/device/厂商/板子平台/ 实在不行全局搜索。
方法2。直接再系统启动后,在主机用命令adb shell mount -o remount rw /dev, 然后adb shell进入板子,再chmod 777 /dev 和chmod 777 /dev/hello. 接下来再stop命令和start命令重启android.记住不是重启板子!!!
另外adb shell mount -o remount rw 目标 非常好用,有的时候要push一些东西但又没有权限时可以用这条指令。。
33楼 chdyuxin2012-10-18 10:50发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
为什么我按照你的做了,编译通过了还是没有看见hello.default.so 文件
Re: 罗升阳2012-10-18 11:04发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复chdyuxin:那编译出来的是什么文件?
32楼 suifeng2012-08-09 14:47发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
我把自己奇怪的错误,贴在这里,希望其他人不要再犯类似的错误:
build/core/base_rules.mk:73: unusual tags optinal on hello.default at hardware/libhardware/modules/hello
target C: hello.default <= hardware/libhardware/modules/hello/hello.c
target SharedLib: hello.default (out/target/product/adv_x86/obj/SHARED_LIBRARIES/hello.default_intermediates/LINKED/hello.default.so)
out/target/product/adv_x86/obj/lib/crtbegin_so.o: In function `__do_global_dtors_aux':
(.text+0x25): undefined reference to `__cxa_finalize'
out/target/product/adv_x86/obj/lib/crtbegin_so.o: In function `atexit':
(.text+0xcb): undefined reference to `__cxa_atexit'
out/target/product/adv_x86/obj/lib/crtbegin_so.o: In function `__stack_chk_fail_local':
。。。
make: *** [out/target/product/adv_x86/obj/SHARED_LIBRARIES/hello.default_intermediates/LINKED/hello.default.so] Error 1
make: Leaving directory `/home/txf/ANDROID'
解决方法:
从modules下的其他目录里面,拷贝一个Android.mk 文件放在hello 目录中间,然后将需要的项修改即可!
31楼 qinyun1882012-04-11 15:28发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
你好,我想问一下,我按你的步骤编译下来,但是我的out/target/product/这个目录下没有生成generic文件,只有ideal6410这个目录,在这个目录下就有/system/lib/hw,但是里面没有生成hello.default.so 呢?
Re: lqxandroid20122012-08-02 11:52发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复qinyun188:也许不在这个路径
/system/lib/hw 这个是有的。
O(∩_∩)O哈哈~,搜索一下,总会有的。
我照着博主的做,搞完整个流程了。
蛮好玩的。
Re: qinyun1882012-08-03 10:42发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复lqxandroid2012:嗯,那时候我是按着流程来移植一个从顶层到底层的应用,已经做好了。还是谢谢。。。
30楼 manshq163com2012-04-09 17:26发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
正在做android 的产品,搜索到了楼主的博客,太好了写的,必须要顶一下.另外楼主能否写一下关于android 内核驱动调试的方法可以吗 ,对我们这种初学者来说,很有帮助
29楼 kongji1232012-04-08 10:41发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
LZ,怎么我编译
mmm hardware/libhardware/moudles/hello报错,
make:进入目录'/home/yzh/android2.3_lau'
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/hello.default_intermediates/hello.o”需要的目标“/hello.c”。 停止。
make:离开目录“/home/yzh/android2.3_lau”
我在hello目录下有hello.c 和Android.mk,怎么报需要目标“/hello.c”
这个问題到底怎么解决啊,这个哥们只是说知道了,但并没有说怎么解决的
Re: kongji1232012-04-08 14:34发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复kongji123:问题已找到,是Android.mk中字符格式问题,在把老罗的内容复制粘贴到新建的Android.mk文件的时候字符格式可能发生了变化,后来自己把modules目录下overlay项目下的Android.mk复制过来修改成hello的则编译通过
28楼 oucsunjie2012-03-28 16:47发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主,您好!我仿照你的程序正在写led的HAL模块,我在编译时遇到这样的问题:
[root@OUC-B103 modules]# mmm led/
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.4
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRJ22
============================================
make: 进入目录“/opt/FriendlyARM/tiny6410/android/Android-2.3.4”
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/led.default_intermediates/LINKED/led.default.so”需要的目标“out/target/product/generic/obj/lib/liblog.so”。 停止。
make: 离开目录“/opt/FriendlyARM/tiny6410/android/Android-2.3.4”
麻烦您给一些建议,谢谢了!
Re: qinyun1882012-04-11 15:44发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复oucsunjie:你好,我现在也遇到了跟你一样的问题,请问你的解决了吗?是怎么解决的呢?谢谢
Re: oucsunjie2012-04-12 16:04发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复qinyun188:把build目录下的buildspec.mk.defaultf复制一下,放到Android-2.3.4目录下,重命名为buildspec.mk,打开该文件,修改#TARGET_PRODUCT:=generic,把前面的#去掉,把generic改为你编译源码后生成的那个文件的名字,这样就可以了
Re: jgm9282013-06-19 17:14发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复oucsunjie:你说的"把generic改为你编译源码后生成的那个文件的名字"是什么意思,请指教,是product下目录的名字吗
Re: qinyun1882012-10-11 15:42发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复oucsunjie:嗯,好的,谢谢。
27楼 luxingshun2012-03-02 16:54发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
楼主。。为什么我按你的弄。打开设备时失败
16. if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
17. LOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);
18. return -EFAULT;
19. }
老是返回-1,,能告诉我是怎么回事不?2.3.3的系统
26楼 thrill0072012-02-13 14:40发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
尊敬的博主:
我编译的时候出现下面情况:
。。。
prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/../lib/gcc/arm-eabi/4.4.3/../../../../arm-eabi/bin/ld: out/target/product/tcc9300st/obj/lib/crtbegin_so.o:(.text+0x8): error: undefined reference to '__cxa_finalize'
collect2: ld returned 1 exit status
make: *** [out/target/product/tcc9300st/obj/SHARED_LIBRARIES/hello.default_intermediates/LINKED/hello.default.so] Error 1
make: Leaving directory `/home/lifeng/android-0812'

请指教,多谢!
Re: thrill0072012-02-13 14:47发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复thrill007:我怀疑问题出在Android.mk上,因为我把hello.cpp整个都注释掉了,还是出那个错误,期待BZ回答,谢谢!
25楼 flydream02011-12-19 15:53发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主,提个问题,HAL是怎么向上提供接口的呢?
是通过这个模块实例变量吗?
/*模块实例变量*/
struct hello_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: HELLO_HARDWARE_MODULE_ID,
name: MODULE_NAME,
author: MODULE_AUTHOR,
methods: &hello_module_methods,
}
};
其中有两个关键字:HAL_MODULE_INFO_SYM,HARDWARE_MODULE_TAG.
从上面可以看到一个方法列表:methods: &hello_module_methods,但是这个方法列表只定义了一个打开函数:
/*模块方法表*/
static struct hw_module_methods_t hello_module_methods = {
open: hello_device_open
};
接下来看这个打开函数:在函数hello_device_open内动态分配了一个(struct hello_device_t*)空间,也给其赋了值,打开,关闭,获取,设置四个函数都有,接下来在返回之前*device = &(dev->common);
可见返回前只给*device赋了值&(dev->common),而这个common只包含两个信息:
dev->common.module = (hw_module_t*)module;
dev->common.close = hello_device_close;
我的疑问是,从HAL上层来说,设置和获取的接口可见吗?从这里的代码如何设置的?
Re: flydream02011-12-19 18:31发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复flydream0:我找到答案了:下篇文章中有这么一行代码:
/*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/
static inline int hello_device_open(const hw_module_t* module, struct hello_device_t** device) {
return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
}
由此可见*device=&(dev->common)返回的是(struct hw_device_t*),然后又传给了(struct hello_device_t*)...,问题是何不支持返回*device =dev?

后来查看了一下hardware.h,得到以下原型:
typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);

} hw_module_methods_t;
原来Open函数的原型中,第三个参数的类型明确指出是: struct hw_device_t** device,而不能随便是我们定义的(struct hello_device_t**).
Re: 罗升阳2011-12-19 21:31发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复flydream0:是的。因为hello_device_t的第一个成员变量是common,它的类型为hw_device_t,所以可以把一个hello_device_t指针强制转换为hw_device_t指针。这种用法在linux内核中很普遍。
24楼 dinglbo2011-12-12 01:09发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
LZb你好。按你的这一系列教程,我做到后面发现最后卡在了这里。
Hello Stub: failed to open /dev/hello -- Permission denied.
我用的是2.2版本的。里面没有uevent.rc这个,但是在init下找到了device.c这个文件,于是我在文件中加了如下代码:
[cpp] view plaincopy
  1. static struct perms_ devperms[] = {  
  2.     { "/dev/null",          0666,   AID_ROOT,       AID_ROOT,       0 },  
  3. ……………………  
  4.     { "/dev/binder",        0666,   AID_ROOT,       AID_ROOT,       0 },  
  5.     { "/dev/hello",         0666,   AID_ROOT,       AID_ROOT,       0 }, /*这是我加的*/  
  6.   
  7.         /* logger should be world writable (for logging) but not readable */  
  8.     { "/dev/log/",          0662,   AID_ROOT,       AID_LOG,        1 },  

但编译过后还是会产生之前的错误!
我不知道怎么办了,求帮助~
Re: mutex_js2012-03-25 19:47发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复dinglbo:兄弟,你好,请问你这个问题解决了没有啊,我和你一样。
Re: 罗升阳2011-12-12 21:29发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复dinglbo:用adb连上模拟器,进入到/dev目录,用ls命令来检查一下/dev/hello文件的权限修改成功了没有。
23楼 ZFZF2949900512011-11-29 21:21发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
还要请问下楼主用的画图软件是什么?呵呵。有没有在ubuntu下好的画图软件推荐啊?谢谢
Re: 罗升阳2011-11-30 11:39发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:这些图都是在windows下画的,MagicDraw
22楼 cyq10282011-11-29 17:28发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
引用“ZFZF294990051”的评论:请问dev-&gt;common.close = hello_device_close; 这个cl...

同问!
Re: 罗升阳2011-11-29 17:42发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复cyq1028:已经回答了,可以参考一下:)
21楼 ZFZF2949900512011-11-28 22:25发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
请问dev->common.close = hello_device_close; 这个close函数在什么情况下会调用? 打开设备后如果没有出现错误,程序也没有显示的调用,难道是android系统自己调用吗?
Re: 罗升阳2011-11-29 17:41发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:要自己调的,包括open函数,也是要自己来调用的,系统不管这个,具体你可以参考一下后面一篇文章《在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口》。一般我们会在应用程序框架层维护这个硬件服务,而且系统只有一个唯一的实例,因此,一般open了之后,就不会close了。当然,你想close也是可以的,自己调用一下。
Re: insoonior2012-11-20 00:00发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:罗老师,open函数不是在被硬象抽象层加载时自动调用的吗?
Re: 罗升阳2012-11-20 00:30发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复insoonior:是的,这可以看看这个函数hello_device_open的实现,以及它是怎么被调用的。
20楼 ZFZF2949900512011-11-24 23:04发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
你好。我在2.3.4源码上编译居然出来个这么错误,真不知道哪里原因?
target thumb C: hello.default <= hardware/libhardware/modules/hello/hello.c
In file included from hardware/libhardware/modules/hello/hello.c:5:
bionic/libc/include/errno.h:45: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'extern'
make: *** [out/target/product/omap3evm/obj/SHARED_LIBRARIES/hello.default_intermediates/hello.o] 错误 1
Re: 罗升阳2011-11-26 16:46发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:试了一下把hello.c文件名改成hello.cpp看看
Re: ZFZF2949900512011-11-28 22:26发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:试了还是不行,同样错误。埃...
Re: 罗升阳2011-11-29 17:38发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:如果实在是解决不了,我建议还是不要include头文件errno.h吧,这个不是必须的,相应引用的地方改改就行了。如果你解决了这个问题,也欢迎你在这里分享一下:)
Re: ZFZF2949900512011-11-30 10:02发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:这个部分我找到错误了。原来是我在hello.h中的__END_DECLS写成了__EDN_DECLS. 我先include<hello.h> 所以不论在它下面再Include其他头文件,都会报错。原理我还以为是编译器的问题,以为是c语言的问题,原来最大问题还是我自己。太粗心了。希望别人不要犯同样的错误。这种问题太折磨人。
Re: 罗升阳2011-11-30 11:41发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:赞!写代码时还是要仔细一点~不然就会自己给自己挖坑~前面也有网码遇到类似的情况。
19楼 JayZhang2011-11-22 14:03发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
罗老师你好,我给你发了邮件,有问题请教你,希望你能帮助我~~~^0^
Re: 罗升阳2011-11-22 21:56发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复zhangjie201412:不知道哪个邮件是你发的......
18楼 floweriswho2011-11-17 23:40发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
java...好期待阿!
17楼 ccstuoshu12011-11-15 16:18发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主你好,我想写个USB驱动加到内核中,然后我只需要在应用程序中调用这个usb设备的读写操作,这个读写操作就是很一般的字符设备里面都有的read,write,现在的问题是我必须要重新在android框架下把你这个写hello的例子流程重新走一遍还是可以套用里面已经有的我只需要把这个设备名称加到某个位置就行了。因为是菜鸟所以问题可能没表达清楚,希望博主读懂了,谢谢。
Re: 罗升阳2011-11-15 22:56发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ccstuoshu1:确实是没看明白,呵呵。设备背后要有驱动程序支持才可以使用,和它的名称和位置其实没有关系。
16楼 ccstuoshu12011-11-15 16:05发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
android上的/dev下的设备文件权限 可以在init程序中控制,一般在
android/system/core/init/devices.c中有个变量:
static struct perms_ devperms[]={
...
{ "/dev/hello", 0666, AID_ROOT, AID_ROOT, 0 },
}
就好了,然后重新编译一遍就好了,我是重新编译的整个内核,用mmm单独编译好像不行,我不知道为什么
Re: 罗升阳2011-11-15 22:53发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ccstuoshu1:你可以看看执行mmm命令之后,得到的init文件是不是新的
15楼 ytllei2011-11-13 15:21发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主你好,有没有办法在在上层应用层调用自己增加的系统调用?
Re: 罗升阳2011-11-13 17:35发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ytllei:可以。如果你说的是内核的系统调用的话,首先就是按照在Linux内核增加系统调用接口的方法来增你的系统调用,接着在Android系统的运行时库层用C或者C++来封装一下这个系统调用,再接着在JNI层编写一个本地方法来封装运行时库层的函数,最后在frameworks层编写一个java接口来供application层调用,这个java接口通过调用前面的jni本地方法来实现系统调用。当然,你省略掉运行时库这一层的封装也是可以的,直接在jni层封装系统调用。
Re: ytllei2011-11-13 21:06发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:我的邮箱:ytllei@163.com
Re: ytllei2011-11-13 19:56发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:非常感谢!
请问博主有没有这方面的例子,或参考资料?
Re: 罗升阳2011-11-14 00:29发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ytllei:我手头上没有相应的例子。为Linux内核增加系统调用的例子,在网上很多,你自己找找看。内核增加了系统调用接口之后,再参照这一系列HAL的文章来在Android系统的frameworks层增加相应的java接口即可。
14楼 钢都百炼生2011-11-07 22:39发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
网上资料很多,但是这篇写得比较细,可以直接用来教学了.谢谢分享.
13楼 jxgtalent2011-10-26 15:15发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
我按照你的方法一步一步操作,怎么报告以下错误啊?网上也没找到满意的答复,求教了
CC drivers/video/goldfishfb.o
LD drivers/video/built-in.o
LD drivers/built-in.o
arm-eabi-ld: error: cannot open drivers/hello/built-in.o: No such file or directory
make[1]: *** [drivers/built-in.o] Error 1
make: *** [drivers] Error 2
Re: 罗升阳2011-10-26 21:23发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复jxgtalent:这个看起来不是HAL的代码
12楼 guidian1032011-09-28 18:07发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
问一下,
/*模块方法表*/
23.static struct hw_module_methods_t hello_module_methods = {
24. open: hello_device_open
25.};
这个有什么用?我不用可不可以?
还有,为什么一定是hw_module_methods_t 这个结构,不能用其他结构吗?
Re: 罗升阳2011-09-28 23:15发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复guidian103:这个问题就好比是问为什么C语言要用int来表示整数,为什么不能用其它的关键字来表示。
这是HAL的规范,换句话说,就是Google定的游戏规则,你要在这个平台上做东西,就必须遵守这个游戏规则,具体为什么,就要看一下HAL的实现了(libhardware/include/hardware/hardware.h和hardware/libhardware/hardware.c两个文件)。
Re: guidian1032011-10-16 13:56发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:明白,谢谢
11楼 xyzxyzxz2011-09-21 12:04发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主您好!仔细看了下这段代码,有两处疑问,由于是新手可能问题很基础,勿见笑,
1. LOGI("Hello Stub: set value %d to device.", val);是什么函数?
为什么不是printf("Hello Stub: set value %d to device.", val)?
2. write(dev->fd, &val, sizeof(val)); read(dev->fd, val, sizeof(*val));这两个函数为什么目标地址都是dev->fd,dev->fd不是设备号吗?这样就能写入设备的val了吗?
Re: 罗升阳2011-09-22 01:35发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复xyzxyzxz:1. Android在内核提供了日志系统的功能,LOGI就是用来敲日志的,具体可以参考一下《浅谈Android系统开发中LOG的使用》、《Android日志系统驱动程序Logger源代码分析》、《Android应用程序框架层和系统运行库层日志系统源代码分析》和《Android日志系统Logcat源代码简要分析》这一系列文件。printf是C运行时库提供的一个函数,一般它是输出到终端上的。两者不是同一样概念。
2. dev->fd不是设备号,是打开文件描述符,具体来说,就/dev/hello设备文件的打开文件描述符。这里的write和read是系统调用函数,是用来读写文件的,这两个函数先通过文件系统层,然后进入到我们的设备驱动模块去调用相应的读写函数,这个就涉及到Linux设备驱动的相关知识了,可以参考前面一篇文章《Android学习启动篇》一文提到的一本书《Linux Device Drivers》。
Re: xyzxyzxz2011-09-22 08:59发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:懂了,非常感谢您细致耐心的回答!
Re: xyzxyzxz2011-09-21 12:09发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复xyzxyzxz:还有个问题就是HAL层的hello_set_val和hello_get_val跟driver里的__hello_get_val和__hello_set_val有什么关系?
Re: 罗升阳2011-09-22 01:36发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复xyzxyzxz:这个问题同上面的回答2。
10楼 kevinacc2011-09-21 09:55发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
博主的教程很好啊。学习中。。。
这里应该是一个笔误:
解决办法是类似于Linux的udev规则,打开Android源代码工程目录下,进入到system/core/rootdir目录,里面有一个名为uevent.rc文件,往里面添加一行:

其中的uevent.rc应该是ueventd.rc。我验证过了。
Re: 罗升阳2011-09-22 01:26发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复kevinacc:是的,笔误了,呵呵,已经修正过来,多谢提醒~
9楼 ast5101832011-09-19 15:03发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
真的不错 谢谢分享!
8楼 wantianpei2011-09-07 23:49发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
楼主:
USER-NAME@MACHINE-NAME:~/Android$ mmm hardware/libhardware/moudles/hello

modules
应该改成:
USER-NAME@MACHINE-NAME:~/Android$ mmm hardware/libhardware/modules/hello
Re: 罗升阳2011-09-07 23:53发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复wantianpei:呵呵,又是一个笔误,多谢提醒~
7楼 atxtu2011-09-01 15:03发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
用mmm hardware/libhardware/moudles/hello单个编译模块成功,而make clean后重新make怎么在system/lib/hw中没有生成hello.default呢?怎么让这个新加的模块一起编译呢
Re: 罗升阳2011-09-01 23:13发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复atxtu:还真没试过make clean这种操作,呵呵,不过你可以看看再执行make的时候,hardware/libhardware/modules下的gralloc模块有没有编译出来,可以有编译出来的话,你再研究一下hardware/libhardware下面的Android.mk文件是怎么编写的
6楼 jhluroom2011-08-24 20:46发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
您好:我编译出现这样的提示是什么原因造成的?谢谢!!
make:进入目录'/home/jhlu/android/src'
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/hello.default_intermediates/hello.o”需要的目标“:”。 停止。
make:离开目录“/home/jhlu/android/src”
Re: 罗升阳2011-08-24 21:05发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复jhluroom:参考一下这两位哥们的碰到的问题:
-------------------------------
@bychen_19851208:
1.
LZ,怎么我编译
mmm hardware/libhardware/moudles/hello报错,
make:进入目录'/home/yzh/android2.3_lau'
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/hello.default_intermediates/hello.o”需要的目标“/hello.c”。 停止。
make:离开目录“/home/yzh/android2.3_lau”
我在hello目录下有hello.c 和Android.mk,怎么报需要目标“/hello.c”
2.
知道了
----------------------------------
@hui05504
1.
楼主,按照你上面的教程,出现了以下错误,
No rule to make target `out/target/product/generic/obj/lib/libhardware.so', needed by `out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so'. Stop.
,麻烦指导下,谢谢
2.
不好意思,这个错误的出错原因估计是在out/target/product/generic/这个目录下,因为我编译源码的时候不是在generic里生成的,而是在新建的目录底下生成,但是这个命令确默认是在generic的路径,所以出错了
-------------------------------------
5楼 bychen_198512082011-08-03 14:48发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
知道了
4楼 bychen_198512082011-08-03 14:44发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
LZ,怎么我编译
mmm hardware/libhardware/moudles/hello报错,
make:进入目录'/home/yzh/android2.3_lau'
make: *** 没有规则可以创建“out/target/product/generic/obj/SHARED_LIBRARIES/hello.default_intermediates/hello.o”需要的目标“/hello.c”。 停止。
make:离开目录“/home/yzh/android2.3_lau”
我在hello目录下有hello.c 和Android.mk,怎么报需要目标“/hello.c”
Re: kongji1232012-04-08 09:52发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复bychen_19851208:我这是同样的问题最后你怎么解决的呢?
3楼 hui055042011-07-31 14:13发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
解决办法是类似于Linux的udev规则,打开Android源代码工程目录下,进入到system/core/rootdir目录,里面有一个名为uevent.rc文件,往里面添加一行
楼主,system/core/rootdir目录下没有uevent.rc文件,只有init.rc这个文件,怎么添加root权限呢?
Re: qinyun1882012-04-11 15:51发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复hui05504:@hui05504
1.
楼主,按照你上面的教程,出现了以下错误,
No rule to make target `out/target/product/generic/obj/lib/libhardware.so', needed by `out/target/product/generic/obj/SHARED_LIBRARIES/libandroid_servers_intermediates/LINKED/libandroid_servers.so'. Stop.
,麻烦指导下,谢谢
2.
不好意思,这个错误的出错原因估计是在out/target/product/generic/这个目录下,因为我编译源码的时候不是在generic里生成的,而是在新建的目录底下生成,但是这个命令确默认是在generic的路径,所以出错了
-------------------------------------
我现在也出现了这个情况,那要怎么解决呢?
Re: hui055042011-07-31 17:29发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复hui05504:不好意思,楼主,那个不能联系评论三次,只有在这里说了。
首先谢谢楼主的回复,问题找到了,out/target/product/generic/system/lib/hw目录,是有hello.xxxxx.so文件。错误的原因是没有添加root的权限,按照你这篇文章所提到的解决方法:
(解决办法是类似于Linux的udev规则,打开Android源代码工程目录下,进入到system/core/rootdir目录,里面有一个名为uevent.rc文件,往里面添加一行)
但是在我的system/core/rootdir目录下没有uevent.rc文件,只有init.rc这个文件,怎么添加root权限呢?
Re: 罗升阳2011-07-31 18:44发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复hui05504:参考一个这个:
回复gunglaw:你下载的是最新版本的源代码么?旧一点的版本可能不是这种机制,你可以看一下system/core/init目录下,有没有ueventd.c这个文件,uevent.rc这个文件的内容是在ueventd_main这个函数里面进行解析的,如果没有,就要分析一下同目录下的init.c这个文件了,里面可以修改设备文件的访问模式。
Re: hui055042011-07-31 18:53发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:没有这个目录,我的代码是android 2.2的源码,:( 怎么分析呢,楼主,这个问题困惑我一天了,杯具!
Re: 罗升阳2011-07-31 19:15发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复hui05504:你在init.c文件里面,搜索一下,看看有没有找到"/dev/binder"这个字符串,如果能找到的话,它就是处理/dev/binder设备文件访问权限的地方,/dev/hello设备文件的处理方式和/dev/binder的是一样的,你参考一下加点代码就可以了。
Re: mutex_js2012-03-25 19:32发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:楼主,init.c文件引入了devices.h文件,我在devices.c文件中找到如下代码,添加了最后一句,但是还是不生效,求助啊。
static struct perms_ devperms[] = {
{ "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/full", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/ptmx", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/tty", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/random", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/urandom", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/ashmem", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/binder", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/hello", 0666, AID_ROOT, AID_ROOT, 0 },
Re: cofspring20122012-08-12 15:08发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复mutex_js:你好,我也是在devices.c里面加了{ "/dev/hello", 0666, AID_ROOT, AID_ROOT, 0 },这么一行,还是无效。。。请问你后来是怎么解决的呐?
Re: 罗升阳2012-08-12 15:16发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复cofspring2012:你用adb工具连上设备,用ls -l /dev/hello文件确认一下它的权限位。devices.c文件是包含在init模块中的,如果init是打包在ramdisk.img镜像中的,所以,你修改了devices.c文件,并且重新编译了init模块之后,还要确保新编译出来的init模块已经打包在ramdisk.img镜像里面。
Re: cofspring20122012-08-13 21:59发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:谢谢楼主热心回复哦,我之前是有重新编译init模块的,不过,ramdisk.img没有重新打包,刚才我重新打包了,进入out/..../root目录,使用这个命令find . | cpio -o -H newc | gzip > ../ramdisk-new.img进行重新打包,可是hello.apk还是写不了。。。。adb之后,是这样的
# ls -l /dev/hello
crw------- root root 252, 0 2012-08-13 13:49 hello
正确的权限显示应该是怎么样的?
我对底层很不熟,刚刚开始学习,非常感谢楼主的文章,也请楼主多多指导。
Re: 罗升阳2012-08-13 23:26发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复cofspring2012:这个权限没能设置好,只有root用户有读写权限。
Re: cofspring20122012-08-14 08:40发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复Luoshengyang:谢谢楼主这么及时回复哦,之前不知道为什么重新打包之后还是不对,刚才又重新检查了一边device.c,重新把{ "/dev/hello", 0666, AID_ROOT, AID_ROOT, 0 },这行改到了binder那行的下面,原本是放在最后一行的,不知道是不是这个原因,总之现在重新编译init并打包ramdisk以后,可以正确写上了,别的用户也有rw权限了。谢谢楼主啦
2楼 hui055042011-07-27 16:07发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
很好,谢谢分享
1楼 gunglaw2011-07-12 10:24发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
帅哥,我在system/core/rootdir目录里没有发现uevent.rc这个文件啊,自己创建一个? 需要在Android.mk文件中做什么修改呢?
Re: ZFZF2949900512011-11-30 16:29发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复gunglaw:请问你这个权限问题是怎么解决的?可以共享一下么?
Re: 罗升阳2011-12-01 10:15发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复ZFZF294990051:你的代码版本是多少?是不是没有uevent.rc这个文件?如果是这样的话,就要改一下system/core/init目录下的device.c文件了,我记得是这个文件。
Re: 罗升阳2011-07-16 16:08发表 [回复]
在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序 (学习老罗的)
回复gunglaw:你下载的是最新版本的源代码么?旧一点的版本可能不是这种机制,你可以看一下system/core/init目录下,有没有ueventd.c这个文件,uevent.rc这个文件的内容是在ueventd_main这个函数里面进行解析的,如果没有,就要分析一下同目录下的init.c这个文件了,里面可以修改设备文件的访问模式。