免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2169 | 回复: 0
打印 上一主题 下一主题

/mm/init.c paging_init() [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-13 13:29 |只看该作者 |倒序浏览



setup.S->start_kernel(void) -> setup_arch -> paging_init()
(1)
   接下来是paging_init,调用下面的pagetable_init,初始化页表然后重新加
载cr3,flush tlb,然后使用kmap_init为kmap_automic使用的变量求值,.....
不算复杂,重要的是free_area_init,初始化了zone-buddy内存管理系统(设置
所有页面都是PG_reserved(free_all_bootmem,负责重置)).
503 void __init paging_init(void)
504 {
505 #ifdef CONFIG_X86_PAE
506         set_nx();
507         if (nx_enabled)
508                 printk("NX (Execute Disable) protection: active\n");
509 #endif
510
511         pagetable_init();
512
513         load_cr3(swapper_pg_dir);
514
515 #ifdef CONFIG_X86_PAE
516         /*
517          * We will bail out later - printk doesn't work right now so
518          * the user would just see a hanging kernel.
519          */
520         if (cpu_has_pae)
521                 set_in_cr4(X86_CR4_PAE);
522 #endif
523         __flush_tlb_all();      //load 了cr3...
524
525         kmap_init();
526 }
(2)/mm/init.c
swapper_pg_dir 静态分配的
pgd_t swapper_pg_dir[1024];
//删了config_pae的代码
内核在使用虚拟空间:
+------------------------------------------------------------------     
|   8K空洞
+------------------------------------------------------------------
|   FIXADDR_TOP(0xffffe000UL)            (include/asm-i386/fixmap.h)
|   fixed map(每项4k虚存,见FIXADDR_SIZE)      
|      { //fix map 内容 (enum fixed_addresses)
|         FIX_APIC_BASE,
|     FIX_IO_APIC_BASE_0,
|   FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1
|
|   FIX_CO_CPU, /* Cobalt timer */
|   FIX_CO_APIC, /* Cobalt APIC Redirection Table */
|   FIX_LI_PCIA, /* Lithium PCI Bridge A */
|   FIX_LI_PCIB, /* Lithium PCI Bridge B */
+--------------
#ifdef CONFIG_HIGHMEM   /*为fix KMAP预留每cpu 8k的虚存,读写各4k*/
|      FIX_KMAP_BEGIN,  /* 主要用于kmap_atomic*/
|    FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
+--------------
|    __end_of_fixed_addresses
|       }
|   FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
+--------------------------------------------------------------------
|   VMALLOC_END (FIXADDR_START)  (include/asm-i386/pgtable.h)
|       +------------------
|       |  xxxxx: kmap 和 vmalloc 相互重叠,2.6已经修正
|       |     kmap 使用的4M虚存  (asm/highmem.h,LAST_PKMAP)
|       |  PKMAP_BASE (0xfe000000UL) (距离4G 32M)
|       +------------------
|     vmalloc 映射区
|   VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1)
|                  & \~(VMALLOC_OFFSET-1)) /*down align 8M */
+--------------------------------------------------------------------
|   约 8M 空洞
+--------------------------------------------------------------------
|   high_memory (见003___arch_i386_mm_ioremap.c 对此的分析)  ..一定映射到内核虚拟空间???,不可以是fixaddr么???
|      内核已经映射了的物理页面 MAX 896M
|
|
|   3G
+--------------------------------------------------------------------
|   resoved for app 0-3G
+--------------------------------------------------------------------
(3) pagetable_init
339 static void __init pagetable_init (void)
340 {
341         unsigned long vaddr;
342         pgd_t *pgd_base = swapper_pg_dir;
351         /* Enable PSE if available */
352         if (cpu_has_pse) {
353                 set_in_cr4(X86_CR4_PSE);
354         }
355
356         /* Enable PGE if available */
357         if (cpu_has_pge) {
358                 set_in_cr4(X86_CR4_PGE);
359                 __PAGE_KERNEL |= _PAGE_GLOBAL;
360                 __PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
361         }
362
363         kernel_physical_mapping_init(pgd_base);
364         remap_numa_kva();
365
366         /*
367          * Fixed mappings, only the page table structure has to be
368          * created - mappings will be set by set_fixmap():
369          */
370         vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
371         page_table_range_init(vaddr, 0, pgd_base);    //这里用0,应该是超过了4G,或者2^64,回饶,所以是0
372
373         permanent_kmaps_init(pgd_base);
385 }
141  /* This maps the physical memory to kernel virtual address space, a total
142  * of max_low_pfn pages, by creating page tables starting from address
143  * PAGE_OFFSET.
144  */
PAGE_OFFSET      0xc0000000
//初始化页目录,页表,,
//1页目录 = 1 * (4k/4) * 4k = 4M,    896M,所以要用掉页目录表中的 896/4 = 225项  
//pse设置话是一页面是4MB了,
//这样
(4) kernel_physical_mapping_init
145 static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
146 {
147         unsigned long pfn;
148         pgd_t *pgd;
149         pmd_t *pmd;
150         pte_t *pte;
151         int pgd_idx, pmd_idx, pte_ofs;
152
153         pgd_idx = pgd_index(PAGE_OFFSET);   //内核虚拟地址开始处....
154         pgd = pgd_base + pgd_idx;
155         pfn = 0;
156
157         for (; pgd_idx = max_low_pfn)
160                         continue;
161                 for (pmd_idx = 0; pmd_idx

76 /*
77  * Create a page table and place a pointer to it in a middle page
78  * directory entry.
79  */
80 static pte_t * __init one_page_table_init(pmd_t *pmd)
81 {
82         if (pmd_none(*pmd)) {      //开始时,pmd为none,分配pte_t表...然后建立映射.
83                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
84                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));     //设置页面目录.
85                 if (page_table != pte_offset_kernel(pmd, 0))
86                         BUG();  
87
88                 return page_table;
89         }
90         
91         return pte_offset_kernel(pmd, 0);
92 }
93
370 #define pte_offset_kernel(dir, address) \
371         ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
375 #define pmd_page_kernel(pmd) \
376                 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))

