Additional hardware abstraction layer Android (HAL) to the Linux kernel driver module (3) on Ubuntu

      In the Android hardware abstraction layer (HAL) and an overview of the study plan in one article, we briefly describe the method of preparation of the driver in the Android system hardware. Simply put, hardware drivers on the one hand in the distribution of the Linux kernel, on the other hand distributed in user space hardware abstraction layer. Next, on Ubuntu Linux kernel driver for the preparation of the Android system a sub exemplified herein illustrate how to write drivers in the Linux kernel. In this article, we will continue to introduce Android system hardware drivers on the other hand to achieve, namely how to increase hardware modules and kernel drivers interact with the hardware abstraction layer. In this article, we'll learn how you can modify the file mode device with a Linux-like udev rules in the Android system to create a device file.

"Android system source code Scenario Analysis," a book under attack programmer network ( http://0xcc0xcd.com in) serial, click to enter!

      A reference to the preparation of the Android system on Ubuntu Linux kernel driver shown in a paper, ready exemplary kernel driver sequence. Upon completion of this kernel driver, you can get in the Android system three documents, namely / dev / hello, / sys / class / hello / hello / val and / proc / hello. In this article, we will connect the hardware abstraction layer module and a Linux kernel driver module device file / dev / hello.

      Second into the hardware / libhardware / include / hardware directory, create hello.h file:

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

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

      Hello.h contents of the file are as follows:

      


   
   
  1. #ifndef ANDROID_HELLO_INTERFACE_H
  2. #define ANDROID_HELLO_INTERFACE_H
  3. #include <hardware/hardware.h>
  4. __BEGIN_DECLS
  5. / * Definition module ID * /
  6. #define HELLO_HARDWARE_MODULE_ID "hello"
  7. / * Hardware module structure * /
  8. struct hello_module_t {
  9. struct hw_module_t common;
  10. };
  11. / * Hardware interface structure * /
  12. struct hello_device_t {
  13. struct hw_device_t common;
  14. int fd;
  15. int (*set_val)(struct hello_device_t* dev, int val);
  16. int (*get_val)(struct hello_device_t* dev, int* val);
  17. };
  18. __END_DECLS
  19. #endif

      Here Android hardware abstraction layer according to the requirements specification, the module ID, module structure, and a hardware interface structures are defined. In the structure of the hardware interface, a file descriptor FD indicates the device, the device file corresponding to us to be treated "/ dev / hello", set_val and get_val for function interfaces of the HAL provided.

      III. Into the hardware / libhardware / modules directory, create hello directory, and add hello.c file. hello.c more content, we look at the segment.

      The first is the header file that contains the relevant definitions and related structures:

      


   
   
  1. #define LOG_TAG "HelloStub"
  2. #include <hardware/hardware.h>
  3. #include <hardware/hello.h>
  4. #include <fcntl.h>
  5. #include <errno.h>
  6. #include <cutils/log.h>
  7. #include <cutils/atomic.h>
  8. #define DEVICE_NAME "/dev/hello"
  9. #define MODULE_NAME "Hello"
  10. #define MODULE_AUTHOR "[email protected]"
  11. / * Device to open and close the interface * /
  12. static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
  13. static int hello_device_close(struct hw_device_t* device);
  14. / * Device Access Interfaces * /
  15. static int hello_set_val(struct hello_device_t* dev, int val);
  16. static int hello_get_val(struct hello_device_t* dev, int* val);
  17. / * Methods table module * /
  18. static struct hw_module_methods_t hello_module_methods = {
  19. open: hello_device_open
  20. };
  21. / * Module instance variables * /
  22. struct hello_module_t HAL_MODULE_INFO_SYM = {
  23. common: {
  24. tag: HARDWARE_MODULE_TAG,
  25. version_major: 1,
  26. version_minor: 0,
  27. id: HELLO_HARDWARE_MODULE_ID,
  28. name: MODULE_NAME,
  29. author: MODULE_AUTHOR,
  30. methods: &hello_module_methods,
  31. }
  32. };

      Here, the instance variable name must be HAL_MODULE_INFO_SYM, tag must also be HARDWARE_MODULE_TAG, this is the Android hardware abstraction layer specification.

      Hello_device_open defined function:

      


   
   
  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. if(!dev) {
  4. LOGE( "Hello Stub: failed to alloc space");
  5. return -EFAULT;
  6. }
  7. memset(dev, 0, sizeof(struct hello_device_t));
  8. dev->common.tag = HARDWARE_DEVICE_TAG;
  9. dev->common.version = 0;
  10. dev->common. module = ( hw_module_t*) module;
  11. dev->common.close = hello_device_close;
  12. dev->set_val = hello_set_val;dev->get_val = hello_get_val;
  13. if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
  14. LOGE( "Hello Stub: failed to open /dev/hello -- %s.", strerror(errno)); free(dev);
  15. return -EFAULT;
  16. }
  17. *device = &(dev->common);
  18. LOGI( "Hello Stub: open /dev/hello successfully.");
  19. return 0;
  20. }

      DEVICE_NAME is defined as "/ dev / hello". Since the device driver in the kernel file is created inside by device_create, but the device file device_create created by default only the root user can read and write, and hello_device_open usually invoked by the upper APP, APP these generally do not have root privileges, this time led open the device file failed:

      Hello Stub: failed to open /dev/hello -- Permission denied.
      The solution is similar to the Linux udev rules, under the Android open source project directory, enter the system / core / rootdir directory with a file named ueventd.rc, entered, add the line:
       /dev/hello 0666 root root
      Defined hello_device_close, hello_set_val and hello_get_val three functions:
      

    
    
  1. static int hello_device_close(struct hw_device_t* device) {
  2. struct hello_device_t* hello_device = (struct hello_device_t*)device;
  3. if(hello_device) {
  4. close(hello_device->fd);
  5. free(hello_device);
  6. }
  7. return 0;
  8. }
  9. static int hello_set_val(struct hello_device_t* dev, int val) {
  10. LOGI( "Hello Stub: set value %d to device.", val);
  11. write(dev->fd, &val, sizeof(val));
  12. return 0 ;
  13. }
  14. static int hello_get_val(struct hello_device_t* dev, int* val) {
  15. if(!val) {
  16. LOGE( "Hello Stub: error val pointer");
  17. return -EFAULT;
  18. }
  19. read(dev->fd, val, sizeof(*val));
  20. LOGI( "Hello Stub: get value %d from device", *val);
  21. return 0;
  22. }

      Four new Android.mk continue to file in the directory hello:
       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)
      Note, LOCAL_MODULE-defined rules, hello followed by default, hello.default can guarantee that our modules can always be loaded into hard like abstraction layer.
      Five compile:
       USER-NAME@MACHINE-NAME:~/Android$ mmm hardware/libhardware/modules/hello
       After successful compilation, you can see hello.default.so files in the out / target / product / generic / system / lib / hw directory.
      Six repackage Android system image system.img:
       USER-NAME@MACHINE-NAME:~/Android$ make snod
       After re-packaged, system.img contains hardware abstraction layer module hello.default we define the.
      While we in the Android system adds a hardware abstraction layer module for our own hardware, but now Java applications can not access to our hardware. We also have to write JNI method and increase the API interface in the Android Application Frameworks layer, to make the top Application visit our hardware. In the next article, we will complete this process system, it allows us to access our own custom hardware in Java applications.

Guess you like

Origin blog.csdn.net/ll148305879/article/details/93030418