啟動期間的記憶體管理之pagging_init初始化分頁機制--Linux記憶體管理(十四)

来源:https://www.cnblogs.com/linhaostudy/archive/2018/12/08/10088904.html
-Advertisement-
Play Games

1 今日內容(分頁機制初始化) 在初始化記憶體的結點和記憶體區域之前, 內核先通過pagging_init初始化了內核的分頁機制. 在分頁機制完成後, 才會開始初始化系統的記憶體數據結構(包括記憶體節點數據和記憶體區域), 併在隨後初始化buddy伙伴系統來接管記憶體管理的工作 2 分頁機制初始化 arm64架 ...


1 今日內容(分頁機制初始化)

在初始化記憶體的結點和記憶體區域之前, 內核先通過pagging_init初始化了內核的分頁機制.

在分頁機制完成後, 才會開始初始化系統的記憶體數據結構(包括記憶體節點數據和記憶體區域), 併在隨後初始化buddy伙伴系統來接管記憶體管理的工作

2 分頁機制初始化

arm64架構下, 內核在start_kernel()->setup_arch()中通過arm64_memblock_init( )完成了memblock的初始化之後, 接著通過setup_arch()->paging_init()開始初始化分頁機制

paging_init負責建立只能用於內核的頁表, 用戶空間是無法訪問的. 這對管理普通應用程式和內核訪問記憶體的方式,有深遠的影響

2.1 虛擬地址空間(以x86_32位系統為例)

因此在仔細考察其實現之前,很重要的一點是解釋該函數的目的

在x86_32系統上內核通常將總的4GB可用虛擬地址空間按3:1的比例劃分給用戶空間和內核空間, 虛擬地址空間的低端3GB

用於用戶狀態應用程式, 而高端的1GB則專用於內核. 儘管在分配內核的虛擬地址空間時, 當前系統上下文是不相干的, 但每個進程都有自身特定的地址空間.

這些劃分主要的動機如下所示

  • 在用戶應用程式的執行切換到核心態時(這總是會發生,例如在使用系統調用或發生周期性的時鐘中斷時),內核必須裝載在一個可靠的環境中。因此有必要將地址空間的一部分分配給內核專用.
  • 物理記憶體頁則映射到內核地址空間的起始處,以便內核直接訪問,而無需複雜的頁表操作.

如果所有物理記憶體頁都映射到用戶空間進程能訪問的地址空間中, 如果在系統上有幾個應用程式在運行, 將導致嚴重的安全問題. 每個應用程式都能夠讀取和修改其他進程在物理記憶體中的記憶體區. 顯然必須不惜任何代價防止這種情況出現.

雖然用於用戶層進程的虛擬地址部分隨進程切換而改變,但是內核部分總是相同的

出於記憶體保護等一系列的考慮, 內核將整個進程的虛擬運行空間劃分為內核虛擬運行空間和內核虛擬運行空間

按3:1的比例劃分地址空間, 只是約略反映了內核中的情況,內核地址空間作為內核的常駐虛擬地址空間, 自身又分為各個段

地址空間的第一段用於將系統的所有物理記憶體頁映射到內核的虛擬地址空間中。由於內核地址空間從偏移量0xC0000000開始,即經常提到的3 GiB,每個虛擬地址x都對應於物理地址x—0xC0000000,因此這是一個簡單的線性平移。

直接映射區域從0xC0000000到high_memory地址,high_memory準確的數值稍後討論。第1章提到過,這種方案有一問題。由於內核的虛擬地址空間只有1 GiB,最多只能映射1 GiB物理記憶體。IA-32系統(沒有PAE)最大的記憶體配置可以達到4 GiB,引出的一個問題是,如何處理剩下的記憶體?

這裡有個壞消息。如果物理記憶體超過896 MiB,則內核無法直接映射全部物理記憶體。該值甚至比此前提到的最大限制1 GiB還小,因為內核必須保留地址空間最後的128 MiB用於其他目的,我會稍後解釋。將這128 MiB加上直接映射的896 MiB記憶體,則得到內核虛擬地址空間的總數為1 024 MiB = 1GiB。內核使用兩個經常使用的縮寫normal和highmem,來區分是否可以直接映射的頁幀。

