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

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

一篇解析Linux paging_init

2022-12-12 17:47 作者:補給站Linux內(nèi)核  | 我要投稿

說明:

  1. Kernel版本:4.14

  2. ARM64處理器,Contex-A53,雙核

  3. 使用工具:Source Insight 3.5, Visio

1. 介紹

從詳細講解Linux物理內(nèi)存初始化中,可知在paging_init調(diào)用之前,存放Kernel Image和DTB的兩段物理內(nèi)存區(qū)域可以訪問了(相應的頁表已經(jīng)建立好)。盡管物理內(nèi)存已經(jīng)通過memblock_add添加進系統(tǒng),但是這部分的物理內(nèi)存到虛擬內(nèi)存的映射還沒有建立,可以通過memblock_alloc分配一段物理內(nèi)存,但是還不能訪問,一切還需要等待paging_init的執(zhí)行。最終頁表建立好后,可以通過虛擬地址去訪問最終的物理地址了。

按照慣例,先上圖,來一張ARM64內(nèi)核的內(nèi)存布局圖片吧,最終的布局如下所示:


2. paging_init

paging_init源代碼短小精悍,直接貼上來,分模塊來介紹吧。


  • mark 1:分配一頁大小的物理內(nèi)存存放pgd;

  • mark 2:將內(nèi)核的各個段進行映射;

  • mark 3:將memblock子系統(tǒng)添加的物理內(nèi)存進行映射;

  • mark 4:切換頁表,并將新建立的頁表內(nèi)容替換swappper_pg_dir頁表內(nèi)容;

代碼看起來費勁?圖來了:

圖片

下邊將對各個子模塊進一步的分析。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ??


3. early_pgtable_alloc

這個模塊與FIX MAP映射區(qū)域相關(guān),建議先閱讀前文(二)Linux物理內(nèi)存初始化先上圖:

圖片

FIX MAP的區(qū)域劃分從圖中可以看出來

本函數(shù)會先分配物理內(nèi)存,然后借用之前的全局頁表bm_pte,建立物理地址到虛擬地址的映射,這次映射的作用是為了去訪問物理內(nèi)存,把內(nèi)存清零,所以它只是一個臨時操作,操作完畢后,會調(diào)用pte_clear_fixmap()來清除映射。

early_pgtable_alloc之后,我們看到paging_init調(diào)用了pgd_set_fixmap函數(shù),這個函數(shù)調(diào)用完后,通過memblock_alloc分配的物理內(nèi)存,最終就會用來存放pgd table了,這片區(qū)域的內(nèi)容最后也會拷貝到swapper_pg_dir中去。

4. map_kernel

map_kernel的主要工作是完成內(nèi)核中各個段的映射,此外還包括了FIXADDR_START虛擬地址的映射,如下圖:

圖片

映射完成之后,可以看一下具體各個段的區(qū)域,以我自己使用的平臺為例:

圖片

這些地址信息也能從System.map文件中找到。

aarch64-linux-gnu-objdump -x vmlinux能查看更詳細的地址信息。

5. map_mem

從函數(shù)名字中可以看出,map_mem主要完成的是物理內(nèi)存的映射,這部分的物理內(nèi)存是通過memblock_add添加到系統(tǒng)中的,當對應的memblock設置了MEMBLOCK_NOMAP的標志時,則不對其進行地址映射。

map_mem函數(shù)中,會遍歷memblock中的各個塊,然后調(diào)用__map_memblock來完成實際的映射操作。先來一張效果圖:

圖片

map_mem都是將物理地址映射到線性區(qū)域中,我們也發(fā)現(xiàn)了Kernel Image中的text, rodata段映射了兩次,原因是其他的子系統(tǒng),比如hibernate,會映射到線性區(qū)域中,可能需要線性區(qū)域的地址來引用內(nèi)核的text, rodata,映射的時候也會限制成了只讀/不可執(zhí)行,防止意外修改或執(zhí)行。

map_kernelmap_mem函數(shù)中的頁表映射,最終都是調(diào)用__create_pgd_mapping函數(shù)實現(xiàn)的:

圖片

總體來說,就是逐級頁表建立映射關(guān)系,同時中間會進行權(quán)限的控制等。細節(jié)不再贅述,代碼結(jié)合圖片閱讀,效果會更佳噢。

6. 頁表替換及內(nèi)存釋放

這部分代碼不多,不上圖了,看代碼吧:

簡單來說,將新建立好的pgd頁表內(nèi)容,拷貝到swapper_pg_dir中,也就是覆蓋掉之前的臨時頁表了。當拷貝完成后,顯而易見的是,我們可以把paging_init一開始分配的物理內(nèi)存給釋放掉。

此外,在之前的文章也分析過swapper_pg_dir頁表存放的時候,是連續(xù)存放的pgd, pud, pmd等,現(xiàn)在只需要復用swapper_pg_dir,其余的當然也是可以釋放的了。


原文作者:LoyenWang




一篇解析Linux paging_init的評論 (共 條)

分享到微博請遵守國家法律
苍山县| 岱山县| 仲巴县| 万年县| 新密市| 辽阳市| 普安县| 建始县| 江阴市| 司法| 西青区| 北安市| 荃湾区| 玉门市| 东兰县| 抚远县| 新晃| 安塞县| 九江市| 太保市| 醴陵市| 黄骅市| 东乡县| 台北县| 文登市| 新源县| 郎溪县| 镇远县| 五大连池市| 阿荣旗| 玉环县| 雅江县| 隆尧县| 锦屏县| 双流县| 吴忠市| 阳泉市| 沙坪坝区| 富源县| 石河子市| 讷河市|