色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內存映射的原理

嵌入式開發AIoT ? 來源:嵌入式開發AIoT ? 2023-01-15 09:55 ? 次閱讀

一、物理地址空間

  1. 物理地址是處理器在系統總線上看到的地址。使用RISC的處理器通常只實現一個物理地址空間,外圍設備和物理內存使用統一的物理地址空間。有些處理器架構把分配給外圍設備的物理地址區域稱為設備內存。
  2. 處理器通過外圍設備控制器寄存器訪問外圍設備,寄存器分為控制器,狀態寄存器和數據寄存器三大類。外圍設備的寄存器通常被連續地編址,處理器對外圍設備寄存編址方式分為:i/o映射方式(i/o-mapped),內存映射方式(memory-mapped)。
  3. 應用程序只能通過虛擬地址訪問外設寄存器,內核提供API函數來把外設寄存器的物理地址映射到虛擬地址空間。
  4. ARM64(物理地址寬度最大支持48位)架構分為兩種內存類型:
  • 正常內存(Noramal Memory):包括物理內存和只讀存儲器(ROM);
  • 設備內存(Device Memory):指分配給外圍設備寄存器的物理地址區域;
  • 設備內存共享屬性總是外部共享,緩存屬性總是不可緩存(必須繞過處理器的緩存)
  • 二、內存映射原理

內存映射即在進程的虛擬地址空間中創建一個映射,分為兩種:

  1. 文件映射:文件支持的內存映射,把文件的一個區間映射到進程的虛擬地址空間,數據源是存儲設備上的文件。
  2. 匿名映射:沒有文件支持的內存映射,把物理內存映射到進程的虛擬地址空間,沒有數據源。

【原理】:創建內存映射時,在進程的用戶虛擬地址空間中分配一個虛擬內存區域。內核采用延遲分配物理內存的策略,在進程第一次訪問虛擬頁的時候,產生缺頁異常。==如果是文件映射,那么分配物理頁,把文件指定區間的數據讀到物理頁中,然后在頁表中把虛擬頁映射到物理頁。如果是匿名映射,就分配物理頁,然后在頁表中把虛擬頁映射到物理頁。==(1)兩個進程可以使用共享的文件映射實現共享內存。匿名映射通常是私有映射,共享的匿名映射只可能出現父進程和子進程之間。在進程的虛擬地址空間中,代碼段和數據段是私有的文件映射,未初始化數據段、堆棧是私有的匿名映射。(2)修改過的臟頁面不會立即更新到文件中,可以調用msync來強制同步寫入文件。

flowchartLR
task_struct-->mm_struct-->vm_area_struct

三、虛擬內存源碼分析

3.1 相關數據結構

structvm_area_struct{
/*ThefirstcachelinehastheinfoforVMAtreewalking.*/

//這兩個成員分別用來保存該虛擬內存空間的首地址和末地址后第一個字節的地址
unsignedlongvm_start;/*Ourstartaddresswithinvm_mm.*/
unsignedlongvm_end;/*Thefirstbyteafterourendaddresswithinvm_mm.*/

/*linkedlistofVMareaspertask,sortedbyaddress*/
structvm_area_struct*vm_next,*vm_prev;

//如果采用鏈表組織化,會影響它搜索速度問題,解決此問題采用紅黑樹(每個進程結構體mm_struct中都
//創建一顆紅黑樹,將VMA作為一個節點加入紅黑樹給中,這樣可以提升搜索速度)
structrb_nodevm_rb;

/*
*LargestfreememorygapinbytestotheleftofthisVMA.
*EitherbetweenthisVMAandvma->vm_prev,orbetweenoneofthe
*VMAsbelowusintheVMArbtreeandits->vm_prev.Thishelps
*get_unmapped_areafindafreeareaoftherightsize.
*/
unsignedlongrb_subtree_gap;

/*Secondcachelinestartshere.*/

structmm_struct*vm_mm;/*Theaddressspacewebelongto.*/
pgprot_tvm_page_prot;/*AccesspermissionsofthisVMA.*/
unsignedlongvm_flags;/*Flags,seemm.h.*/

/*
*Forareaswithanaddressspaceandbackingstore,
*linkageintotheaddress_space->i_mmapintervaltree.
*/
struct{
structrb_noderb;
unsignedlongrb_subtree_last;
}shared;

/*
*Afile'sMAP_PRIVATEvmacanbeinbothi_mmaptreeandanon_vma
*list,afteraCOWofoneofthefilepages.AMAP_SHAREDvma
*canonlybeinthei_mmaptree.AnanonymousMAP_PRIVATE,stack
*orbrkvma(withNULLfile)canonlybeinananon_vmalist.
*/
structlist_headanon_vma_chain;/*Serializedbymmap_sem&
*page_table_lock*/
structanon_vma*anon_vma;/*Serializedbypage_table_lock*/

/*Functionpointerstodealwiththisstruct.*/
conststructvm_operations_struct*vm_ops;

/*Informationaboutourbackingstore:*/
unsignedlongvm_pgoff;/*Offset(withinvm_file)inPAGE_SIZEunits,*not*PAGE_CACHE_SIZE*/
structfile*vm_file;//文件,如果是私有的匿名映射,該成員為空指針
void*vm_private_data;/*指向內存的私有數據*/

#ifndefCONFIG_MMU
structvm_region*vm_region;/*NOMMUmappingregion*/
#endif
#ifdefCONFIG_NUMA
structmempolicy*vm_policy;/*NUMApolicyfortheVMA*/
#endif
structvm_userfaultfd_ctxvm_userfaultfd_ctx;
};

