当前位置: 首页 > news >正文

预约网站制作设计图室内效果图

预约网站制作,设计图室内效果图,江西建网站,上海网站制作官网Android12 共享内存驱动实现 SOC#xff1a;RK3568 system#xff1a;Android12 概述#xff1a; 1. 概述 Ashmem#xff08;Anonymous Shared Memory#xff0c;Android 匿名共享内存#xff09;#xff0c;它基于 mmap 系统调用#xff0c;可以让不同进程将同一段…Android12 共享内存驱动实现 SOCRK3568 systemAndroid12 概述 1. 概述 AshmemAnonymous Shared MemoryAndroid 匿名共享内存它基于 mmap 系统调用可以让不同进程将同一段物理内存映射到各自的虚拟地址中从而实现内存共享。 它以驱动程序的形式在内核空间中实现并通过文件描述符来传递共享内存的句柄。 工作上要使用Ashmem但是对于C来讲使用不方便因为涉及到fd文件描述符传递 。于是想参考google 的Ashmem,设计一个简单的进程只通过操作文件即可获取共享的驱动 逻辑原理如下 主要代码 //结构体MyAshmem_area 用来描述一块匿名共享内存struct MyAshmem_area {char name[MYASHMEM_FULL_NAME_LEN];//匿名struct list_head unpinned_list;//暂时无用//每一块匿名共享内存都会在临时文件系统tmpfs中对应一个文件也就是filestruct file *file;size_t size;//文件的大小 sizeunsigned long prot_mask;//    prot_mask是访问保护位 };struct MyAshmem_area *asma; 开机启动Myshmem驱动 static int __init MyAshmem_init(void) {int ret -ENOMEM;//创建一个使用slap缓存 用于分配 MyAshmem_area 的分配器MyAshmem_area_cachep kmem_cache_create(ashmem_area_cache,sizeof(struct MyAshmem_area),0, 0, NULL);if (!MyAshmem_area_cachep) {pr_err(failed to create slab cache\n);goto out;}//注册匿名共享内存设备ret misc_register(MyAshmem_misc);if (ret) {pr_err(failed to register misc device!\n);goto out_free1;}pr_info(initialized\n);return 0;out_free1:kmem_cache_destroy(MyAshmem_area_cachep); out:return ret; } 注册时调用 device_initcall(MyAshmem_init); 匿名内存设备是一个misc设备类型,所以它使用一个miscdevice类型的结构体结构体MyAshmem_misc进行注册定义如下 static struct miscdevice MyAshmem_misc {.minor MISC_DYNAMIC_MINOR,.name MyAshmem,.fops MyAshmem_fops, }; 文件操作/dev/MyAshmemMyAshmem_fops 表示其操作方法列表。 static const struct file_operations MyAshmem_fops {.owner THIS_MODULE,.open MyAshmem_open,//当应用open时调用.release MyAshmem_release,.mmap MyAshmem_mmap,当应用mmap 时调用 }; open具体实现方法 static int MyAshmem_open(struct inode *inode, struct file *file) {int ret;//当open计数器大于1时返回if(op 0){printk(already MyAshmem_open);return 0;}printk(MyAshmem_open);asma kmem_cache_zalloc(MyAshmem_area_cachep, GFP_KERNEL);if (!asma)return -ENOMEM;//初始化链表 暂时没完善INIT_LIST_HEAD(asma-unpinned_list);memcpy(asma-name, MYASHMEM_NAME_PREFIX, MYASHMEM_NAME_PREFIX_LEN);//设置默认匿名strcpy(asma-name MYASHMEM_NAME_PREFIX_LEN, MyAshmemDrive);//设置默认长度asma-size 4096;//设置默认保护位置asma-prot_mask PROT_MASK;//open计数器加一op;return 0; } mmap实现 static int MyAshmem_mmap(struct file *file, struct vm_area_struct *vma) {static struct file_operations vmfile_fops;int ret 0;mutex_lock(MyAshmem_mutex);printk(MyAshmem_mmap);/* user needs to SET_SIZE before mapping */if (!asma-size) {ret -EINVAL;goto out;}/* requested mapping size larger than object size *///比较size 设置大小否则直接失败if (vma-vm_end - vma-vm_start PAGE_ALIGN(asma-size)) {ret -EINVAL;goto out;}/* requested protection bits must match our allowed protection mask *///检测需要映射的虚拟内存vma的保护权限是否超过了匿名共享内存的保护权限//比如vma除了允许读之外还允许写但是asma只允许读这就算超过了会mmap失败直接返回。if ((vma-vm_flags ~calc_vm_prot_bits(asma-prot_mask, 0)) calc_vm_prot_bits(PROT_MASK, 0)) {ret -EPERM;goto out;}vma-vm_flags ~calc_vm_may_flags(~asma-prot_mask);//第一次mmap会创造一个临时文件用来映射共享内存//第二次打开直接从这个映射文件上mmapif (!asma-file) {char *name MYASHMEM_NAME_DEF;struct file *vmfile;struct inode *inode;if (asma-name[MYASHMEM_NAME_PREFIX_LEN] ! \0)name asma-name;/* ... and allocate the backing shmem file *///在tmpfs中创建一个临时文件。vmfile shmem_file_setup(name, asma-size, vma-vm_flags);if (IS_ERR(vmfile)) {ret PTR_ERR(vmfile);goto out;}vmfile-f_mode | FMODE_LSEEK;inode file_inode(vmfile);lockdep_set_class(inode-i_rwsem, backing_shmem_inode_class);//记录临时文件asma-file vmfile;/** override mmap operation of the vmfile so that it cant be* remapped which would lead to creation of a new vma with no* asma permission checks. Have to override get_unmapped_area* as well to prevent VM_BUG_ON check for f_ops modification.*/if (!vmfile_fops.mmap) {vmfile_fops *vmfile-f_op;vmfile_fops.mmap MyAshmem_vmfile_mmap;vmfile_fops.get_unmapped_area MyAshmem_vmfile_get_unmapped_area;}vmfile-f_op vmfile_fops;}get_file(asma-file);/** XXX - Reworked to use shmem_zero_setup() instead of* shmem_set_file while were in staging. -jstultz*///判断映射虚拟内存vma是否需要在不同进程间共享if (vma-vm_flags VM_SHARED) {ret shmem_zero_setup(vma);if (ret) {fput(asma-file);goto out;}} else {vma_set_anonymous(vma);}if (vma-vm_file)fput(vma-vm_file);vma-vm_file asma-file;out:mutex_unlock(MyAshmem_mutex);//返回地址return ret; } 全部代码drivers\staging\android\MyAshmem.c #include linux/init.h #include linux/export.h #include linux/file.h #include linux/fs.h #include linux/falloc.h #include linux/miscdevice.h #include linux/security.h #include linux/mm.h #include linux/mman.h #include linux/uaccess.h #include linux/personality.h #include linux/bitops.h #include linux/mutex.h #include linux/shmem_fs.h#define PROT_MASK (PROT_EXEC | PROT_READ | PROT_WRITE)#define MYASHMEM_NAME_LEN 256 #define MYASHMEM_NAME_PREFIX dev/MyAshmem/ #define MYASHMEM_NAME_PREFIX_LEN (sizeof(MYASHMEM_NAME_PREFIX) - 1) #define MYASHMEM_FULL_NAME_LEN (MYASHMEM_NAME_LEN MYASHMEM_NAME_PREFIX_LEN) #define MYASHMEM_NAME_DEF /dev/MyAshmem static int op 0; struct MyAshmem_area {char name[MYASHMEM_FULL_NAME_LEN];struct list_head unpinned_list;struct file *file;size_t size;unsigned long prot_mask; }; struct MyAshmem_area *asma;static DEFINE_MUTEX(MyAshmem_mutex); static struct kmem_cache *MyAshmem_area_cachep __read_mostly;static int MyAshmem_open(struct inode *inode, struct file *file) {int ret;//当open计数器大于1时返回if(op 0){printk(already MyAshmem_open);return 0;}printk(MyAshmem_open);asma kmem_cache_zalloc(MyAshmem_area_cachep, GFP_KERNEL);if (!asma)return -ENOMEM;//初始化链表 暂时没完善INIT_LIST_HEAD(asma-unpinned_list);memcpy(asma-name, MYASHMEM_NAME_PREFIX, MYASHMEM_NAME_PREFIX_LEN);//设置默认匿名strcpy(asma-name MYASHMEM_NAME_PREFIX_LEN, MyAshmemDrive);//设置默认长度asma-size 4096;//设置默认保护位置asma-prot_mask PROT_MASK;//open计数器加一op;return 0; }static int MyAshmem_release(struct inode *ignored, struct file *file) {if (asma-file)fput(asma-file);kmem_cache_free(MyAshmem_area_cachep, asma);op--;return 0; } static int MyAshmem_vmfile_mmap(struct file *file, struct vm_area_struct *vma) {/* do not allow to mmap ashmem backing shmem file directly */return -EPERM; }static unsigned long MyAshmem_vmfile_get_unmapped_area(struct file *file, unsigned long addr,unsigned long len, unsigned long pgoff,unsigned long flags) {return current-mm-get_unmapped_area(file, addr, len, pgoff, flags); }static inline vm_flags_t calc_vm_may_flags(unsigned long prot) {return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD) |_calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) |_calc_vm_trans(prot, PROT_EXEC, VM_MAYEXEC); }static struct lock_class_key backing_shmem_inode_class; static int MyAshmem_mmap(struct file *file, struct vm_area_struct *vma) {static struct file_operations vmfile_fops;int ret 0;mutex_lock(MyAshmem_mutex);printk(MyAshmem_mmap);/* user needs to SET_SIZE before mapping */if (!asma-size) {ret -EINVAL;goto out;}/* requested mapping size larger than object size *///比较size 设置大小否则直接失败if (vma-vm_end - vma-vm_start PAGE_ALIGN(asma-size)) {ret -EINVAL;goto out;}/* requested protection bits must match our allowed protection mask *///检测需要映射的虚拟内存vma的保护权限是否超过了匿名共享内存的保护权限//比如vma除了允许读之外还允许写但是asma只允许读这就算超过了会mmap失败直接返回。if ((vma-vm_flags ~calc_vm_prot_bits(asma-prot_mask, 0)) calc_vm_prot_bits(PROT_MASK, 0)) {ret -EPERM;goto out;}vma-vm_flags ~calc_vm_may_flags(~asma-prot_mask);//第一次mmap会创造一个临时文件用来映射共享内存//第二次打开直接从这个映射文件上mmapif (!asma-file) {char *name MYASHMEM_NAME_DEF;struct file *vmfile;struct inode *inode;if (asma-name[MYASHMEM_NAME_PREFIX_LEN] ! \0)name asma-name;/* ... and allocate the backing shmem file *///在tmpfs中创建一个临时文件。vmfile shmem_file_setup(name, asma-size, vma-vm_flags);if (IS_ERR(vmfile)) {ret PTR_ERR(vmfile);goto out;}vmfile-f_mode | FMODE_LSEEK;inode file_inode(vmfile);lockdep_set_class(inode-i_rwsem, backing_shmem_inode_class);//记录临时文件asma-file vmfile;/** override mmap operation of the vmfile so that it cant be* remapped which would lead to creation of a new vma with no* asma permission checks. Have to override get_unmapped_area* as well to prevent VM_BUG_ON check for f_ops modification.*/if (!vmfile_fops.mmap) {vmfile_fops *vmfile-f_op;vmfile_fops.mmap MyAshmem_vmfile_mmap;vmfile_fops.get_unmapped_area MyAshmem_vmfile_get_unmapped_area;}vmfile-f_op vmfile_fops;}get_file(asma-file);/** XXX - Reworked to use shmem_zero_setup() instead of* shmem_set_file while were in staging. -jstultz*///判断映射虚拟内存vma是否需要在不同进程间共享if (vma-vm_flags VM_SHARED) {ret shmem_zero_setup(vma);if (ret) {fput(asma-file);goto out;}} else {vma_set_anonymous(vma);}if (vma-vm_file)fput(vma-vm_file);vma-vm_file asma-file;out:mutex_unlock(MyAshmem_mutex);//返回地址return ret; }static const struct file_operations MyAshmem_fops {.owner THIS_MODULE,.open MyAshmem_open,.release MyAshmem_release,.mmap MyAshmem_mmap, };static struct miscdevice MyAshmem_misc {.minor MISC_DYNAMIC_MINOR,.name MyAshmem,.fops MyAshmem_fops, };static int __init MyAshmem_init(void) {int ret -ENOMEM;//创建一个使用slap缓存 用于分配 MyAshmem_area 的分配器MyAshmem_area_cachep kmem_cache_create(ashmem_area_cache,sizeof(struct MyAshmem_area),0, 0, NULL);if (!MyAshmem_area_cachep) {pr_err(failed to create slab cache\n);goto out;}//注册匿名共享内存设备ret misc_register(MyAshmem_misc);if (ret) {pr_err(failed to register misc device!\n);goto out_free1;}pr_info(initialized\n);return 0;out_free1:kmem_cache_destroy(MyAshmem_area_cachep); out:return ret; } device_initcall(MyAshmem_init); drivers/staging/android/Makefile  ccflags-y -I$(src) # needed for trace eventsobj-y ion/ obj-$(CONFIG_FIQ_DEBUGGER) fiq_debugger/obj-$(CONFIG_ASHMEM) ashmem.o obj-$(CONFIG_ANDROID_VSOC) vsoc.o obj-y MyAshmem.o 进程write #include stdio.h #include stdlib.h #includesys/types.h #includesys/stat.h #includefcntl.h #includesys/mman.h #includeunistd.h #define ASHMEM_DEVICE /dev/MyAshmem int main(void){int fd open(ASHMEM_DEVICE, O_RDWR);char *addr (char*)mmap(NULL, 4096 , PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);int i 0;while(1){*addr i;printf(write:%d\n,*addr);sleep(1);}return 0; } 进程read: #include stdio.h #include stdlib.h #includesys/types.h #includesys/stat.h #includefcntl.h #includesys/mman.h #includeunistd.h #define ASHMEM_DEVICE /dev/MyAshmem int main(void){int fd2 open(ASHMEM_DEVICE, O_RDWR);char *addr2 (char*)mmap(NULL, 4096 , PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0);int i 0;while(1){printf(read:%d\n,*addr2);sleep(1);}return 0; } 编译/mnt/h/android-ndk-r21e/android-ndk-r21e/install/bin/aarch64-linux-android-g write.cpp -o write.out /mnt/h/android-ndk-r21e/android-ndk-r21e/install/bin/aarch64-linux-android-g read.cpp  -o read.out 结果 BUG1.目前只能使用一次得重新开机才能使用 2.不支持多组只支持一组应用使用  下一章节改进觉得有用喜欢的话就给个点赞收藏
http://www.eeditor.cn/news/120562/

