11 跟踪一个服务,直接找到驱动实现
如果说我自己学习整个系统,直到底层驱动的方法,我想说的就是我常用的就是跟踪震动这个模块,而为什么是这个,主要是简单,但是又是从上到下都具备,对于学习系统框架是最好的路径。
于是今天我们跟踪下这个代码,震动在 APP 中的使用方式。

 代码中这样使用:
 private Vibrator vibrator;
 vibrator=(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
 vibrator.vibrate(2000);
 我们跟踪 getSystemService 代码,找到对应服务

 这样子我们就要找初始化服务的地方,找下 SystemServiceRegistry 里面的静态代码块,可以看到有这段:

 然后我们看 SystemVibrator 文件实现,
 
 这个代码就是找到震动服务的代理,于是我们找下服务即可 VibratorService.java,这个就是我
 们调用的时候真正实现的地方。
 
 然后跟下去,找到往下走的代码:
 
 调用到这个,就知道走下去了,因为标记了 native,说明是个本地方法,我们去找下:
 我们通过检索找到代码:
 
 在这里面又想讲下,观察这个 cpp 文件,找到注册方法,然后搜索这个注册方法:
 会检索到这个/frameworks/base/services/core/jni/onload.cpp,这个是在虚拟机启动的时候,初
 始化的所有系统相关的 jni 对应表,这个可以多看看。
 要找它编译到哪里,从它目录往上找,找到一个 bp 或者 mk 即可。这里是

 我们找到具体的实现地方,一般而言文件名或者函数名是一致的,我们这里可以看到是
 hardware\libhardware\modules\vibrator 的 vibrator.c,我们打开看看这个代码:
 定义了挂载位置:
 static const char THE_DEVICE[] = “/sys/class/timed_output/vibrator/enable”;
最后我们就要找到真正驱动编写的地方,实际中能够通过这个路径,定位到驱动实现,这里
 我用老代码演示,手头没有驱动代码:
 static int __init vibrator_init(void)
 {
 return creat_vibrator_sysfs_file(); 这块会注册操作节/sys/class/timed_output/vibrator/enable";
 }
static void __exit vibrator_exit(void)
 {
 remove_vibrator_sysfs_file();
 }
 module_init(vibrator_init);
 module_exit(vibrator_exit);
 此处在 creat_vibrator_sysfs_file 则会去进行注册设备,将设备的处理函数和设备进行绑定,
 此时 open(THE_DEVICE, O_RDWR);
 nwr = sprintf(value, “%d\n”, timeout_ms);
 ret = write(fd, value, nwr);
 这样子处理是,write 函数会对应到此设备进行注册的写入函数,这时向文件设备写入不同
 的值,设备处理函数则会直接引起硬件操作,使得硬件真正跑起来。
 这里简单说下__init 这个编译配置属性,这个代表把后面的方法编译到这个段里面,系统启
 动后会找到这个段,这个段里面全部是驱动的初始化方法,可以直接遍历,执行系统的驱动
 初始化。
 这块定位的路线在 kernel 里面。https://www.bbsmax.com/A/qVdeaEY8dP/

 简单说下就是找到这个段里面的方法,依次执行,完成驱动的初始化,系统层是通过 HAL
 的统一接口去调用,然后这个 HAL 是 C 代码,然后使用注册 JNI 的方式提供给服务,然后服
 务对应有客户端,使用 Binder 进行跨进程调用,完成使用这个驱动的整个回路。


















