最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

30分鐘搞懂Linux內(nèi)核內(nèi)存映射,(值得大神們收藏)

2022-03-08 20:39 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

一、內(nèi)存映射基礎(chǔ)知識(shí)

1、內(nèi)核地址映射模型

  • 比如:X86CPU采用段頁式地址映射模型,進(jìn)程代碼地址為邏輯地址,經(jīng)過段頁式地址映射之后,才能夠真正訪問物理內(nèi)存。32位Linux內(nèi)核地址空間劃分:0GB--3GB為用戶空間,3GB--4GB為內(nèi)核空間。32位和64位內(nèi)核地址空間劃分是不同的。具體空間表示如下:

2、內(nèi)核高端內(nèi)存

  • 比如:當(dāng)內(nèi)核模塊代碼或絡(luò)訪問內(nèi)存時(shí),代碼中的地址為邏輯地址,而且對(duì)應(yīng)到真正的物理內(nèi)存地址,需要地址和它一對(duì)一的映射,假設(shè):邏輯地址0xc0000003對(duì)應(yīng)的物理地址為0x3。內(nèi)核邏輯地址空間訪問為0xc0000000--0xFFFFFFFF,那么對(duì)應(yīng)的物理內(nèi)存范圍為0x0--0x40000000。即只能訪問1GB物理內(nèi)存。假設(shè)我們的電腦8GB物理內(nèi)存,那么內(nèi)核就只能訪問前面1GB物理內(nèi)存,剩下7GB物理內(nèi)存它無法訪問,因?yàn)閮?nèi)核的地址空間已經(jīng)全部映射到物理內(nèi)存地址范圍0x--0x40000000。

  • Linux將內(nèi)核地址空間劃分為三部分:

  • ZONE_DMA/ZONE_NORMAL/ZONE_HIGHMEM。高端內(nèi)存HIGH_MEM地址空間范圍為0xF8000000--0xFFFFFFFF(896MB-1024MB)。針對(duì)高端內(nèi)存的最基本思想:借一段地址空間,建立臨時(shí)地址映射,用完后釋放,達(dá)到此段地址空間可以循環(huán)使用,訪問所有物理內(nèi)存。

3、內(nèi)存映射

  • 內(nèi)存映射是在進(jìn)程的虛擬地址空間中創(chuàng)建一個(gè)映射,可分為兩種:

A、文件映射(文件支持的內(nèi)存映射,把文件的一個(gè)區(qū)間映射到進(jìn)程的虛擬地址空間,數(shù)據(jù)源是存儲(chǔ)設(shè)備上文件);?

B、匿名映射(沒有文件支持的內(nèi)存映射,把物理內(nèi)存映射到進(jìn)程的虛擬地址空間,沒有數(shù)據(jù)源)。通常把文件映射的物理頁稱為文件頁,把匿名映射的物理頁稱為匿名頁。

4、根據(jù)修改是否對(duì)其他進(jìn)程可見和是否傳遞到底層文件,內(nèi)存映射分為共享映射和私有映射。

A、共享映射:修改數(shù)據(jù)時(shí)映射相同區(qū)域的其他進(jìn)程可以看見,如果是文件支持的映射,修改會(huì)傳遞到底層文件。?

B、私有映射:第一次修改數(shù)據(jù)時(shí)會(huì)從數(shù)據(jù)源復(fù)制一個(gè)副本,然后修改副本,其他進(jìn)程看不見,不影響我們的數(shù)據(jù)源。

  • 兩個(gè)進(jìn)程可以使用共享的文件映射實(shí)現(xiàn)共享內(nèi)存。匿名映射通常為私有映射,共享的匿名映射只可能出現(xiàn)在父進(jìn)程和子進(jìn)程之間。在進(jìn)程的虛擬地址空間中,代碼段和數(shù)據(jù)段是私有的文件映射,未初始化數(shù)據(jù)段、堆棧是私有的匿名映射。

5、內(nèi)存映射原理機(jī)制:

  1. 創(chuàng)建內(nèi)存映射的時(shí),在進(jìn)程的用戶虛擬地址空間中分配一個(gè)虛擬內(nèi)存區(qū)域(vm_area_struct);

  2. Linux內(nèi)核采用延遲分配物理內(nèi)存的策略,在進(jìn)程第一次訪問虛擬頁的時(shí)候,產(chǎn)生缺頁異常,如果是文件映射,那么分配物理頁,把文件指定區(qū)間的數(shù)據(jù)讀到物理頁中,然后在頁表中把虛擬頁映射到物理頁;如果你是匿名映射,那么分配物理頁,然后在頁表中把虛擬頁映射到物理頁。

二、應(yīng)用層API系統(tǒng)調(diào)用

  • Linux內(nèi)核當(dāng)中內(nèi)存管理子系統(tǒng)提供給我們用戶層的系統(tǒng)調(diào)用API函數(shù),具體如下:

1、用來創(chuàng)建內(nèi)存映射

2、用來刪除內(nèi)存映射

3、專用用來擴(kuò)大或縮小已經(jīng)存在的內(nèi)存映射,可能同時(shí)移動(dòng)

4、用來設(shè)置堆的上界

5、用來創(chuàng)建非線性的文件映射,即文件區(qū)域和虛擬地址空間之間的映射不是線性關(guān)系,現(xiàn)在已不用

6、用來設(shè)置虛擬內(nèi)存區(qū)域的訪問權(quán)限

在Linux空間中可以使用如下函數(shù):

