用墨刀做网站首页,如何做好阿里巴巴企业网站建设,网店美工的技能要求,网站设计与建设考试scatterlist
物理内存的散列表。通俗讲#xff0c;就是把一些分散的物理内存#xff0c;以列表的形式组织起来
诞生背景
假设有三个模块可以访问memory#xff1a;CPU、DMA控制器和某个外设。CPU通过MMU以虚拟地址#xff08;VA#xff09;的形式访问memory#xff1b;…scatterlist
物理内存的散列表。通俗讲就是把一些分散的物理内存以列表的形式组织起来
诞生背景
假设有三个模块可以访问memoryCPU、DMA控制器和某个外设。CPU通过MMU以虚拟地址VA的形式访问memoryDMA直接以物理地址PA的形式访问memoryDevice通过自己的IOMMU以设备地址DA的形式访问memory。然后某个“软件实体”分配并使用了一片存储空间。该存储空间在CPU视角上虚拟空间是连续的起始地址是va1实际上它映射到了3块不连续的物理内存上我们以pa1,pa2,pa3表示。那么如果该软件单纯的以CPU视角访问这块空间操作va1则完全没有问题因为MMU实现了连续VA到非连续PA的映射。不过如果软件经过一系列操作后要把该存储空间交给DMA控制器最终由DMA控制器将其中的数据搬移给某个外设的时候由于DMA控制器只能访问物理地址只能以“不连续的物理内存块”为单位递交而不是我们所熟悉的虚拟地址。此时scatterlist就诞生了为了方便我们需要使用一个数据结构来描述这一个个“不连续的物理内存块”起始地址、长度等信息这个数据结构就是scatterlist。而多个scatterlist组合在一起形成一个表可以是一个struct scatterlist类型的数组也可以是kernel帮忙抽象出来的struct sg_table就可以完整的描述这个虚拟地址了。最后从本质上说scatterlist数组是各种不同地址映射空间PA、VA、DA、等等的媒介因为物理地址是真实的、实在的存在因而可以作为通用语言借助它这些映射空间才能相互转换例如从VA转到DA
介绍
struct scatterlist struct scatterlist用于描述一个在物理地址上连续的内存块以page为单位它的定义位于“include/linux/scatterlist.h”中如下 page_link指示该内存块所在的页面。bit0和bit1有特殊用途可参考后面的介绍因此要求page最低4字节对齐。offset指示该内存块在页面中的偏移起始位置。length该内存块的长度。dma_address该内存块实际的起始地址PA相比page更接近我们人类的语言。dma_length相应的长度信息。struct sg_table
多个scatterlist组成一个数组以表示在物理上不连续的虚拟地址空间。通常情况下使用scatterlist功能的模块会自行维护这个数组指针和长度例如[2]中所提到的struct mmc_data不过呢为了使用者可以偷懒kernel抽象出来了一个简单的数据结构struct sg_table帮忙保存scatterlist的数组指针和长度 其中sgl是内存块数组的首地址orig_nents是内存块数组的sizenents是有效的内存块个数可能会小于orig_nents。scatterlist数组中到底有多少有效内存块呢这不是一个很直观的事情主要有如下2个规则决定 1如果scatterlist数组中某个scatterlist的page_link的bit0为1表示该scatterlist不是一个有效的内存块而是一个chain铰链指向另一个scatterlist数组。通过这种机制可以将不同的scatterlist数组链在一起因为scatterlist也称作chain scatterlist。2如果scatterlist数组中某个scatterlist的page_link的bit1为1表示该scatterlist是scatterlist数组中最后一个有效内存块后面的就忽略不计了。table中sgl数组大小最大为PAGE_SIZE如果nents个数超过了SG_MAX_SINGLE_ALLOC那么就需要使用到chain了。具体实现可以查看sg_alloc_table - __sg_alloc_table使用提供的API函数就可以访问所有的sg了例如for_each_sg()
参考链接
Linux内核scatterlist API介绍 - AlanTu - 博客园Linux内存管理 - 随笔分类(第2页) - AlanTu - 博客园聊聊scatterlist的chain结构Welcome to The Linux Kernel’s documentation! — The Linux Kernel 4.7 documentationLinux Kernel Crypto API — The Linux Kernel 4.7 documentation内核解压缩 · Linux Inside 中文版Linux内核加密模块crypto的使用 | 杨磊的博客