Kernel Page Global Directory (PGD) of Page table of Process created in Linux Kernel

Kernel Page Global Directory (PGD) of User process created

在早期版本:html

在fork一個進程的時候,必須創建進程本身的內核頁目錄項(內核頁目錄項要與用戶空間
的頁目錄放在同一個物理地址連續的頁面上,因此不能共享,但全部進程的內核頁表與進
程0共享)
3G用戶,頁目錄中一項映射4M的空間(一項頁目錄1024項頁表,每項頁表對應1個頁面4K
),即:
#define PGDIR_SHIFT 22
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
>>> sys_fork->do_fork->copy_mm->mm_init->pgd_alloc->get_pgd_slow
#if CONFIG_X86_PAE
。。。。。。。。。。。。。
#else
extern __inline__ pgd_t *get_pgd_slow(void)
{
>>> 分配頁目錄表(包含1024項頁目錄),即爲一個進程分配的頁目錄能夠映射的空間爲
1024*4M=4G
 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
 if (pgd) {
>>> #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
>>> TASK_SIZE爲3G大小,USER_PTRS_PER_PGD爲用戶空間對應的頁目錄項數目(
3G/4M=768)
>>> 將用戶空間的頁目錄項清空
  memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
>>> 將內核頁目錄表(swapper_pg_dir)的第768項到1023項拷貝到進程的頁目錄表的第
768項到1023項中
  memcpy(pgd + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, 
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 }
 return pgd;
}
#endiflinux

比較後來的版本:app

pgd_t *pgd_alloc(struct mm_struct *mm)  -> 
 pgd_ctor(mm, pgd); //關鍵代碼,將指向內核空間的頁目錄項拷貝到新分配的pgd對應的項目中。
->
    clone_pgd_range(pgd + KERNEL_PGD_BOUNDARY, //item points to the kernel space
             swapper_pg_dir + KERNEL_PGD_BOUNDARY, KERNEL_PGD_PTRS);

ref. spa

[1] http://biancheng.dnbcw.info/linux/321897.html.net

[2] http://m.blog.csdn.net/blog/SunnyBeiKe/6898253code

相關文章
相關標籤/搜索