1、把內(nèi)存的物理頁映射到進(jìn)程的虛擬地址空間,這個(gè)函數(shù)用處是:實(shí)現(xiàn)進(jìn)程和內(nèi)核共享內(nèi)存。

  • int remap_pfn_range (struct vm_area_struct *vma,unsigned long addr,unsigned long pfn,unsigned long size,pgprot_t prot);

2、把外設(shè)寄存器的物理地址映射到進(jìn)程的虛擬地址空間,進(jìn)程可能直接訪問外設(shè)寄存器。

  • int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr,unsigned long phys_addr, unsigned long size,pgprot_t prot);

  • 應(yīng)用層當(dāng)中應(yīng)用程序通過使用C標(biāo)準(zhǔn)庫提供的函數(shù)malloc()申請(qǐng)內(nèi)存。glibc庫的內(nèi)存分配器ptmalloc使用brk或mmap向內(nèi)核以頁為單位申請(qǐng)?zhí)摂M內(nèi)存,然后把頁劃分成小內(nèi)存塊分配給應(yīng)用程序。默認(rèn)的閾值為128KB,如果應(yīng)用程序申請(qǐng)的內(nèi)存長(zhǎng)度小于閾值,ptmalloc分配器使用brk向內(nèi)核申請(qǐng)?zhí)摂M內(nèi)存,否則ptmalloc分配器使用mmap內(nèi)內(nèi)核申請(qǐng)?zhí)摂M內(nèi)存。應(yīng)用程序可以直接使用mmap向內(nèi)核申請(qǐng)?zhí)摂M內(nèi)存。

三、Linux內(nèi)核常用數(shù)據(jù)結(jié)構(gòu)

1、進(jìn)程描述符

2、內(nèi)存描述符

3、虛擬內(nèi)存區(qū)域

4、mmap系統(tǒng)調(diào)用

a.進(jìn)程創(chuàng)建匿名的內(nèi)存映射,把內(nèi)存的物理頁映射到進(jìn)程的虛擬地址空間;?

b.進(jìn)程把文件映射到進(jìn)程的虛擬地址空間,可以像訪問內(nèi)存一樣訪問文件,不需要調(diào)用系統(tǒng)調(diào)用read()/write()訪問文件,從面避免用戶模式和內(nèi)核模式之間的切換,提高讀寫文件的速度。?

c.兩個(gè)進(jìn)程針對(duì)同一個(gè)文件創(chuàng)建共享的內(nèi)存映射,實(shí)現(xiàn)共享會(huì)敗在。

  • 函數(shù)原型:

  • 參數(shù)如下:

  • addr:起始虛擬地址,如果addr為0,內(nèi)核選擇虛擬地址。如果addr為非0,內(nèi)核把這個(gè)參數(shù)作為提示,在附近選擇虛擬地址。

  • length:映射的長(zhǎng)度,單位是字節(jié)。

  • prot:保護(hù)位,具體參數(shù)如下:

  • PROT_EXEC:頁可執(zhí)行 PROT_READ:頁可讀 PROT_WRITE:頁可寫 PROT_NONE:面不可訪問

  • lags:標(biāo)志,具體參數(shù)如下:

  • MAP_SHARED:共享映射

  • MAP_PRIVATE:私有映射

  • MAP_ANONYMOUS:匿名映射

  • MAP_FIXED:固定映射

  • MAP_HUGETLB:使用巨型頁

  • MAP_LOCKED:把頁鎖在內(nèi)存中

  • fd:文件描述符

  • offset:偏移,單位是字節(jié),必須是頁長(zhǎng)度的整數(shù)倍。

  • 返回值:

  • 返回起始虛擬地址,否則返回負(fù)的錯(cuò)誤號(hào)。

    四、創(chuàng)建/刪除內(nèi)存映射

    1、創(chuàng)建內(nèi)存映射

  • C標(biāo)準(zhǔn)庫封裝函數(shù)mmap()用來創(chuàng)建內(nèi)存映射,內(nèi)核提花POSIX標(biāo)準(zhǔn)定義的系統(tǒng)調(diào)用mmap,內(nèi)核系統(tǒng)調(diào)用sys_mmap(),具體操作流程如下:


  • 函數(shù)sys_mmap_pgoff執(zhí)行流程視圖如下:

  • a.如果是創(chuàng)建文件映射,根據(jù)文件描述符在進(jìn)程的打開文件表中找到file實(shí)例;

  • b.如果是創(chuàng)建匿名巨型頁映射,在hugetlbfs文件系統(tǒng)中創(chuàng)建文件“anon_hugepage",并且創(chuàng)建此文件 的一個(gè)打開實(shí)例file;

  • c.調(diào)用vm_mmap_pgoff進(jìn)行處理。


30分鐘搞懂Linux內(nèi)核內(nèi)存映射,(值得大神們收藏)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
固原市| 鸡泽县| 定安县| 肇东市| 东莞市| 镇宁| 彭州市| 滦平县| 碌曲县| 麻江县| 封丘县| 铁力市| 临潭县| 郑州市| 高碑店市| 广饶县| 邢台市| 丰县| 平邑县| 彰化市| 新化县| 辽源市| 沾益县| 通化市| 朝阳县| 安仁县| 台北市| 利辛县| 平武县| 阆中市| 确山县| 缙云县| 江华| 天津市| 锦州市| 苍山县| 习水县| 清流县| 诸暨市| 东乡县| 驻马店市|