3.2 虛擬內存操作集合

structvm_operations_struct{
void(*open)(structvm_area_struct*area);//在創建虛擬內存區域時調用open方法
void(*close)(structvm_area_struct*area);//在刪除虛擬內存區域時調用close方法
int(*mremap)(structvm_area_struct*area);//使用系統調用mremap移動虛擬內存區域時調用
int(*fault)(structvm_area_struct*vma,structvm_fault*vmf);//訪問文件映射的虛擬頁時,如果沒有映射到物理頁,生成
//缺頁異常,異常處理程序調用fault方法來把文件的數據讀到文件頁緩存當中
int(*pmd_fault)(structvm_area_struct*,unsignedlongaddress,
pmd_t*,unsignedintflags);//與fault類似,區別是該方法針對使用透明巨型頁的文件映射

/*讀文件映射的虛擬頁時,如果沒有映射到物理頁,生成缺頁異常,異常處理程序除了讀入正在訪問的文件頁
還會預讀后續文件頁,調用map_pages方法在文件的頁緩存中分配物理頁*/
void(*map_pages)(structvm_area_struct*vma,structvm_fault*vmf);

/*notificationthatapreviouslyread-onlypageisabouttobecome
*writable,ifanerrorisreturneditwillcauseaSIGBUS*/

/*第一次寫私有的文件映射時,生成頁錯誤異常,異常處理程序執行寫時復制,調用page_mkwrite方法以
通知文件系統頁即將變成可寫,以便文件系統檢查是否允許寫,或者等待頁進入合適的狀態*/
int(*page_mkwrite)(structvm_area_struct*vma,structvm_fault*vmf);

/*sameaspage_mkwritewhenusingVM_PFNMAP|VM_MIXEDMAP*/
int(*pfn_mkwrite)(structvm_area_struct*vma,structvm_fault*vmf);

/*calledbyaccess_process_vmwhenget_user_pages()fails,typically
*forusebyspecialVMAsthatcanswitchbetweenmemoryandhardware
*/
int(*access)(structvm_area_struct*vma,unsignedlongaddr,
void*buf,intlen,intwrite);

/*Calledbythe/proc/PID/mapscodetoaskthevmawhetherit
*hasaspecialname.Returningnon-NULLwillalsocausethis
*vmatobedumpedunconditionally.*/
constchar*(*name)(structvm_area_struct*vma);

#ifdefCONFIG_NUMA
/*
*set_policy()opmustaddareferencetoanynon-NULL@newmempolicy
*toholdthepolicyuponreturn.CallershouldpassNULL@newto
*removeapolicyandfallbacktosurroundingcontext--i.e.donot
*installaMPOL_DEFAULTpolicy,northetaskorsystemdefault
*mempolicy.
*/
int(*set_policy)(structvm_area_struct*vma,structmempolicy*new);

/*
*get_policy()opmustaddreference[mpol_get()]toanypolicyat
*(vma,addr)markedasMPOL_SHARED.Thesharedpolicyinfrastructure
*inmm/mempolicy.cwilldothisautomatically.
*get_policy()mustNOTaddarefifthepolicyat(vma,addr)isnot
*markedasMPOL_SHARED.vmapoliciesareprotectedbythemmap_sem.
*Ifno[shared/vma]mempolicyexistsattheaddr,get_policy()op
*mustreturnNULL--i.e.,donot"fallback"totaskorsystemdefault
*policy.
*/
structmempolicy*(*get_policy)(structvm_area_struct*vma,
unsignedlongaddr);
#endif
/*
*Calledbyvm_normal_page()forspecialPTEstofindthe
*pagefor@addr.Thisisusefulifthedefaultbehavior
*(usingpte_page())wouldnotfindthecorrectpage.
*/
structpage*(*find_special_page)(structvm_area_struct*vma,
unsignedlongaddr);
};

