新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM linux 建立頁表過程

        ARM linux 建立頁表過程

        作者: 時間:2016-11-09 來源:網絡 收藏
        paging_init 用來建立頁表,初始化zone的memory map

        本文引用地址:http://www.104case.com/article/201611/317934.htm
        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。



        關鍵詞: ARMlinux建立頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 南开区| 黔东| 蓬莱市| 理塘县| 高台县| 浦县| 赤峰市| 金沙县| 如皋市| 墨江| 万荣县| 上蔡县| 铜梁县| 镇沅| 吉林市| 灌南县| 兴城市| 天长市| 潮安县| 靖安县| 藁城市| 乡宁县| 贵定县| 泸溪县| 兖州市| 天津市| 壶关县| 松潘县| 拜泉县| 宜宾县| 永吉县| 龙山县| 鲜城| 嘉荫县| 肇庆市| 小金县| 宁蒗| 五大连池市| 丰台区| 五莲县| 汶上县|