Ashmem初始化流程从ashmem.c的__ashmem_init方法开始,代码如下:
835 static int __init ashmem_init(void)
836 {
837 int ret;
838
839 ashmem_area_cachep = kmem_cache_create("ashmem_area_cache",
840 sizeof(struct ashmem_area),
841 0, 0, NULL);
842 if (unlikely(!ashmem_area_cachep)) {
843 pr_err("failed to create slab cache\n");
844 return -ENOMEM;
845 }
846
847 ashmem_range_cachep = kmem_cache_create("ashmem_range_cache",
848 sizeof(struct ashmem_range),
849 0, 0, NULL);
850 if (unlikely(!ashmem_range_cachep)) {
851 pr_err("failed to create slab cache\n");
852 return -ENOMEM;
853 }
854
855 ret = misc_register(&ashmem_misc);
856 if (unlikely(ret)) {
857 pr_err("failed to register misc device!\n");
858 return ret;
859 }
860
861 register_shrinker(&ashmem_shrinker);
862
863 pr_info("initialized\n");
864
865 return 0;
866 }
第839行和第847行使用函数kmem_cache_create创建了两个slab缓冲分配器,ashmem_area_cachep和ashmem_range_cachep,前者用来分配ashmem_area结构体,后者用来分配ashmem_range结构体,第855行注册设备类型为misc,ashmem_misc设备结构体定义为:
829 static struct miscdevice ashmem_misc = {
830 .minor = MISC_DYNAMIC_MINOR,
831 .name = "ashmem",
832 .fops = &ashmem_fops,
833 };
根据该结构体定义可知Ashmem对应的设备文件为:/dev/ashmem,该结构体定义了fops字段,具体内容为ashmem_fops如下:
816 static const struct file_operations ashmem_fops = {
817 .owner = THIS_MODULE,
818 .open = ashmem_open,
819 .release = ashmem_release,
820 .read = ashmem_read,
821 .llseek = ashmem_llseek,
822 .mmap = ashmem_mmap,
823 .unlocked_ioctl = ashmem_ioctl,
824 #ifdef CONFIG_COMPAT
825 .compat_ioctl = compat_ashmem_ioctl,
826 #endif
827 };
根据字段可以看出该结构体定义了对Ashmem的打开、释放、读取、映射、seek等操作。
继续看__ashmem_init函数的第861行,调用register_shrinker函数向内存管理系统注册了一个内存回收函数ashmem_shrinker,当系统内存不足的时候就会调用该函数释放内存。