Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动
在这篇Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划中,我们简要介绍了Android系统的匿名共享内存机制,其中,简要提到了它具有辅助内存管理系统来有效地管理内存的特点,但是没有进一步去了解它是如何实现的。在本文中,我们将通过分析Android系统的匿名共享内存Ashmem驱动程序的源代码,来深入了解它是如何辅助内存管理系
Android系统的匿名共享内存Ashmem机制并没有自立山头,从头搞一套自己的共享内存机制,而是建立在Linux内核实现的共享内存的基础上的。与此同时,它又向Linux内存管理系统的内存回收算法注册接口,告诉Linux内存管理系统它的某些内存块不再使用了,可以被回收了,不过,这些不再使用的内存需要由它的使用者来告诉Ashmem驱动程序。通过这种用户-Ashmem驱动程序-内存管理系统三者的紧密合作,实现有效的内存管理机制,适合移动设备小内存的特点。
Android系统的匿名共享内存Ashmem驱动程序利用了Linux的共享内存子系统导出的接口来实现自己的功能,因此,它的实现非常小巧,总共代码不到700行。虽然代码很少,但是这里不打算机械式地一行一行地阅读和分析Ashmem驱动程序的源代码,而是通过使用情景来分析,这样可以帮助我们清晰地理解它的实现原理。我们这里所说的使用情景,将从Android系统的应用程序框架层提供的匿名共享内存接口开始,经过系统运行时库层,最终到达驱动程序层,通过这样一个完整的过程来理解Android系统的匿名共享内存Ashmem机制。这里,我们将从这篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划介绍的Android应用程序框架层提供MemoryFile接口开始,分别介绍Android系统匿名共享内存的创建(open)、映射(mmap)、读写(read/write)以及锁定和解锁(pin/unpin)四个使用情景。
在进入到这个四个使用情景前,我们先来看一下Ashmem驱动程序模块的初始化函数,看看它给用户空间暴露了什么接口,即它创建了什么样的设备文件,以及提供了什么函数来操作这个设备文件。Ashmem驱动程序实现在kernel/common/mm/ashmem.c文件中,它的模块初始化函数定义为ashmem_init:
- static struct file_operations ashmem_fops = {
- .owner = THIS_MODULE,
- .open = ashmem_open,
- .release = ashmem_release,
- .mmap = ashmem_mmap,
- .unlocked_ioctl = ashmem_ioctl,
- .compat_ioctl = ashmem_ioctl,
- };
- static struct miscdevice ashmem_misc = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "ashmem",
- .fops = &ashmem_fops,
- };
- static int __init ashmem_init(void)
- {
- int ret;
- ......
- ret = misc_register(&ashmem_misc);
- if (unlikely(ret)) {
- printk(KERN_ERR "ashmem: failed to register misc device!\n");
- return ret;
- }
- ......
- return 0;
- }