Android HAL layer frame analysis (II)

Previous analysis of the key members of our hw_module_t (hardware module) and hw_device_t (hardware) of the two android HAL layer structure, let's look at the specific top app in the end is how to achieve operational hardware?

We know that some hardware manufacturers do not want to open some of their own core code out, so these codes into the HAL layer, but how to ensure that it does not open it? HAL layer code is not also let everyone know to download it? In fact, the hardware manufacturer HAL core code is in the form of a shared library, each time when needed, hal will automatically load the relevant call shared libraries. So it is how to find a hardware load corresponding shared libraries it? This is why we have to say this.

App upper acquisition hardware module function call hw_get_module JNI layer by hal, hal this function is dealing with the upper inlet. So if we execute the process to look at the source code of the program calls, then this function is the first function is called hal layer, here we come

From the beginning of this function, process execution of the program to go along.

hw_get_module function is defined in /hardware/libhardware/hardware.c, open the file you can see is defined as follows:

 1 int hw_get_module(const char *id, const struct hw_module_t **module) 
 2 {
 3     int status;
 4     int i;
 5     const struct hw_module_t *hmi = NULL;
 6     char prop[PATH_MAX];
 7     char path[PATH_MAX];
 8 
 9     /*
10      * Here we rely on the fact that calling dlopen multiple times on
11      * the same .so will simply increment a refcount (and not load
12      * a new copy of the library).
13      * We also assume that dlopen() is thread-safe.
14      */
15 
16     /* Loop through the configuration variants looking for a module */
17     for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
18         if (i < HAL_VARIANT_KEYS_COUNT) {
19             if (property_get(variant_keys[i], prop, NULL) == 0) {//获取属性
20                 continue;
21             }
22             snprintf(path, sizeof(path), "%s/%s.%s.so",
23                     HAL_LIBRARY_PATH1, id, prop);
24             if (access(path, R_OK) == 0) break;//检查system路径是否有库文件
25 
26             snprintf(path, sizeof(path), "%s/%s.%s.so",
27                      HAL_LIBRARY_PATH2, id, prop);
28             if (access(path, R_OK) == 0) break;//检查vender路径是否有库文件
29         } else {
30             snprintf(path, sizeof(path), "%s/%s.default.so",//如果都没有,则使用缺省的
31                      HAL_LIBRARY_PATH1, id);
32             if (access(path, R_OK) == 0) break;
33         }
34     }
35 
36     status = -ENOENT;
37     if (i < HAL_VARIANT_KEYS_COUNT+1) {
38         /* load the module, if this fails, we're doomed, and we should not try
39          * to load a different variant. */
40         status = load(id, path, module);//装载库,得到module
41     }
42 
43     return status;
44 }

 

 Look at the first line we know that there are two parameters, the first parameter is the id id to get a hardware module, the second module parameter is a pointer we want the hardware module structure.

It can be seen, id hal upper layer needs to be acquired to the first hardware module, hw_get_module function to find matching the id and the corresponding hardware module structure according to this id.

Let's look at how to find.

There are 17 lines for loop, the upper limit is HAL_VARIANT_KEYS_COUNT + 1, then this HAL_VARIANT_KEYS_COUNT What is it? Found under view the same file are:

static const int HAL_VARIANT_KEYS_COUNT =  (sizeof(variant_keys)/sizeof(variant_keys[0]));

It is the original number of elements in the array of ariant_keys. So this array, what is it? In this document looking for, we are:

/**
 * There are a set of variant filename for modules. The form of the filename
 * is "<MODULE_ID>.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"
};

We can see that it is actually a string array. The station does not know what to do. Hw_get_module functions continue to look into the for loop, see line 22, in fact, it is HAL_LIBRARY_PATH1, id, prop three strings put together out of a path,

HAL_LIBRARY_PATH1 is defined as follows:

/** Base path of the hal modules */
#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

id is an upper provided, prop value of this variable is the front line 19 property_get (variant_keys [i], prop, NULL) function to get to, in fact, this function is a property by ariant_keys array lookup to the variant name system corresponds. Different platforms to get value prop is not the same.

If the acquired value is prop tout, id hardware module that needs to be acquired leds, then the last path is the string consisting /system/lib/hw/leds.tout.so.

24 behind the line access is to check whether the presence of this path, if it BREAK, out of the loop. If not, continue to go below,

Here you can see just a few lines and similar forms,

snprintf(path, sizeof(path), "%s/%s.%s.so",  HAL_LIBRARY_PATH2, id, prop);

if (access(path, R_OK) == 0) break;//检查vender路径是否有库文件

HAL_LIBRARY_PATH2 of binding "/ vendor / lib / hw", assuming the same value is acquired prop tout, id needs to be acquired is a hardware module leds, in this case the value is out of the path spell / vender / lib / hw / leds .tout.so, and then determine whether the file exists. If there is out of the loop.

From the above analysis, in fact, this is the way search hal layer dynamic shared libraries, from which we can get two things:

1. The dynamic shared libraries typically placed in the "/ system / lib / hw" and "/ vendor / lib / hw" two paths.

2. The name of the dynamic library in the form of "id.variant.so" named, where id provided for the upper, middle name variant to variant, is included with the platform change.

Then, from 29-32 lines we can see that when all the variants of the name does not exist in the form of packets, with regard to "id.default.so" form of the package name lookup exists.

Line 37, if (i <HAL_VARIANT_KEYS_COUNT + 1), if i is less than var name of the array, then, that found a corresponding library, then line 38 load (id, path, module); // load library, obtained module.


Hal layer above it to rule the search base figure out.
 

Next we will enter the load function to see how the shared library is loaded.

Published 407 original articles · won praise 150 · views 380 000 +

Guess you like

Origin blog.csdn.net/ds1130071727/article/details/104908801