linux 内核:为什么 swapper_pg_dir 被加载到 cr3 两次

linux kernel: why swapper_pg_dir is loaded into cr3 twice

我正在阅读 linux 2.6.26 源代码。

在内核启动期间,swapper_pg_dir 被加载到 cr3 两次。

第一次,在arch/x86/kernel/head_32.S,开始分页

331     movl $pa(swapper_pg_dir),%eax
332     movl %eax,%cr3      /* set the page table pointer.. */

之后,在 arch/x86/mm/init_32.c

519 void __init paging_init(void)
520 {
521 #ifdef CONFIG_X86_PAE
522     set_nx();
523     if (nx_enabled)
524         printk(KERN_INFO "NX (Execute Disable) protection: active\n");
525 #endif
526     pagetable_init();
527 
528     load_cr3(swapper_pg_dir);                                                                                                                                                                
529 
530     __flush_tlb_all();
531 
532     kmap_init();
533 }

是否需要 528 行 load_cr3(swapper_pg_dir),因为 swapper_pg_dir 已经在 head_32.S 中加载到 cr3 中?

arch/x86/mm/init_32.c中的评论+376个答案:

364 /*                                                                                                                                                                                           
365  * Build a proper pagetable for the kernel mappings.  Up until this
366  * point, we've been running on some set of pagetables constructed by
367  * the boot process.
368  *
369  * If we're booting on native hardware, this will be a pagetable
370  * constructed in arch/x86/kernel/head_32.S.  The root of the
371  * pagetable will be swapper_pg_dir.
372  *
373  * If we're booting paravirtualized under a hypervisor, then there are
374  * more options: we may already be running PAE, and the pagetable may
375  * or may not be based in swapper_pg_dir.  In any case,
376  * paravirt_pagetable_setup_start() will set up swapper_pg_dir
377  * appropriately for the rest of the initialization to work.
378  *
379  * In general, pagetable_init() assumes that the pagetable may already
380  * be partially populated, and so it avoids stomping on any existing
381  * mappings.
382  */
383 static void __init pagetable_init(void)
384 {