android内存地址分配,AndroidION内存分配

android内存地址分配,AndroidION内存分配

2023年6月27日发(作者:)

android内存地址分配,AndroidION内存分配ION设计的⽬标为了避免内存碎⽚化,或者者为少量有着特殊内存需求的硬件,⽐⽅GPUs、display controller以及camera等,在系统启动的时候,会为他们预留少量memory pools,这些memory pools就由ION来管理。通过ION即可以在硬件以及user space之间实现zero-copy的内存share。ION的实现ION通过ION heaps来展现presents它对应的memory pools。不同的Android硬件可能会要求不同的ION heaps实现,默认的ION驱动会提供如下三种不同的ION heaps实现:ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc_user()ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kzalloc. ION_HEAP_TYPE_CARVEOUT: carveout memory is physically contiguous and set aside at boot.开发者可以⾃⼰实现更多的ION heaps。⽐⽅NVIDIA就提交了⼀种ION_HEAP_TYPE_IOMMU的heap,这种heap带有IOMMU功能。不论哪⼀种ION heaps实现,他们都必需实现如下接⼝:struct ion_heap_ops { int (*allocate) (struct ion_heap *heap, struction_buffer *buffer, unsigned long len, unsigned long align, unsigned long flags); void (*free) (struct ion_buffer *buffer); int(*phys) (struct ion_heap *heap, struct ion_buffer *buffer, ion_phys_addr_t *addr, size_t *len); struct scatterlist *(*map_dma)(struct ion_heap *heap, struct ion_buffer *buffer); void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer);void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); void (*unmap_kernel) (struct ion_heap *heap, struction_buffer *buffer); int (*map_user) (struct ion_heap *heap, struct ion_buffer *buffer, struct vm_area_struct *vma); };简单来说,接⼝的各个函数功能如下:allocate()和free()分别⽤来从heap中分配或者者释放⼀个ion_buffer对象对于物理连续的内存,phys()⽤来得到ion_buffer对象的物理内存地址及其⼤⼩。假如heap没有提供物理连续的内存,那么它也可以不⽤提供这个接⼝。其中,ion_phys_addr_t将来会被定义在/include/linux/types.h中的phys_addr_t替代。map_dma()和unmap_dma()分别来⽤使ion_buffer对象为DMA(Direct Memory Access,直接内存存取。顾名思义,不占⽤cpu资源,从⼀个硬件存储区域把⼀部分连续的数据复制到另⼀个硬件存储区域)做好准备或者者取消做好准备map_kernel()和unmap_kernel()分别⽤来把physical memory映射(map)到内核虚拟地址空间(kernel virtual address space)或者者取消映射map_user()⽤来把physical memory映射(map)到客户内存空间(user space)。为什么没有对应的unmap_user()呢?由于,这个映射⽤⼀个file descriptor来表⽰,当这个file descriptor关闭的时候,这个映射关系就⾃动取消了。在user space使⽤ION使⽤场景典型的,在客户空间使⽤的设施访问库(user space device access libraries)⼀般使⽤ION来分配⼤块连续的media buffers。⽐⽅,stillcamera library分配⼀个capture buffer来供camera device使⽤。当这个buffer填满video data的时候,这个library就能把这块buffer传递给kernel,⽽后让JPEG硬编码板块来解决。具体使⽤细节在user space 的C/C++程序能够能够分配ION内存之前,它必需取得访问/dev/ion的权限。通过调⽤open("/dev/ion", O_RDONLY)即可取得⼀个以handle形式返回的file descriptor,这个file descriptor⽤来代表⼀个ION client。注意,尽管传给open⼀个O_RDONLY参数,但是你依然可对这块memory进⾏写操作。在⼀个user process中最多有⼀个client。当有了⼀个client之后,即可以开始分配ION内存。为了分配内存,client必需填满下⾯的ion_allocation_data结构,handle除外,由于它是output参数。其余三个参数分别指明内存的⼤⼩、对齐⽅式以及flags。flags是⼀个bit mask,⽤来说明可以从哪些heaps中分配想要的内存。其决定顺序由系统启动时,通过ion_device_add_heap()增加的heap顺来决定。⽐⽅,ION_HEAP_TYPE_CARVEOUT是在ION_HEAP_TYPE_CONTIG之前被add的,那么假如flags = ION_HEAP_TYPE_CONTIG | ION_HEAP_TYPE_CARVEOUT,那么就是先尝试分配ION_HEAP_TYPE_CARVEOUT类型的heap,假如不⾏,再尝试分配ION_HEAP_TYPE_CONTIG类型的heap。()struct ion_allocation_data { size_t len; size_t align;unsigned int flags; struct ion_handle *handle; }user space通过ioctl()系统接⼝来与ION交互。在client填充ion_allocatoin_data结构之后,即可以通过调⽤int ioctl(int client_fd,ION_IOC_ALLOC, struct ion_allocation_data *allocation_data)来allocate a buffer。这个调⽤详情之后,分配的buffer会通过ion_allocatoin_data的handle来返回,但是CPU不可以访问这个buffer。这个handle只可以通过调⽤int ioctl(int client_fd,ION_IOC_SHARE, struct ion_fd_data *fd_data);来取得⼀个⽤来share的file descriptor。这⾥,client_fd参数是前⾯通过open取得的⼀个对应/dev/ion file descriptor,fd_data是如下的数据结构,其handle对应ion_allocation_data::handle,是input参数;fd则是output参数,可以⽤来share。当⼀个user process中的client分享(share)了这个fd之后,在其余user process中(当然,也可share给创⽴这个fd的client⾃⼰),为了取得这个shared buffer,先必需通过调⽤open("/dev/ion", O_RDONLY)取得⼀个client。(注:ION通过线程的PID来track各个client, 尤其是process中的"group leader"线程的PID。在相同的process中重复调⽤open("/dev/ion", O_RDONLY)只会取得指向kernel同⼀个client的another file descriptor)。取得client之后,⽽后再通过mmap()函数来把这个fd映射到address space of process(mmap函数参考1,参考2)。假如要释放这个fd对应的buffer,在调⽤mmap()的process中,先要通过munmap()来取消mmap()的效果。⽽后在之前share这个fd的client中,需要通过int ioctl(int client_fd, ION_IOC_FREE, struct ion_handle_data *handle_data);来关闭这个fd对应的file descriptor。其中,ion_handle_data表⽰前⾯通过ION_IOC_ALLOC命令取得的handle,其定义如下:struct ion_handle_data {struct ion_handle *handle; }这个ION_IOC_FREE命令会导致对应的handle的计数减1。当handle计数为0的时候,其指向的ion_handle对象就会被销毁,并且相关的ION bookkeeping数据结构也会升级。Demo在这个Demo中,fd在同⼀个client中被share使⽤:来源#include#include #include #include #include #include #include"/home/developer/kernel3.4/goldfish/include/linux/ion.h"void main(){ struct ion_fd_data fd_data; struct ion_allocation_dataionAllocData; =0x1000; = 0; = ION_HEAP_TYPE_SYSTEM; intfd=open("/dev/ion",O_RDWR); ioctl(fd,ION_IOC_ALLOC, &ionAllocData); fd_ = ;ioctl(fd,ION_IOC_SHARE,&fd_data); int *p = mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,fd_,0);p[0]=99; perror("test"); printf("hello all %dn",p[0]);}在kernel中share ION buffer在kernel中⽀持multiple clients,每⼀个使⽤ION功能的driver都可以在kernel中对应⼀个client。⼀个kernel driver通过调⽤struction_client *ion_client_create(struct ion_device *dev, unsigned int heap_mask, const char *debug_name)来取得⼀个ION clienthandle(注意,前⾯在user space中通过open("/dev/ion", O_RDONLY)返回的client是int类型)。dev参数是⼀个和/dev/ion相关的global ION device,heap_mask参数和之前提到的ion_allocation_data的flags成员⼀样的含义。当在user space中通过ION_IOC_SHARE命令得到⼀个buffer的file descriptor并把它传递给kernel之后,kernel driver通过调⽤struction_handle *ion_import_fd(struct ion_client *client, int fd_from_user);来把这个fd变成⼀个ion_handle对象,这个对象就是这个driver中对相应的buffer⼀个client-local reference。ion_import_fd⽅法会根据这个buffer的物理地址来查找:在本client中能否已经obtained⼀个对应此buffer的ion_handle,假如是的话,那么即可以简单的添加这个ion_handle的引⽤计数就可。有些硬件只能通过physical addresses来操作physically-contiguous buffers,那么,这些对应的drivers就需要通过调⽤intion_phys(struct ion_client *client, struct ion_handle *handle, ion_phys_addr_t *addr, size_t *len)来把ion_handle转变成⼀个physical buffer。当然,假如这个buffer不是physically contiguous,那么这个调⽤就会失败。当解决⼀个来⾃client的调⽤时,ION会validates 输⼊的 file descriptor, client and handle arguments。⽐⽅ION会确保 filedescriptor是由ION_IOC_SHARE命令创⽴的;⽐⽅当ion_phys()调⽤时,ION会检测这个buffer能否在这个client对应有访问权限list中,假如不是,那么就会返回错误。这样的验证机制能够减少可能的unwanted accesses以及疏忽的内存泄露。ION通过debugfs提供可视化的debug,它通过在/sys/kernel/debug/ion下⾯,使⽤stored files来记录相应的heaps和clients,并使⽤symbolic names或者者PIDs来标志。⽐较ION和DMABUFION和DMABUF都是通过传递⼀个匿名file descriptor对象,给其余client⼀个基于引⽤计数的访问权限,从⽽达到分享内存的⽬的。ION通过⼀个可分享和追踪的⽅式从预留的memory pool中分配内存。DMABUF更多的专注于buffer导⼊、导出以及同步的⽅式来实现在NON-ARM架构上的buffer的分享。ION⽬前只⽀持Android kernelION所有的user-space program都可以通过/dev/ion接⼝来分配ION内存。但是在Android会通过验证user和group IDs的⽅式来阻⽌对ION的⾮受权访问。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687842240a50008.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信