init.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/x86_64/mm/init.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
  6.  *  Copyright (C) 2002  Andi Kleen <ak@suse.de>
  7.  */
  8. #include <linux/config.h>
  9. #include <linux/signal.h>
  10. #include <linux/sched.h>
  11. #include <linux/kernel.h>
  12. #include <linux/errno.h>
  13. #include <linux/string.h>
  14. #include <linux/types.h>
  15. #include <linux/ptrace.h>
  16. #include <linux/mman.h>
  17. #include <linux/mm.h>
  18. #include <linux/swap.h>
  19. #include <linux/smp.h>
  20. #include <linux/init.h>
  21. #include <linux/blk.h>
  22. #include <linux/pagemap.h>
  23. #include <linux/bootmem.h>
  24. #include <asm/processor.h>
  25. #include <asm/system.h>
  26. #include <asm/uaccess.h>
  27. #include <asm/pgtable.h>
  28. #include <asm/pgalloc.h>
  29. #include <asm/dma.h>
  30. #include <asm/fixmap.h>
  31. #include <asm/e820.h>
  32. #include <asm/apic.h>
  33. #include <asm/tlb.h>
  34. #include <asm/pda.h>
  35. #include <asm/mmu_context.h>
  36. #include <asm/proto.h>
  37. mmu_gather_t mmu_gathers[NR_CPUS];
  38. static unsigned long totalram_pages;
  39. int do_check_pgt_cache(int low, int high)
  40. {
  41. int freed = 0;
  42. if(read_pda(pgtable_cache_sz) > high) {
  43. do {
  44. if (read_pda(pgd_quick)) {
  45. pgd_free_slow(pgd_alloc_one_fast());
  46. freed++;
  47. }
  48. if (read_pda(pmd_quick)) {
  49. pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
  50. freed++;
  51. }
  52. if (read_pda(pte_quick)) {
  53. pte_free_slow(pte_alloc_one_fast(NULL, 0));
  54. freed++;
  55. }
  56. } while(read_pda(pgtable_cache_sz) > low);
  57. }
  58. return freed;
  59. }
  60. #ifndef CONFIG_DISCONTIGMEM
  61. /*
  62.  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
  63.  * physical space so we can cache the place of the first one and move
  64.  * around without checking the pgd every time.
  65.  */
  66. void show_mem(void)
  67. {
  68. int i, total = 0, reserved = 0;
  69. int shared = 0, cached = 0;
  70. printk("Mem-info:n");
  71. show_free_areas();
  72. printk("Free swap:       %6dkBn",nr_swap_pages<<(PAGE_SHIFT-10));
  73. i = max_mapnr;
  74. while (i-- > 0) {
  75. total++;
  76. if (PageReserved(mem_map+i))
  77. reserved++;
  78. else if (PageSwapCache(mem_map+i))
  79. cached++;
  80. else if (page_count(mem_map+i))
  81. shared += page_count(mem_map+i) - 1;
  82. }
  83. printk("%d pages of RAMn", total);
  84. printk("%d reserved pagesn",reserved);
  85. printk("%d pages sharedn",shared);
  86. printk("%d pages swap cachedn",cached);
  87. printk("%ld pages in page table cachen",read_pda(pgtable_cache_sz));
  88. show_buffers();
  89. }
  90. #endif
  91. /* References to section boundaries */
  92. extern char _text, _etext, _edata, __bss_start, _end;
  93. extern char __init_begin, __init_end;
  94. int after_bootmem;
  95. static void *spp_getpage(void)
  96. void *ptr;
  97. if (after_bootmem)
  98. ptr = (void *) get_free_page(GFP_ATOMIC); 
  99. else
  100. ptr = alloc_bootmem_low_pages(PAGE_SIZE); 
  101. if (!ptr)
  102. panic("set_pte_phys: cannot allocate page data %sn", after_bootmem?"after bootmem":"");
  103. return ptr;
  104. static void set_pte_phys(unsigned long vaddr,
  105.  unsigned long phys, pgprot_t prot)
  106. {
  107. pml4_t *level4;
  108. pgd_t *pgd;
  109. pmd_t *pmd;
  110. pte_t *pte;
  111. level4 = pml4_offset_k(vaddr);
  112. if (pml4_none(*level4)) {
  113. printk("PML4 FIXMAP MISSING, it should be setup in head.S!n");
  114. return;
  115. }
  116. pgd = level3_offset_k(level4, vaddr);
  117. if (pgd_none(*pgd)) {
  118. pmd = (pmd_t *) spp_getpage(); 
  119. set_pgd(pgd, __pgd(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
  120. if (pmd != pmd_offset(pgd, 0)) {
  121. printk("PAGETABLE BUG #01!n");
  122. return;
  123. }
  124. }
  125. pmd = pmd_offset(pgd, vaddr);
  126. if (pmd_none(*pmd)) {
  127. pte = (pte_t *) spp_getpage();
  128. set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
  129. if (pte != pte_offset(pmd, 0)) {
  130. printk("PAGETABLE BUG #02!n");
  131. return;
  132. }
  133. }
  134. pte = pte_offset(pmd, vaddr);
  135. set_pte(pte, mk_pte_phys(phys, prot));
  136. /*
  137.  * It's enough to flush this one mapping.
  138.  * (PGE mappings get flushed as well)
  139.  */
  140. __flush_tlb_one(vaddr);
  141. }
  142. void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
  143. {
  144. unsigned long address = __fix_to_virt(idx);
  145. if (idx >= __end_of_fixed_addresses) {
  146. printk("Invalid __set_fixmapn");
  147. return;
  148. }
  149. set_pte_phys(address, phys, prot);
  150. }
  151. extern pmd_t temp_boot_pmds[]; 
  152. unsigned long __initdata table_start, table_end; 
  153. static  struct temp_map { 
  154. pmd_t *pmd; 
  155. void  *address; 
  156. int    allocated; 
  157. } temp_mappings[] __initdata = { 
  158. { &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) },
  159. { &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, 
  160. {}
  161. }; 
  162. static __init void *alloc_low_page(int *index, unsigned long *phys) 
  163. struct temp_map *ti;
  164. int i; 
  165. unsigned long pfn = table_end++, paddr; 
  166. void *adr;
  167. if (table_end >= end_pfn) 
  168. panic("alloc_low_page: ran out of page mappings"); 
  169. for (i = 0; temp_mappings[i].allocated; i++) {
  170. if (!temp_mappings[i].pmd) 
  171. panic("alloc_low_page: ran out of temp mappings"); 
  172. ti = &temp_mappings[i];
  173. paddr = (pfn << PAGE_SHIFT) & PMD_MASK; 
  174. set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); 
  175. ti->allocated = 1; 
  176. __flush_tlb();         
  177. adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); 
  178. *index = i; 
  179. *phys  = pfn * PAGE_SIZE;  
  180. return adr; 
  181. static __init void unmap_low_page(int i)
  182. struct temp_map *ti = &temp_mappings[i];
  183. set_pmd(ti->pmd, __pmd(0));
  184. ti->allocated = 0; 
  185. static void __init phys_pgd_init(pgd_t *pgd, unsigned long address, unsigned long end)
  186. long i, j; 
  187. i = pgd_index(address);
  188. pgd = pgd + i;
  189. for (; i < PTRS_PER_PGD; pgd++, i++) {
  190. int map; 
  191. unsigned long paddr, pmd_phys;
  192. pmd_t *pmd;
  193. paddr = (address & PML4_MASK) + i*PGDIR_SIZE; 
  194. if (paddr >= end) { 
  195. for (; i < PTRS_PER_PGD; i++, pgd++) 
  196. set_pgd(pgd, __pgd(0)); 
  197. break;
  198. if (!e820_mapped(paddr, paddr+PGDIR_SIZE, 0)) { 
  199. set_pgd(pgd, __pgd(0)); 
  200. continue;
  201. pmd = alloc_low_page(&map, &pmd_phys);
  202. set_pgd(pgd, __pgd(pmd_phys | _KERNPG_TABLE));
  203. for (j = 0; j < PTRS_PER_PMD; pmd++, j++ , paddr += PMD_SIZE) {
  204. unsigned long pe;
  205. if (paddr >= end) { 
  206. for (; j < PTRS_PER_PMD; j++, pmd++)
  207. set_pmd(pmd,  __pmd(0)); 
  208. break;
  209. }
  210. pe = _PAGE_PSE | _KERNPG_TABLE | _PAGE_GLOBAL | paddr;
  211. set_pmd(pmd, __pmd(pe));
  212. }
  213. unmap_low_page(map);
  214. }
  215. __flush_tlb();
  216. /* Setup the direct mapping of the physical memory at PAGE_OFFSET.
  217.    This runs before bootmem is initialized and gets pages directly from the 
  218.    physical memory. To access them they are temporarily mapped. */
  219. void __init init_memory_mapping(void) 
  220. unsigned long adr;        
  221. unsigned long end;
  222. unsigned long next; 
  223. unsigned long pgds, pmds, tables; 
  224. end = end_pfn << PAGE_SHIFT; 
  225. /* 
  226.  * Find space for the kernel direct mapping tables.
  227.  * Later we should allocate these tables in the local node of the memory
  228.  * mapped.  Unfortunately this is done currently before the nodes are 
  229.  * discovered.
  230.  */
  231. pgds = (end + PGDIR_SIZE - 1) >> PGDIR_SHIFT;
  232. pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; 
  233. tables = round_up(pgds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE); 
  234. /* Direct mapping must currently fit below the kernel in the first MB.
  235.    This is because we have no way to tell the later passes to not reuse
  236.    the memory, until bootmem is initialised */
  237. /* Should limit MAXMEM for this */
  238. table_start = find_e820_area(/*0*/ 0x8000, __pa_symbol(&_text), tables); 
  239. if (table_start == -1UL) 
  240. panic("Cannot find space for the kernel page tables"); 
  241. table_start >>= PAGE_SHIFT; 
  242. table_end = table_start;
  243.        
  244. end += __PAGE_OFFSET; /* turn virtual */  
  245. for (adr = PAGE_OFFSET; adr < end; adr = next) { 
  246. int map;
  247. unsigned long pgd_phys; 
  248. pgd_t *pgd = alloc_low_page(&map, &pgd_phys);
  249. next = adr + PML4_SIZE;
  250. if (next > end) 
  251. next = end; 
  252. phys_pgd_init(pgd, adr-PAGE_OFFSET, next-PAGE_OFFSET); 
  253. set_pml4(init_level4_pgt + pml4_index(adr), 
  254.  mk_kernel_pml4(pgd_phys, KERNPG_TABLE));
  255. unmap_low_page(map);   
  256. asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
  257. __flush_tlb_all();
  258. printk("kernel direct mapping tables upto %lx @ %lx-%lxn", end, 
  259.        table_start<<PAGE_SHIFT, 
  260.        table_end<<PAGE_SHIFT);
  261. void __init zap_low_mappings (void)
  262. {
  263. int i;
  264. for (i = 0; i < NR_CPUS; i++) {
  265. if (cpu_pda[i].level4_pgt) 
  266. cpu_pda[i].level4_pgt[0] = 0; 
  267. }
  268. flush_tlb_all();
  269. }
  270. #ifndef CONFIG_DISCONTIGMEM
  271. void __init paging_init(void)
  272. {
  273. unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
  274. unsigned int max_dma;
  275. max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
  276. if (end_pfn < max_dma)
  277. zones_size[ZONE_DMA] = end_pfn;
  278. else {
  279. zones_size[ZONE_DMA] = max_dma;
  280. zones_size[ZONE_NORMAL] = end_pfn - max_dma;
  281. }
  282. free_area_init(zones_size);
  283. }
  284. static inline int page_is_ram (unsigned long pagenr)
  285. {
  286. int i;
  287. for (i = 0; i < e820.nr_map; i++) {
  288. unsigned long addr, end;
  289. if (e820.map[i].type != E820_RAM) /* not usable memory */
  290. continue;
  291. /*
  292.  * !!!FIXME!!! Some BIOSen report areas as RAM that
  293.  * are not. Notably the 640->1Mb area. We need a sanity
  294.  * check here.
  295.  */
  296. addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
  297. end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
  298. if  ((pagenr >= addr) && (pagenr < end))
  299. return 1;
  300. }
  301. return 0;
  302. }
  303. #endif
  304. void __init mem_init(void)
  305. {
  306. unsigned long codesize, reservedpages, datasize, initsize;
  307. unsigned long tmp;
  308. max_mapnr = end_pfn; 
  309. num_physpages = end_pfn; /* XXX not true because of holes */
  310. high_memory = (void *) __va(end_pfn << PAGE_SHIFT);
  311. /* clear the zero-page */
  312. memset(empty_zero_page, 0, PAGE_SIZE);
  313. reservedpages = 0;
  314. /* this will put all low memory onto the freelists */
  315. #ifdef CONFIG_DISCONTIGMEM
  316. totalram_pages += numa_free_all_bootmem();
  317. tmp = 0;
  318. /* should count reserved pages here for all nodes */ 
  319. #else
  320. if (!mem_map) BUG();
  321. totalram_pages += free_all_bootmem();
  322. for (tmp = 0; tmp < end_pfn; tmp++)
  323. /*
  324.  * Only count reserved RAM pages
  325.  */
  326. if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
  327. reservedpages++;
  328. #endif
  329. after_bootmem = 1;
  330. codesize =  (unsigned long) &_etext - (unsigned long) &_text;
  331. datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
  332. initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
  333. printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)n",
  334. (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
  335. max_mapnr << (PAGE_SHIFT-10),
  336. codesize >> 10,
  337. reservedpages << (PAGE_SHIFT-10),
  338. datasize >> 10,
  339. initsize >> 10);
  340. /*
  341.  * Subtle. SMP is doing its boot stuff late (because it has to
  342.  * fork idle threads) - but it also needs low mappings for the
  343.  * protected-mode entry to work. We zap these entries only after
  344.  * the WP-bit has been tested.
  345.  */
  346. #ifndef CONFIG_SMP
  347. zap_low_mappings();
  348. #endif
  349. }
  350. void __init __map_kernel_range(void *address, int len, pgprot_t prot) 
  351. int i;
  352. void *end = address + len;
  353. BUG_ON((pgprot_val(prot) & _PAGE_PSE) == 0);
  354. address = (void *)((unsigned long)address & LARGE_PAGE_MASK); 
  355. for (; address < end; address += LARGE_PAGE_SIZE) { 
  356. pml4_t *pml4;
  357. pgd_t *pgd;
  358. pmd_t *pmd;
  359. pml4 = pml4_offset_k((unsigned long) address); 
  360. if (pml4_none(*pml4)) { 
  361. void *p = (void *)get_zeroed_page(GFP_KERNEL); 
  362. if (!p) panic("Cannot map kernel range"); 
  363. for (i = 0; i < smp_num_cpus; i++) {
  364. set_pml4((pml4_t *)(cpu_pda[i].level4_pgt) + 
  365.  pml4_index((unsigned long)address),
  366.  mk_kernel_pml4(virt_to_phys(p),KERNPG_TABLE));
  367. }
  368. pgd = pgd_offset_k((unsigned long)address); 
  369. if (pgd_none(*pgd)) { 
  370. void *p = (void *)get_zeroed_page(GFP_KERNEL); 
  371. if (!p) panic("Cannot map kernel range"); 
  372. set_pgd(pgd, __mk_pgd(virt_to_phys(p), KERNPG_TABLE));
  373. pmd = pmd_offset(pgd, (unsigned long) address); 
  374. set_pmd(pmd, __mk_pmd(virt_to_phys(address), prot));
  375. __flush_tlb_all(); 
  376. void free_initmem(void)
  377. {
  378. void *addr;
  379. addr = (&__init_begin);
  380. for (; addr < (void *)(&__init_end); addr += PAGE_SIZE) {
  381. ClearPageReserved(virt_to_page(addr));
  382. set_page_count(virt_to_page(addr), 1);
  383. #ifdef CONFIG_INIT_DEBUG
  384. memset((unsigned long)addr & ~(PAGE_SIZE-1), 0xcc, PAGE_SIZE); 
  385. #endif
  386. free_page((unsigned long)addr);
  387. totalram_pages++;
  388. }
  389. printk ("Freeing unused kernel memory: %luk freedn", (&__init_end - &__init_begin) >> 10);
  390. }
  391. #ifdef CONFIG_BLK_DEV_INITRD
  392. void free_initrd_mem(unsigned long start, unsigned long end)
  393. {
  394. if (start < (unsigned long)&_end)
  395. return;
  396. printk ("Freeing initrd memory: %ldk freedn", (end - start) >> 10);
  397. for (; start < end; start += PAGE_SIZE) {
  398. ClearPageReserved(virt_to_page(start));
  399. set_page_count(virt_to_page(start), 1);
  400. free_page(start);
  401. totalram_pages++;
  402. }
  403. }
  404. #endif
  405. void si_meminfo(struct sysinfo *val)
  406. {
  407. val->totalram = totalram_pages;
  408. val->sharedram = 0;
  409. val->freeram = nr_free_pages();
  410. val->bufferram = atomic_read(&buffermem_pages);
  411. val->totalhigh = 0;
  412. val->freehigh = nr_free_highpages();
  413. val->mem_unit = PAGE_SIZE;
  414. return;
  415. }
  416. void reserve_bootmem_generic(unsigned long phys, unsigned len) 
  417. /* Should check here against the e820 map to avoid double free */ 
  418. #ifdef CONFIG_DISCONTIGMEM
  419. reserve_bootmem_node(NODE_DATA(phys_to_nid(phys)), phys, len);
  420. #else       
  421. reserve_bootmem(phys, len);    
  422. #endif
  423. }
  424. void free_bootmem_generic(unsigned long phys, unsigned len) 
  425. #ifdef CONFIG_DISCONTIGMEM
  426. free_bootmem_node(NODE_DATA(phys_to_nid(phys)), phys, len);
  427. #else       
  428. free_bootmem(phys, len);    
  429. #endif
  430. }