In the previous article we analyzed the Android HAL layer of the main two structural body hw_module_t (Hardware module) and hw_device_t (Hardware Device) members, let us specifically see how the upper-level app is how to implement the operating hardware?
We know that some hardware vendors are reluctant to open up some of their core code, so put the code on the HAL layer, but how do you make sure it's not open? Hal layer code is not also let everyone know download? In fact, the hardware manufacturer's HAL core code is in the form of a shared library, each time when needed, HAL will automatically load the call to the relevant shared library. So how do you load a shared library for a particular hardware device? That's what we're going to say in this article.
The upper-level app acquires the hardware module through JNI calling the Hw_get_module function of the HAL layer, which is the upper layer's gateway to the HAL. So if we look at the source code using the procedure called execution, this function is the first function called by the HAL layer, and below we
Starting with this function, go down the process of executing the program.
hw_get_module function definition in/hardware/libhardware/hardware.c, open this file can see the definition 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/*
Ten * Here we rely on the fact that calling Dlopen multiple times on
* The same so would simply increment a refcount (and not load
A new copy of the library).
* We also assume that Dlopen () is Thread-safe.
14 */
15
*/* Loop through the configuration variants looking for a module */
+ for (i=0; i
if (I < Hal_variant_keys_count) {
if (Property_get (Variant_keys[i], prop, NULL) = = 0) {//Get property
Continue;
21}
snprintf (path, sizeof (path), "%s/%s.%s.so",
Hal_library_path1, ID, prop);
if (Access (path, r_ok) = = 0) break;//Check if the system path has a library file
25
snprintf (path, sizeof (path), "%s/%s.%s.so",
Hal_library_path2, ID, prop);
if (Access (path, r_ok) = = 0) break;//Check if the vender path has a library file
} else {
snprintf (path, sizeof (path), "%s/%s.default.so",//if none, use the default
Hal_library_path1, id);
if (Access (path, r_ok) = = 0) break;
33}
34}
35
* status =-enoent;
PNS if (i < hal_variant_keys_count+1) {
*/* Load the module, if this fails, we ' re doomed, and we should not try
* To load a different variant. */
The status = Load (id, path, module);//load library, get module
41}
42
return status;
44}
Look at the first line we know there are two parameters, the first parameter ID is the ID of the hardware module to get, and the second parameter module is a pointer to the structure of the hardware module we want.
So it can be seen that the upper layer first gives the hardware module that the HAL needs to obtain the Id,hw_get_module function according to this ID to find the matching and this ID corresponding to the hardware module structure.
Let's see how it looks.
17 line has a for loop, the upper limit is hal_variant_keys_count+1, then what is this hal_variant_keys_count? See the same file found below:
static const int Hal_variant_keys_count =
(sizeof (Variant_keys)/sizeof (variant_keys[0]));
It turns out that it is the number of elements Ariant_keys this array. So what is this array? In this document, there are:
/**
* There is 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 the it can pick up a different
File on the emulator. */
"Ro.product.board",
"Ro.board.platform",
"Ro.arch"
};
You can see that it is actually a string array. Station and do not know what to do. Continue to see the Hw_get_module function, into the for loop inside, look at 22 lines, in fact it is going to hal_library_path1, ID, prop this three string pieced together a path out,
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"
The ID is provided on the upper level, prop the value of this variable is obtained by the previous 19 lines Property_get (Variant_keys[i], prop, NULL) function, in fact, this function is to find the corresponding variant name in the system by the property of the Ariant_keys array. Different platforms get to the prop value is not the same.
If the obtained prop value is tout, the ID of the hardware module to be acquired is the LEDs, then the last path consists of a string of/system/lib/hw/leds.tout.so.
The next 24 lines of access are checked for the existence of this path, and if there is a break, jump out of the loop. If not, keep walking down,
You can see that the following lines are similar to the form just now,
snprintf (path, sizeof (path), "%s/%s.%s.so", Hal_library_path2, ID, prop);
if (Access (path, r_ok) = = 0) break;//Check if the vender path has a library file
Combining hal_library_path2 as "/VENDOR/LIB/HW", assuming that the same prop value is tout, the ID of the hardware module that needs to be acquired is the LEDs, in which case the path spelled out by the value is/vender/lib/hw/ Leds.tout.so, and then determines whether the file exists. If there is a bounce loop.
From the above analysis, actually this is the HAL Layer search dynamic Shared library way, from which we can get two points:
1. Dynamic shared libraries are generally placed under the two paths "/SYSTEM/LIB/HW" and "/VENDOR/LIB/HW".
2. The name of the dynamic library is named "Id.variant.so", where the ID is provided on the upper layer and the variant name in the middle variant is changed with the system platform.
Then, from 29 to 32 rows we can see whether the package name is found in "id.default.so" when all variants of the variant name form are not present.
37 Rows, if (I < hal_variant_keys_count+1), if I is less than the variant name array, indicates that the corresponding library is found, then 38 rows of load (ID, path, module);//load library, get module.
The above rules of the HAL Layer Search library are clear.
Next we'll go into the load function and see how the shared library is loaded.
Android hardware Abstraction layer (HAL) deep Anatomy (ii)