相关文章:

  • 建设民政局网站需要多少钱企业为什么要做网络营销推广
  • 网站建设 部署与发布题库工业和信息化部网站备案管理系统
  • 网站备案中心wordpress 下载插件xydown
  • 高校档案网站建设的目的是什么意思杭州网站推广找哪家
  • 德清县建设银行官方网站美食类网站模板
  • apmserv 设置网站目录查询网站域名
  • php建站网站用自己的电脑做服务器吗
  • 企业网站建设的基本内容工信部网站备案查询验证码错误
  • 网站下载软件建设网站的功能地位
  • 南通的电商网站建设文字创意logo设计
  • 炫酷的动画网站网站优化防范
  • 网站源码是什么意思进入公众号看不到内容
  • 网站关键词怎么布局上海网络推广营销策划方案
  • 电子印章在线制作网站小程序开发需要什么
  • 酒店网站模板网站扁平化布局
  • 铭万做网站怎么样亚马逊图书官网
  • 化妆品网站模板深圳市出行政策最新
  • 网站开发设计哪家好钢板防护罩做网站
  • 怎样分析一个网站做的好坏什么网站做广告效果好
  • 企业网站建设管理系统常州手机网站开发
  • 图片网站模版管理咨询师考试
  • 旅游景区网站开发的政策可行性怎样切图做网站
  • 单页面网站现在个人网站名称备案
  • 房屋设计公司网站国际网站怎么样做
  • 洛阳青峰做网站wordpress自适应空白主题
  • 邢台做网站推广的公司互联网产品营销策划方案
  • 装修公司网站php源码写wordpress插件吗
  • 做个网页需要多少钱?官方网站优化方法
  • 电商网站建设求职定位搜狗推广找谁
  • 专业做美食视频的网站怎样设计网站首页