浅析android下propt怎么通过init进程传递和glibc库函数的添加
2010-03-09 15:26
453 查看
浅析android下propt怎么通过init进程传递和glibc库函数的添加 adb shell # printenv # getprop 获取所有java层propt # setprop wifi.interface eth0 设置"wifi.interface"对应的数值为eth0 环境变量ANDROID_PROPERTY_WORKSPACE=9,32768 所以fd=9,大小size=32768 system/init/init.c=>main()进程将调用 =>property_init =>init_property_area void property_init(void) { //ashmem_area - android shared memory area是android共享内容存的一种方式 //打开ashmem设备,申请一段size大小的kernel空间内存,不去释放,以便供所有用户空间进程共享. //内核驱动位于linux/mm/ashmem.c文件[luther.gliethttp]. init_property_area(); //#define PROP_PATH_RAMDISK_DEFAULT "/default.prop" //从ramdisk中读取default.prop文件,将文件中的所有java环境中使用到的propt释放到 //这个共享内存中. load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT); } 当然init程序在后边仍然可以调用property_set()来设置新的propt,比如:property_set("ro.hardware", hardware); ok,这个公用户空间程序共享的内核空间内存区域ashmem已经申请成功,并且填入了所有我们需要的数据,不论是从ramdisk解压出来的 default.prop文件直接读出的propt,还是手工调用property_set()设置的propt,都已经放入了内存中. 接下来init继续运行,注册环境变量ANDROID_PROPERTY_WORKSPACE: =>service_start => get_property_workspace(&fd, &sz); //从init进程的空闲fdt中dup一个空闲的fd,比如空闲的fd=9 //执行一次dup,那么打开init的引用计数就会加1,这样保证不被无故释放[luther.gliethttp]. sprintf(tmp, "%d,%d", dup(fd), sz);//比如ANDROID_PROPERTY_WORKSPACE=9,32768 add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);//添加环境变量 "ANDROID_PROPERTY_WORKSPACE" //其实是放到一个static const char *ENV[32];中,调用service_start()函数时ENV将作为参数传递给 //execve(svc->args[0], (char**) svc->args, (char**) ENV);传递给service系统服务进程. bionic/arch-arm/bionic/crtbegin_dynamic.S bionic/arch-arm/bionic/crtbegin_static.S _start: mov r0, sp mov r1, #0 adr r2, 0f adr r3, 1f b __libc_init //glibc库初始化 0: b main 1: .long __PREINIT_ARRAY__ .long __INIT_ARRAY__ .long __FINI_ARRAY__ .long __CTOR_LIST__ ... 使用adb pull init .从emulator模拟器导处init进程,进行如下反汇编: luther@gliethttp:~$ arm-linux-objdump -DS init |more init: file format elf32-littlearm Disassembly of section .text: 000080a0 <.text>: 80a0: e1a0000d mov r0, sp 80a4: e3a01000 mov r1, #0 ; 0x0 80a8: e28f2004 add r2, pc, #4 ; 0x4 80ac: e28f3004 add r3, pc, #4 ; 0x4 80b0: ea004ab3 b 0x1ab84 //可以看到这个就是b __libc_init 80b4: ea004ab5 b 0x1ab90 //可以看到这个就是b main 80b8: 0001f000 andeq pc, r1, r0 80bc: 0001f008 andeq pc, r1, r8 80c0: 0001f014 andeq pc, r1, r4, lsl r0 80c4: 0001f01c andeq pc, r1, ip, lsl r0 所以arm-linux-gcc就是按上面的方式对init进程进行link链接的[luther.gliethttp]. bionic/bionic/libc_init_dynamic.c bionic/bionic/libc_init_static.c =>__libc_init bionic/bionic/libc_init_common.c =>__libc_init_common =>__system_properties_init =>__system_property_area__ int __system_properties_init(void) { ... env = getenv("ANDROID_PROPERTY_WORKSPACE"); ... pa = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0); ... __system_property_area__ = pa; ... return 0; } 好了,经过上面glibc库的初始化之后,所有应用程序都可以通过编译到glibc库中自定义的property_get库函数 操作__system_property_area__了,比如:wpa_supplicant用户应用应用程序调用wifi_connect_to_supplicant() =>property_get("wifi.interface", iface, "sta");来获得ashmem中与"wifi.interface"匹配的propt[luther.gliethttp].
相关文章推荐
- [zz] 浅析android下propt怎么通过init进程传递和glibc库函数的添加
- 浅析android下propt怎么通过init进程传递和glibc库函数的添加
- Android TV 添加系统服务,通过Binder机制从APK对其进行跨进程远程调用
- Android 7.0 pendingIntent bug(AlarmManager通过PendingIntent传递数据(跨进程数据传递
- Android如何通过parcelable实现跨进程之间多态的类型的传递。
- 以Android L读取系统所有logcat并写入文件为例分析Android 以添加系统进程的方式申请selinux的权限执行shell脚本,以及avc:dined应该怎么申请权限
- Android中通过进程注入技术修改广播接收器的优先级
- android monitor tool (8.0 监控文件系统 添加哪个进程修改文件功能)
- Android中通过进程注入技术修改系统返回的Mac地址
- Android-->intent-filter 过滤规则的匹配 (Activity通过Uri传递参数)
- Android 通过程序添加桌面快捷方式
- android通过Handler在线程之间传递消息
- android开发——跨进程通讯数据传递(二)
- Android 开发笔记——通过 Intent 传递类对象
- 怎么看Android官网,怎么看Google官网?可以通过设置Hosts来解决
- Android底层启动过程(应该说是应用进程init启动后的一些步骤)
- 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制
- 通过execve在两个进程间传递环境变量
- 通过WM_COPY进行跨进程数据传递
- 分析Android 根文件系统启动过程(init守护进程分析)