ARM linux 建立頁表過程

來源:互聯網
上載者:User

paging_init 用來建立頁表,初始化zone的memory map

    void *zero_page;    sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);    build_mem_type_table();    sanity_check_meminfo();    prepare_page_table();    map_lowmem();    bootmem_init();    devicemaps_init(mdesc);    kmap_init();    top_pmd = pmd_off_k(0xffff0000);    /*     * allocate the zero page.  Note that this always succeeds and     * returns a zeroed result.     */    zero_page = alloc_bootmem_low_pages(PAGE_SIZE);    empty_zero_page = virt_to_page(zero_page);    __flush_dcache_page(NULL, empty_zero_page);

build_mem_type_table 這個函數根據CPU類型,設定mem_types全域數組,mem_types數組儲存了頁目錄和頁表的屬性,將來建立頁目錄和頁表時,會用到mem_types。

sanity_check_meminfo 檢測判斷是否需要建立highmem區,並且重建描述記憶體bank的數組

VMALLOC_MIN定義了vmalloc區的起始位置(通過VMALLOC_END和vmalloc_reserve計算得出),VMALLOC_END定義了vmalloc區的結束位置,vmalloc_reserve是系統預留給vmalloc區的大小。

prepare_page_table 這個函數會請空頁目錄,有兩塊地址空間地區是不需要清除的,一個是kernel image,另外一個是kernel線性地址映射區

map_lowmem 建立低端記憶體的所有頁目錄和頁表:遍曆memory bank,映射那些沒有highmem標記的記憶體bank

bootmem_init :

1. 調用check_initrd擷取initrd所在的memory bank對應的node

2. 對每一個節點:

  • 擷取該node的 min(最小pfn), node_low(最大low memory pfn), node_hight(最大high memory pfn)
  • 調用bootmem_init_node初始化node,bootmem_init_node會初始化bootmem bitmap
  • 如果是node 0,那麼調用reserve_node_zero為node 0 reserve的記憶體:核心text和data區,初始化頁表區(16KB),以及swapper_pg_dir之前的一塊記憶體(在我的機器上是4個page)
  • 如果initrd存放在當前的node上,那麼調用bootmem_reserve_initrd保留initrd佔用的記憶體。initrd_start是initrd在起始虛擬記憶體地址,initrd_end是initrd結束的虛擬記憶體地址。

3. 對每一個node 調用bootmem_free_node

  • 設定這個node內各個zone的大小
  • 調用free_area_init_node:計算node的總pages數目,為這個node分配mem map,注意node內所有zone的memmap都分配在一起
  • 調用free_area_init_core:對於node內的每一個zone,進行初始化。注意這個函數present_pages是total size減去了該分區對應的memmap佔用的pages,但是實際上memmap是放在node的開始位置,這裡似乎不應該減去這個值

4. high_memory 是一個很奇怪的變數,high_memory應該是實體記憶體的概念,但是high_memory變數儲存的確實一個核心地址。

devicemaps_init 這個函數建立device的映射,

1. 把machine vectors映射到0xffff0000處

2. 調用平台特定的map_io,對於mx51,這個函數主要是映射mx51功能寄存器區, AIPS1 AIPS2 和SPBA0,這三個寄存器區大小為1MB,映射後的虛擬位址分別為0xF7E00000,0xF7D00000,0xFB100000

kmap_init 建立pkmap的pgd和pte。並且讓pkmap_page_table指向這個PTE page的linux p/t。一般來說kmap都是使用一個page的pte來映射高端記憶體到核心地址空間,對於arm來說,每個page可以存放512個pte_t,所以pkmap的地址空間為2M。

empty zero page

按照源碼注釋,它是一個特定的初始化為0的頁,用於COW

我的理解是,系統有時需要一個頁面全零,這種情況下,並不需要分配一個全零的頁面,而是讓PTE指向empty_zero_page,當試圖寫這個page時,由於這個empty_zero_page是共用的,所以導致了COW。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.