(5) page_table_range_init  ,,,没设置pte...因为这是用来映射高端内存的或者别的用途?.要用的时候再设置pte项..而不是永久映射.
105 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
106 {
107         pgd_t *pgd;
108         pud_t *pud;
109         pmd_t *pmd;
110         int pgd_idx, pmd_idx;
111         unsigned long vaddr;
112
113         vaddr = start;
114         pgd_idx = pgd_index(vaddr);
115         pmd_idx = pmd_index(vaddr);
116         pgd = pgd_base + pgd_idx;
117
118         for ( ; (pgd_idx
20 /*
21  * The "pgd_xxx()" functions here are trivial for a folded two-level
22  * setup: the pud is never bad, and a pud always exists (as it's folded
23  * into the pgd entry)
24  */
25 static inline int pgd_none(pgd_t pgd)           { return 0; }
120                         one_md_table_init(pgd);   
121                 pud = pud_offset(pgd, vaddr);
122                 pmd = pmd_offset(pud, vaddr);
123                 for (; (pmd_idx
(6)  permanent_kmaps_init  没设置pte...因为这是用来映射高端内存的.要用的时候再设置pte项
/* *为fix KMAP预留每cpu 8k的虚存,读写各4k*/
46 /*
47  * Ordering is:
48  *
49  * FIXADDR_TOP
50  *                      fixed_addresses
51  * FIXADDR_START
52  *                      temp fixed addresses
53  * FIXADDR_BOOT_START
54  *                      Persistent kmap area
55  * PKMAP_BASE
56  * VMALLOC_END
57  *                      Vmalloc area
58  * VMALLOC_START
59  * high_memory
60  */
61 #define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK )
253 static void __init permanent_kmaps_init(pgd_t *pgd_base)
254 {
255         pgd_t *pgd;
256         pud_t *pud;
257         pmd_t *pmd;
258         pte_t *pte;
259         unsigned long vaddr;
260
261         vaddr = PKMAP_BASE;
262         page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);  //还是调用上一个函数.设置好,页目录项
263
264         pgd = swapper_pg_dir + pgd_index(vaddr);
265         pud = pud_offset(pgd, vaddr);
266         pmd = pmd_offset(pud, vaddr);
267         pte = pte_offset_kernel(pmd, vaddr); //返回页表指针.
268         pkmap_page_table = pte;
269 }
41 #ifdef CONFIG_X86_PAE
42 #define LAST_PKMAP 512
43 #else
44 #define LAST_PKMAP 1024
45 #endif
所以kmap可以分配1024*4k= 4M空间.
(7)  atomic 的高端内存...
242 static void __init kmap_init(void)
243 {
244         unsigned long kmap_vstart;
245
246         /* cache the first kmap pte */
247         kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
248         kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
249
250         kmap_prot = PAGE_KERNEL;
251 }
252
(8)vmalloc的区间没有建立映射..
应该vmalloc时建立映射.








本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17526/showart_1079649.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP