深入剖析Android中init进程实现的C语言源码

2020-01-06 13:38:30丽君

代码比较好理解,主要内容是利用mmap映射property_filename创建了一个共享内存区域,并将共享内存的首地址赋值给全局变量__system_property_area__。

关于mmap映射文件实现共享内存IPC通信机制,可以参考这篇文章:mmap实现IPC通信机制

init_workspace

接下来,我们来看一下init_workspace函数的源码(/system/core/init/property_service.c):

 

 
  1. typedef struct {  void *data; 
  2. size_t size;  int fd; 
  3. }workspace;   
  4. static int init_workspace(workspace *w, size_t size)  { 
  5. void *data;  int fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW); 
  6. if (fd < 0)  return -1; 
  7.   w->size = size; 
  8. w->fd = fd;  return 0; 

客户端进程访问属性内存区域

虽然属性内存区域是init进程创建的,但是Android系统希望其他进程也能够读取这块内存区域里的内容。为了做到这一点,init进程在属性区域初始化过程中做了如下两项工作:

把属性内存区域创建在共享内存上,而共享内存是可以跨进程的。这一点,在上述代码中是通过mmap映射/dev/__properties__文件实现的。pa_workspace变量中的fd成员也保存了映射文件的句柄。

如何让其他进程知道这个共享内存句柄呢?Android先将文件映射句柄赋值给__system_property_area__变量,这个变量属于bionic_lic库中的输出的一个变量,然后利用了gcc的constructor属性,这个属性指明了一个__lib_prenit函数,当bionic_lic库被加载时,将自动调用__libc_prenit,这个函数内部完成共享内存到本地进程的映射工作。