四、系統調用

  • 應用程序通常使用C標準庫提供的函數malloc()申請內存。glibc庫的內存分配器ptmalloc使用brk或mmap向內核以頁為單位申請虛擬內存,然后把頁劃分成小內存塊分配給應用程序。默認的閾值是128kb,如果應用程序申請的內存長度小于閾值,ptmalloc分配器使用brk向內核申請虛擬內存,否則ptmalloc分配器使用mmap向內核申請虛擬內存。
  • 應用程序可以直接使用mmap向內核申請虛擬內存。
【回顧mmap內存映射原理三個階段】:
  1. 進程啟動映射過程,并且在虛擬地址空間中為映射創建虛擬映射區域;
  2. 調用內核空間的系統調用函數mmap(不同于用戶空間函數),實現文件物理地址和進程虛擬地址的一一映射關系;
  3. 進程發起對這片映射空間的訪問,引發缺頁異常,實現文件內容到物理內存(主存)的拷貝。
內存管理子系統提供以下常用系統調用函數:
  1. mmap() ---->創建內存映射

#include void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

  • 系統調用mmap():進程創建匿名的內存映射,把內存的物理頁映射到進程的虛擬地址空間。進程把文件映射到進程的虛擬地址空間,可以像訪問內存一樣訪問文件,不需要調用系統調用read()/write()訪問文件,從而避免用戶模式和內核模式之間的切換,提高讀寫文件速度。兩個進程針對同一個文件創建共享的內存映射,實現共享內存。
  1. munmap() ---->刪除內存映射

#include int munmap(void *addr, size_t len);


代碼實踐

#include
#include
#include
#include
#include
#include
#include

typedefstruct
{
/*data*/
charname[6];
intage;
}people;

intmain(intargc,char**argv)
{
intfd,i;
people*p_map;
chartemp;
fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);

lseek(fd,sizeof(people)*5-1,SEEK_SET);
write(fd,"",1);

