Linux内核 scatterlist介绍
生活随笔
收集整理的這篇文章主要介紹了
Linux内核 scatterlist介绍
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
scatterlist
- 物理內存的散列表。通俗講,就是把一些分散的物理內存,以列表的形式組織起來
誕生背景
- 假設有三個模塊可以訪問memory:CPU、DMA控制器和某個外設。
- CPU通過MMU以虛擬地址(VA)的形式訪問memory;
- DMA直接以物理地址(PA)的形式訪問memory;
- Device通過自己的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是內存塊數組的size,nents是有效的內存塊個數(可能會小于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 documentation
- Linux Kernel Crypto API — The Linux Kernel 4.7 documentation
- 內核解壓縮 · Linux Inside 中文版
- Linux內核加密模塊crypto的使用 | 楊磊的博客
總結
以上是生活随笔為你收集整理的Linux内核 scatterlist介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 国债2022年发行时间利率,买不到国债的
- 下一篇: linux 其他常用命令