linux 的启动涉及到一个解压与定位的过程,对于x86体系结构而言,系统被加载到0x100000的地方,那么swapper_pg_dir的值是什么呢?我们知道swapper_pg_dir是一个很重要的东西,它是所有进程内核空间的页表的模板,而且在涉及到896M以上的内存分配时,swapper_pg_dir也是一个同步的根,这些内存分配包括vmalloc区,高端永久区,高端临时区等。这里需要说明的是,swapper_pg_dir这个东西其实就是一个页目录的指针,页目录指针在x86中是要被加载到cr3寄存器的(使用的 arm产品芯片是没有实现LPAE(Large Physical Address Extension)的VMSA 架构 (即使用MMU管理内存的架构,区别于用MPU来管理内存的PMSA)时,可以使用TTBR0与TTBR1来做保存页表的起始地址,而一个VA具体是用哪一个寄存器中的地址来做translation table walk时,要看TTBCR寄存器的N值以及VA的具体值, 具体看: ARM? Architecture Reference Manual  ARMv7-A and ARMv7-R edition 的文档说明。而因为ARM不能用0xC0000000做为TTBR0与TTBR1所管理的VA的分界,所以Linux并没有使用TTBR1,而是不管是内核空间还是用户空间都只使用TTBR0做为Translation table的存储地址寄存器。
),每个进程都有一个页目录指针,这个指针指示这个进程的内存映射信息,每当切换到一个进程时,该进程的页目录指针就被加载到了cr3,然后直到切换到别的进程的时候才更改,既然swapper_pg_dir是一个页目录指针,那么这个指针是被哪个进程用的呢?现代 操作系统 的含义指示了进程间内存隔离,那么一个页目录指针只能被一个进程使用,那么到底是哪个特定的进程使用了swapper_pg_dir指针呢?遗憾的是,答案是没有任何用户进程使用swapper_pg_dir作为页目录指针,swapper_pg_dir只是在内核初始化的时候被载入到cr3指示内存映射信息,之后在init进程启动后就成了idle内核线程的页目录指针了,/sbin/init由一个叫做init的内核线程exec而成,而init内核线程是原始的内核也就是后来的idle线程do_fork而成的,而在do_fork中会为新生的进程重启分配一个页目录指针,由此可见swapper_pg_dir只是在idle的内核线程中被使用,可是它的作用却不只是为idle进程指示内存映射信息,更多的,它作为一个内核空间的内存映射模板而存在,在 Linux 中,任何进程在内核空间就不分彼此了,所有的进程都会公用一份内核空间的内存映射,因此,内核空间是所有进程共享的,每当一个新的进程建立的时候,都会将swapper_pg_dir的768项以后的信息全部复制到新进程页目录的768项以后,代表内核空间。另外在操作3G+896M以上的虚拟内存时,只会更改swapper_pg_dir的映射信息,当别的进程访问到这些页面的时候会发生缺页,在缺页处理中会与swapper_pg_dir同步。

swapper_pg_dir
被定义在arch/arm/kernel/head.S
#ifdef CONFIG_ARM_LPAE                           
    /* LPAE requires an additional page for the PGD */
#define PG_DIR_SIZE 0x5000                       
#define PMD_ORDER   3                            
#else                                            
#define PG_DIR_SIZE 0x4000                                 
#define PMD_ORDER   2                            
#endif                                           
                                                 
    .globl  swapper_pg_dir                       
    .equ    swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
伪指令equ定义          swapper_pg_dir 值为                        KERNEL_RAM_VADDR - PG_DIR_SIZE     




Logo

更多推荐