[zz] 浅析android下propt怎么通过init进程传递和glibc库函数的添加
2009-10-22 16:48
453 查看
http://blog.chinaunix.net/u1/38994/showart_1170108.html
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链接的. 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.
相关文章推荐
- 浅析android下propt怎么通过init进程传递和glibc库函数的添加
- 浅析android下propt怎么通过init进程传递和glibc库函数的添加
- [zz] 分析Android 根文件系统启动过程(init守护进程分析)
- Android 7.0 pendingIntent bug(AlarmManager通过PendingIntent传递数据(跨进程数据传递
- Android TV 添加系统服务,通过Binder机制从APK对其进行跨进程远程调用
- 以Android L读取系统所有logcat并写入文件为例分析Android 以添加系统进程的方式申请selinux的权限执行shell脚本,以及avc:dined应该怎么申请权限
- Android如何通过parcelable实现跨进程之间多态的类型的传递。
- 分析Android+根文件系统启动过程(init守护进程分析)
- 关于android 7.0系统怎么添加自定义的系统服务
- 浅析android下如何通过jni监控wifi网络连接、dhcpcd执行和power电源控制
- Android 通过URL scheme 实现点击浏览器中的URL链接,启动特定的App,并调转页面传递参数
- 通过addDataScheme("file") 浅析android事件过滤策略
- C++ 遍历指定进程的线程列表,在 VS2015 测试通过,已添加中文注释。
- Android 开发笔记——通过 Intent 传递类对象
- 在Android手持设备与穿戴设备之间通过蓝牙传递assert(如图片)
- Android 通过 Intent 传递类对象
- Android的init进程
- Android init进程中的 charger mode 模式
- 分析Android 根文件系统启动过程(init守护进程分析)
- 通过 SysVinit、Systemd 和 Upstart 管理系统自启动进程和服务