Linux核心頁表初始化

2021-06-20 14:54:59 字數 2920 閱讀 5997

linux在核心啟動過程中start_kernel->setup_arch會呼叫如下兩個函式對頁表進行初始化和建立。

static inline void prepare_page_table(void)

由於arm採用兩級對映,pmd不占用字段,pmd=pgd,而這裡一次清了兩個pgd,和pgd的定義正好對應,所以在for迴圈時每次步長為pgdir_size(2m),根本的原因是arm linux使用了arm的兩個段,在使用者態為__user_cs__user_ds,在核心態為__kernel_cs和__kernel_ds

初始化頁表裡也會flush對應的tlb。

typedef unsigned long pgd_t[2];

#define pmd_clear(pmdp)			\

do while (0)

static inline pmd_t *pmd_off_k(unsigned long virt)

#define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)

/* to find an entry in a page-table-directory */

#define pgd_index(addr) ((addr) >> pgdir_shift)

#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))

/* to find an entry in a kernel page-table-directory */

#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)

/* find an entry in the second-level page table.. */

#define pmd_offset(dir, addr) ((pmd_t *)(dir))

/* find an entry in the third-level page table.. */

#define __pte_index(addr) (((addr) >> page_shift) & (ptrs_per_pte - 1))

/*

* create the page directory entries and any necessary

* are able to cope here with varying sizes and address

* offsets, and we take full advantage of sections and

* supersections.

*///高階記憶體通過alloc_page+kmap的形式對映,在初始化階段不可能有bank的虛擬位址落在vmalloc線性位址空間

if ((md->type == mt_device || md->type == mt_rom) &&

md->virtual >= page_offset && md->virtual < vmalloc_end)

type = &mem_types[md->type];

//如果有大於4g的物理記憶體,單獨建立

/* * catch 36-bit addresses

*/if (md->pfn >= 0x100000)

addr = md->virtual & page_mask;

phys = (unsigned long)__pfn_to_phys(md->pfn);

length = page_align(md->length + (md->virtual & ~page_mask));//將bank整頁對齊

if (type->prot_l1 == 0 && ((addr | phys | length) & ~section_mask))

pgd = pgd_offset_k(addr);

end = addr + length;

do while (pgd++, addr != end);

}static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,

unsigned long end, unsigned long phys,

const struct mem_type *type)

while (pmd++, addr += section_size, addr != end);

flush_pmd_entry(p);

} else

}static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,

unsigned long end, unsigned long pfn,

const struct mem_type *type)

pte = pte_offset_kernel(pmd, addr);//建立pte

do while (pte++, addr += page_size, addr != end);}

linux核心初始化

1 系統的引導和初始化 linux 系統的引導有好幾種方式 常見的有 lilo,loadin引導和linux的自舉引導 bootsect loader 而後者所對應源程式為arch i386 boot bootsect.s,它為實模式的匯程式設計序,無論是哪種引導方式,最後都要跳轉到 arch i3...

Linux核心初始化順序

include linux init.h define pure initcall fn define initcall 0 fn,1 define core initcall fn define initcall 1 fn,1 define core initcall sync fn define...

核心初始化

異常處理 總共有七中的異常情況 1 reset 2 undefined instruct 不支援命令異常 3 軟體中斷 4 指令預取失敗異常 5 資料讀取失敗異常 6 中斷 7 快速中斷 比一般的中斷處理速度快一些 中斷向量 當中斷發生時,處理器就會跳轉到乙個固定的位址去處理指令 globl sta...