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...