p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if(p_map==(void*)-1)
{
fprintf(stderr,"mmap:%s
",strerror(errno));
return-1;
}

temp='A';
close(fd);

for(i=0;i10;i++)
{
temp=temp+1;
(*(p_map+i)).name[1]='';
memcpy((*(p_map+i)).name,&temp,1);
(*(p_map+i)).age=30+i;
}

printf("Initialize.
");

sleep(15);

munmap(p_map,sizeof(people)*10);

printf("UMAOK.
");
return0;
}

#include
#include
#include
#include
#include
#include
#include

typedefstruct
{
/*data*/
charname[6];
intage;
}people;

intmain(intargc,char**argv)
{
intfd,i;
people*p_map;

fd=open(argv[1],O_CREAT|O_RDWR,00777);
p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p_map==(void*)-1)
{
fprintf(stderr,"mmap:%s
",strerror(errno));
return-1;
}

for(i=0;i10;i++)
{
printf("name:%sage:%d
",(*(p_map+i)).name,(*(p_map+i)).age);
}

munmap(p_map,sizeof(people)*10);

return0;
}

運行結果

f5d13690-942f-11ed-bfe3-dac502259ad0.png

審核編輯:陳陳


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11292

    瀏覽量

    209332
  • 內存映射
    +關注

    關注

    0

    文章

    14

    瀏覽量

    7415

原文標題:Linux內核 | 內存映射

文章出處:【微信號:嵌入式開發AIoT,微信公眾號:嵌入式開發AIoT】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    從史前文明到女媧補天:Linux內存逆向映射(reverse mapping)技術的前世今生

    關于Linux內存管理逆向映射技術的歷史和現在的分析,投稿標題《逆向映射的演進》,后經過小編與郭大俠商議改為《Linux
    的頭像 發表于 09-06 15:45 ?1w次閱讀
    從史前文明到女媧補天:<b class='flag-5'>Linux</b><b class='flag-5'>內存</b>逆向<b class='flag-5'>映射</b>(reverse mapping)技術的前世今生

    Linux內核之內存映射原理分析

    Linux 內核采用延遲分配物理內存的策略,在進程第一次訪問虛擬頁的時候,產生缺頁異常。如果是文件映射,那么分配物理頁,把文件指定區間的數據讀到物理頁中,然后在頁表中把虛擬頁映射到物理
    發表于 07-21 17:06 ?2354次閱讀

    Linux內存映射與頁表詳解

    我們通常所說的內存容量,指的是物理內存,只有內核才可以直接訪問物理內存,進程并不可以。
    發表于 08-18 12:30 ?1131次閱讀

    關于Linux內存管理的詳細介紹

    Linux內存管理是指對系統內存的分配、釋放、映射、管理、交換、壓縮等一系列操作的管理。在Linux中,
    發表于 03-06 09:28 ?1064次閱讀

    拆解mmap內存映射的本質!

    mmap 內存映射里所謂的內存其實指的是虛擬內存,在調用 mmap 進行匿名映射的時候(比如進行堆內存
    的頭像 發表于 01-24 14:30 ?1706次閱讀
    拆解mmap<b class='flag-5'>內存</b><b class='flag-5'>映射</b>的本質!

    Linux內核地址映射模型與Linux內核高端內存詳解

    的數據可能不在內存中。 Linux內核地址映射模型 x86 CPU采用了段頁式地址映射模型。進程代碼中的地址為邏輯地址,經過段頁式地址映射
    發表于 05-08 10:33 ?3453次閱讀
    <b class='flag-5'>Linux</b>內核地址<b class='flag-5'>映射</b>模型與<b class='flag-5'>Linux</b>內核高端<b class='flag-5'>內存</b>詳解

    [4.5.1]--4.5動手實踐-Linux內存映射基礎(上)

    Linux
    jf_75936199
    發布于 :2023年02月25日 01:56:27

    [4.6.1]--4.6動手實踐-Linux內存映射實現(中)_clip001

    Linux
    jf_75936199
    發布于 :2023年02月25日 01:57:12

    [4.6.1]--4.6動手實踐-Linux內存映射實現(中)_clip002

    Linux
    jf_75936199
    發布于 :2023年02月25日 02:04:19

    [4.7.1]--4.7動手實踐-Linux內存映射測試(下)

    Linux
    jf_75936199
    發布于 :2023年02月25日 02:05:04

    Linux的mmap文件內存映射機制

    Linux的mmap文件內存映射機制在講述文件映射的概念時, 不可避免的要牽涉到虛存(SVR 4的VM). 實際上, 文件映射是虛存的中心概
    發表于 03-08 09:54

    RTOS和Linux中的內存映射及移植方法

    映射到相應得用戶空間去。同樣重要的是,在I/O調用密集的嵌入式程序中怎么樣把RTOS的硬件接口代碼移植到更加規范的Linux設備驅動程序中去。 本文把概述幾種常用的經常出現于現有嵌入式應用中的內存
    發表于 07-03 07:43

    Linux的mmap文件內存映射機制

    的. Linux提供了內存映射函數mmap, 它把文件內容映射到一段內存上(準確說是虛擬內存上)
    發表于 04-02 14:35 ?438次閱讀

    淺析linux內存映射原理

    內存映射,簡而言之就是將用戶空間的一段內存區域映射到內核空間,映射成功后,用戶對這段內存區域的修
    發表于 08-24 09:35 ?1623次閱讀
    淺析<b class='flag-5'>linux</b><b class='flag-5'>內存</b><b class='flag-5'>映射</b>原理

    Linux 內存管理總結

    一、Linux內存管理概述 Linux內存管理是指對系統內存的分配、釋放、映射、管理、交換、壓縮
    的頭像 發表于 11-10 14:58 ?525次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>內存</b>管理總結
    主站蜘蛛池模板: 精品AV无码一二三区视频| 野花香HD免费高清版6高清版| 国产成人AV永久免费观看| 天堂无码人妻精品AV一区| 国产剧情麻豆mv| 亚洲AV噜噜88| 灰原哀被啪漫画禁漫| 中文字幕无码亚洲字幕成A人蜜桃 中文字幕无码亚洲视频 | 青柠在线电影高清免费观看| 超碰免费视频在线观看| 无码成人AAAAA毛片含羞草| 极品 女神校花 露脸91| 1024人成网站色www下载| 日本阿v在线资源无码免费| 国产精品玖玖玖影院| 一抽一出BGM免费50分动漫| 男女夜晚在爽视频免费观看| 纯肉巨黄H爆粗口男男分卷阅读| 无限资源日本2019版| 久久精品视频免费| 啊叫大点声欠CAO的SAO贷| 午夜免费体验30分| 久久香蕉国产线看观看| oldgrand欧洲老妇人| 胸大美女又黄的网站| 久久久久99精品成人片三人毛片| 91精品国产色综合久久| 色婷婷AV国产精品欧美毛片| 护士被老头边摸边吃奶的视频| 18禁裸乳无遮挡免费网站| 色cccwww| 久草在线在线精品观看99| japanese from色系| 亚洲99精品A片久久久久久| 久久在精品线影院| 二级毛片免费观看全程| 一抽一出BGM免费50分动漫| 青青涩射射| 花蝴蝶hd免费| 扒开校花粉嫩小泬喷潮漫画| 亚洲h视频在线观看|