內核地址空間的最後128 MiB用於何種用途呢?如圖3-15所示,該部分有3個用途。

  • 虛擬記憶體中連續、但物理記憶體中不連續的記憶體區,可以在vmalloc區域分配。該機制通常用於用戶過程,內核自身會試圖儘力避免非連續的物理地址。內核通常會成功,因為大部分大的記憶體塊都在啟動時分配給內核,那時記憶體的碎片尚不嚴重。但在已經運行了很長時間的系統上,在內核需要物理記憶體時,就可能出現可用空間不連續的情況。此類情況,主要出現在動態載入模塊時

  • 持久映射用於將高端記憶體域中的非持久頁映射到內核中

  • 固定映射是與物理地址空間中的固定頁關聯的虛擬地址空間項,但具體關聯的頁幀可以自由
    選擇。它與通過固定公式與物理記憶體關聯的直接映射頁相反,虛擬固定映射地址與物理記憶體位置之間
    的關聯可以自行定義,關聯建立後內核總是會註意到的

同樣我們的用戶空間, 也被劃分為幾個段, 包括從高地址到低地址分別為 :

區域 存儲內容
局部變數, 函數參數, 返回地址等
動態分配的記憶體
BSS段 未初始化或初值為0的全局變數和靜態局部變數
數據段 一初始化且初值非0的全局變數和靜態局部變數
代碼段 可執行代碼, 字元串面值, 只讀變數

2.2 paging_init初始化分頁機制

paging_init函數定義在arch/arm64/mm/mmu.c?v=4.7, line 538

/*
 * paging_init() sets up the page tables, initialises the zone memory
 * maps and sets up the zero page.
 */
void __init paging_init(void)
{
    phys_addr_t pgd_phys = early_pgtable_alloc();
    pgd_t *pgd = pgd_set_fixmap(pgd_phys);

    map_kernel(pgd);
    map_mem(pgd);

    /*
     * We want to reuse the original swapper_pg_dir so we don't have to
     * communicate the new address to non-coherent secondaries in
     * secondary_entry, and so cpu_switch_mm can generate the address with
     * adrp+add rather than a load from some global variable.
     *
     * To do this we need to go via a temporary pgd.
     */
    cpu_replace_ttbr1(__va(pgd_phys));
    memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
    cpu_replace_ttbr1(swapper_pg_dir);

    pgd_clear_fixmap();
    memblock_free(pgd_phys, PAGE_SIZE);

    /*
     * We only reuse the PGD from the swapper_pg_dir, not the pud + pmd
     * allocated with it.
     */
    memblock_free(__pa(swapper_pg_dir) + PAGE_SIZE,
              SWAPPER_DIR_SIZE - PAGE_SIZE);
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於本人是Java入門的開發,在C#開發中遇到的問題,在此記錄一下: 1、client端的send方法不管發送出去沒發送出去,總是顯示發送出去。 查資料得知,send方法是將數據發送到緩存區,並不是直接發送到server。 2、connected 方法,總是顯示已連接上。 一直以為connected ...
  • 在測試中經常會遇到請求一些https的url,但又沒有本地證書,這時候可以用下麵的方法忽略警告 ...
  • 這段時間因公司業務需要.net開發且需要用到DevExpress控制項,我自己研究學習了一下,用的是visual studio(2013)和DevExpress(V14.1.4),VS2013的下載安裝就不說,直接進入正題。 DevExpress(V14.1.4)安裝、破解和漢化的程式下載鏈接 鏈接: ...
  • 在 Asp.Net Core 中,我們常常使用 System.Threading.Timer 這個定時器去做一些需要長期在後臺運行的任務,但是這個定時器在某些場合卻不太靈光,而且常常無法控制啟動和停止,我們需要一個穩定的,類似 WebHost 這樣主機級別的任務管理程式,但是又要比 WebHost ... ...
  • 本節重點不講反射機制,而是講lambda表達式樹來替代反射中常用的獲取屬性和方法,來達到相同的效果但卻比反射高效。 每個人都知道,用反射調用一個方法或者對屬性執行SetValue和GetValue操作的時候都會比直接調用慢很多,這其中設計到CLR中內部的處理,不做深究。然而,我們在某些情況下又無法不 ...
  • ...
  • 一、安裝版本詳情 Server: MariaDB Server version: 5.5.60 MariaDB MariaDB Server [root@ln 125 ~] cat /etc/redhat release CentOS Linux release 7.6.1810 (Core) [r ...
  • 就緒狀態 :一個進程獲得了除處理機外的一切所需資源,一旦得到處理機即可運行,則稱此進程處於就緒狀態。 執行狀態:當一個進程在處理機上運行時,則稱該進程處於運行狀態。 阻塞狀態:一個進程正在等待某一事件發生(例如請求I/O而等待I/O完成等)而暫時仃止運行,這時即使把處理機分配給進程也無法運行,故稱該 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...