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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/i386/mm/init.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  *
  6.  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  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. #ifdef CONFIG_BLK_DEV_INITRD
  22. #include <linux/blk.h>
  23. #endif
  24. #include <linux/highmem.h>
  25. #include <linux/pagemap.h>
  26. #include <linux/bootmem.h>
  27. #include <linux/slab.h>
  28. #include <asm/processor.h>
  29. #include <asm/system.h>
  30. #include <asm/uaccess.h>
  31. #include <asm/pgtable.h>
  32. #include <asm/pgalloc.h>
  33. #include <asm/dma.h>
  34. #include <asm/fixmap.h>
  35. #include <asm/e820.h>
  36. #include <asm/apic.h>
  37. #include <asm/tlb.h>
  38. mmu_gather_t mmu_gathers[NR_CPUS];
  39. unsigned long highstart_pfn, highend_pfn;
  40. static unsigned long totalram_pages;
  41. static unsigned long totalhigh_pages;
  42. int do_check_pgt_cache(int low, int high)
  43. {
  44. int freed = 0;
  45. if(pgtable_cache_size > high) {
  46. do {
  47. if (pgd_quicklist) {
  48. free_pgd_slow(get_pgd_fast());
  49. freed++;
  50. }
  51. if (pmd_quicklist) {
  52. pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
  53. freed++;
  54. }
  55. if (pte_quicklist) {
  56. pte_free_slow(pte_alloc_one_fast(NULL, 0));
  57. freed++;
  58. }
  59. } while(pgtable_cache_size > low);
  60. }
  61. return freed;
  62. }
  63. /*
  64.  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
  65.  * physical space so we can cache the place of the first one and move
  66.  * around without checking the pgd every time.
  67.  */
  68. #if CONFIG_HIGHMEM
  69. pte_t *kmap_pte;
  70. pgprot_t kmap_prot;
  71. #define kmap_get_fixmap_pte(vaddr)
  72. pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
  73. void __init kmap_init(void)
  74. {
  75. unsigned long kmap_vstart;
  76. /* cache the first kmap pte */
  77. kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
  78. kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
  79. kmap_prot = PAGE_KERNEL;
  80. }
  81. #endif /* CONFIG_HIGHMEM */
  82. void show_mem(void)
  83. {
  84. int i, total = 0, reserved = 0;
  85. int shared = 0, cached = 0;
  86. int highmem = 0;
  87. printk("Mem-info:n");
  88. show_free_areas();
  89. printk("Free swap:       %6dkBn",nr_swap_pages<<(PAGE_SHIFT-10));
  90. i = max_mapnr;
  91. while (i-- > 0) {
  92. total++;
  93. if (PageHighMem(mem_map+i))
  94. highmem++;
  95. if (PageReserved(mem_map+i))
  96. reserved++;
  97. else if (PageSwapCache(mem_map+i))
  98. cached++;
  99. else if (page_count(mem_map+i))
  100. shared += page_count(mem_map+i) - 1;
  101. }
  102. printk("%d pages of RAMn", total);
  103. printk("%d pages of HIGHMEMn",highmem);
  104. printk("%d reserved pagesn",reserved);
  105. printk("%d pages sharedn",shared);
  106. printk("%d pages swap cachedn",cached);
  107. printk("%ld pages in page table cachen",pgtable_cache_size);
  108. show_buffers();
  109. }
  110. /* References to section boundaries */
  111. extern char _text, _etext, _edata, __bss_start, _end;
  112. extern char __init_begin, __init_end;
  113. static inline void set_pte_phys (unsigned long vaddr,
  114. unsigned long phys, pgprot_t flags)
  115. {
  116. pgd_t *pgd;
  117. pmd_t *pmd;
  118. pte_t *pte;
  119. pgd = swapper_pg_dir + __pgd_offset(vaddr);
  120. if (pgd_none(*pgd)) {
  121. printk("PAE BUG #00!n");
  122. return;
  123. }
  124. pmd = pmd_offset(pgd, vaddr);
  125. if (pmd_none(*pmd)) {
  126. printk("PAE BUG #01!n");
  127. return;
  128. }
  129. pte = pte_offset(pmd, vaddr);
  130. /* <phys,flags> stored as-is, to permit clearing entries */
  131. set_pte(pte, mk_pte_phys(phys, flags));
  132. /*
  133.  * It's enough to flush this one mapping.
  134.  * (PGE mappings get flushed as well)
  135.  */
  136. __flush_tlb_one(vaddr);
  137. }
  138. void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
  139. {
  140. unsigned long address = __fix_to_virt(idx);
  141. if (idx >= __end_of_fixed_addresses) {
  142. printk("Invalid __set_fixmapn");
  143. return;
  144. }
  145. set_pte_phys(address, phys, flags);
  146. }
  147. static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
  148. {
  149. pgd_t *pgd;
  150. pmd_t *pmd;
  151. pte_t *pte;
  152. int i, j;
  153. unsigned long vaddr;
  154. vaddr = start;
  155. i = __pgd_offset(vaddr);
  156. j = __pmd_offset(vaddr);
  157. pgd = pgd_base + i;
  158. for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
  159. #if CONFIG_X86_PAE
  160. if (pgd_none(*pgd)) {
  161. pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  162. set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
  163. if (pmd != pmd_offset(pgd, 0))
  164. printk("PAE BUG #02!n");
  165. }
  166. pmd = pmd_offset(pgd, vaddr);
  167. #else
  168. pmd = (pmd_t *)pgd;
  169. #endif
  170. for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
  171. if (pmd_none(*pmd)) {
  172. pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  173. set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
  174. if (pte != pte_offset(pmd, 0))
  175. BUG();
  176. }
  177. vaddr += PMD_SIZE;
  178. }
  179. j = 0;
  180. }
  181. }
  182. static void __init pagetable_init (void)
  183. {
  184. unsigned long vaddr, end;
  185. pgd_t *pgd, *pgd_base;
  186. int i, j, k;
  187. pmd_t *pmd;
  188. pte_t *pte, *pte_base;
  189. /*
  190.  * This can be zero as well - no problem, in that case we exit
  191.  * the loops anyway due to the PTRS_PER_* conditions.
  192.  */
  193. end = (unsigned long)__va(max_low_pfn*PAGE_SIZE);
  194. pgd_base = swapper_pg_dir;
  195. #if CONFIG_X86_PAE
  196. for (i = 0; i < PTRS_PER_PGD; i++)
  197. set_pgd(pgd_base + i, __pgd(1 + __pa(empty_zero_page)));
  198. #endif
  199. i = __pgd_offset(PAGE_OFFSET);
  200. pgd = pgd_base + i;
  201. for (; i < PTRS_PER_PGD; pgd++, i++) {
  202. vaddr = i*PGDIR_SIZE;
  203. if (end && (vaddr >= end))
  204. break;
  205. #if CONFIG_X86_PAE
  206. pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  207. set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
  208. #else
  209. pmd = (pmd_t *)pgd;
  210. #endif
  211. if (pmd != pmd_offset(pgd, 0))
  212. BUG();
  213. for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
  214. vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
  215. if (end && (vaddr >= end))
  216. break;
  217. if (cpu_has_pse) {
  218. unsigned long __pe;
  219. set_in_cr4(X86_CR4_PSE);
  220. boot_cpu_data.wp_works_ok = 1;
  221. __pe = _KERNPG_TABLE + _PAGE_PSE + __pa(vaddr);
  222. /* Make it "global" too if supported */
  223. if (cpu_has_pge) {
  224. set_in_cr4(X86_CR4_PGE);
  225. __pe += _PAGE_GLOBAL;
  226. }
  227. set_pmd(pmd, __pmd(__pe));
  228. continue;
  229. }
  230. pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  231. for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
  232. vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
  233. if (end && (vaddr >= end))
  234. break;
  235. *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
  236. }
  237. set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
  238. if (pte_base != pte_offset(pmd, 0))
  239. BUG();
  240. }
  241. }
  242. /*
  243.  * Fixed mappings, only the page table structure has to be
  244.  * created - mappings will be set by set_fixmap():
  245.  */
  246. vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
  247. fixrange_init(vaddr, 0, pgd_base);
  248. #if CONFIG_HIGHMEM
  249. /*
  250.  * Permanent kmaps:
  251.  */
  252. vaddr = PKMAP_BASE;
  253. fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
  254. pgd = swapper_pg_dir + __pgd_offset(vaddr);
  255. pmd = pmd_offset(pgd, vaddr);
  256. pte = pte_offset(pmd, vaddr);
  257. pkmap_page_table = pte;
  258. #endif
  259. #if CONFIG_X86_PAE
  260. /*
  261.  * Add low memory identity-mappings - SMP needs it when
  262.  * starting up on an AP from real-mode. In the non-PAE
  263.  * case we already have these mappings through head.S.
  264.  * All user-space mappings are explicitly cleared after
  265.  * SMP startup.
  266.  */
  267. pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
  268. #endif
  269. }
  270. void __init zap_low_mappings (void)
  271. {
  272. int i;
  273. /*
  274.  * Zap initial low-memory mappings.
  275.  *
  276.  * Note that "pgd_clear()" doesn't do it for
  277.  * us, because pgd_clear() is a no-op on i386.
  278.  */
  279. for (i = 0; i < USER_PTRS_PER_PGD; i++)
  280. #if CONFIG_X86_PAE
  281. set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
  282. #else
  283. set_pgd(swapper_pg_dir+i, __pgd(0));
  284. #endif
  285. flush_tlb_all();
  286. }
  287. static void __init zone_sizes_init(void)
  288. {
  289. unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
  290. unsigned int max_dma, high, low;
  291. max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
  292. low = max_low_pfn;
  293. high = highend_pfn;
  294. if (low < max_dma)
  295. zones_size[ZONE_DMA] = low;
  296. else {
  297. zones_size[ZONE_DMA] = max_dma;
  298. zones_size[ZONE_NORMAL] = low - max_dma;
  299. #ifdef CONFIG_HIGHMEM
  300. zones_size[ZONE_HIGHMEM] = high - low;
  301. #endif
  302. }
  303. free_area_init(zones_size);
  304. }
  305. /*
  306.  * paging_init() sets up the page tables - note that the first 8MB are
  307.  * already mapped by head.S.
  308.  *
  309.  * This routines also unmaps the page at virtual kernel address 0, so
  310.  * that we can trap those pesky NULL-reference errors in the kernel.
  311.  */
  312. void __init paging_init(void)
  313. {
  314. pagetable_init();
  315. load_cr3(swapper_pg_dir);
  316. #if CONFIG_X86_PAE
  317. /*
  318.  * We will bail out later - printk doesnt work right now so
  319.  * the user would just see a hanging kernel.
  320.  */
  321. if (cpu_has_pae)
  322. set_in_cr4(X86_CR4_PAE);
  323. #endif
  324. __flush_tlb_all();
  325. #ifdef CONFIG_HIGHMEM
  326. kmap_init();
  327. #endif
  328. zone_sizes_init();
  329. }
  330. /*
  331.  * Test if the WP bit works in supervisor mode. It isn't supported on 386's
  332.  * and also on some strange 486's (NexGen etc.). All 586+'s are OK. The jumps
  333.  * before and after the test are here to work-around some nasty CPU bugs.
  334.  */
  335. /*
  336.  * This function cannot be __init, since exceptions don't work in that
  337.  * section.
  338.  */
  339. static int do_test_wp_bit(unsigned long vaddr);
  340. void __init test_wp_bit(void)
  341. {
  342. /*
  343.  * Ok, all PSE-capable CPUs are definitely handling the WP bit right.
  344.  */
  345. const unsigned long vaddr = PAGE_OFFSET;
  346. pgd_t *pgd;
  347. pmd_t *pmd;
  348. pte_t *pte, old_pte;
  349. printk("Checking if this processor honours the WP bit even in supervisor mode... ");
  350. pgd = swapper_pg_dir + __pgd_offset(vaddr);
  351. pmd = pmd_offset(pgd, vaddr);
  352. pte = pte_offset(pmd, vaddr);
  353. old_pte = *pte;
  354. *pte = mk_pte_phys(0, PAGE_READONLY);
  355. local_flush_tlb();
  356. boot_cpu_data.wp_works_ok = do_test_wp_bit(vaddr);
  357. *pte = old_pte;
  358. local_flush_tlb();
  359. if (!boot_cpu_data.wp_works_ok) {
  360. printk("No.n");
  361. #ifdef CONFIG_X86_WP_WORKS_OK
  362. panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");
  363. #endif
  364. } else {
  365. printk("Ok.n");
  366. }
  367. }
  368. static inline int page_is_ram (unsigned long pagenr)
  369. {
  370. int i;
  371. for (i = 0; i < e820.nr_map; i++) {
  372. unsigned long addr, end;
  373. if (e820.map[i].type != E820_RAM) /* not usable memory */
  374. continue;
  375. /*
  376.  * !!!FIXME!!! Some BIOSen report areas as RAM that
  377.  * are not. Notably the 640->1Mb area. We need a sanity
  378.  * check here.
  379.  */
  380. addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
  381. end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
  382. if  ((pagenr >= addr) && (pagenr < end))
  383. return 1;
  384. }
  385. return 0;
  386. }
  387. static inline int page_kills_ppro(unsigned long pagenr)
  388. {
  389. if(pagenr >= 0x70000 && pagenr <= 0x7003F)
  390. return 1;
  391. return 0;
  392. }
  393. #ifdef CONFIG_HIGHMEM
  394. void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
  395. {
  396. if (!page_is_ram(pfn)) {
  397. SetPageReserved(page);
  398. return;
  399. }
  400. if (bad_ppro && page_kills_ppro(pfn)) {
  401. SetPageReserved(page);
  402. return;
  403. }
  404. ClearPageReserved(page);
  405. set_bit(PG_highmem, &page->flags);
  406. atomic_set(&page->count, 1);
  407. __free_page(page);
  408. totalhigh_pages++;
  409. }
  410. #endif /* CONFIG_HIGHMEM */
  411. static void __init set_max_mapnr_init(void)
  412. {
  413. #ifdef CONFIG_HIGHMEM
  414.         highmem_start_page = mem_map + highstart_pfn;
  415.         max_mapnr = num_physpages = highend_pfn;
  416.         num_mappedpages = max_low_pfn;
  417. #else
  418.         max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
  419. #endif
  420. }
  421. static int __init free_pages_init(void)
  422. {
  423. extern int ppro_with_ram_bug(void);
  424. int bad_ppro, reservedpages, pfn;
  425. bad_ppro = ppro_with_ram_bug();
  426. /* this will put all low memory onto the freelists */
  427. totalram_pages += free_all_bootmem();
  428. reservedpages = 0;
  429. for (pfn = 0; pfn < max_low_pfn; pfn++) {
  430. /*
  431.  * Only count reserved RAM pages
  432.  */
  433. if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
  434. reservedpages++;
  435. }
  436. #ifdef CONFIG_HIGHMEM
  437. for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
  438. one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
  439. totalram_pages += totalhigh_pages;
  440. #endif
  441. return reservedpages;
  442. }
  443. void __init mem_init(void)
  444. {
  445. int codesize, reservedpages, datasize, initsize;
  446. if (!mem_map)
  447. BUG();
  448. set_max_mapnr_init();
  449. high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
  450. /* clear the zero-page */
  451. memset(empty_zero_page, 0, PAGE_SIZE);
  452. reservedpages = free_pages_init();
  453. codesize =  (unsigned long) &_etext - (unsigned long) &_text;
  454. datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
  455. initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
  456. printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)n",
  457. (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
  458. max_mapnr << (PAGE_SHIFT-10),
  459. codesize >> 10,
  460. reservedpages << (PAGE_SHIFT-10),
  461. datasize >> 10,
  462. initsize >> 10,
  463. (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
  464.        );
  465. #if CONFIG_X86_PAE
  466. if (!cpu_has_pae)
  467. panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
  468. #endif
  469. if (boot_cpu_data.wp_works_ok < 0)
  470. test_wp_bit();
  471. /*
  472.  * Subtle. SMP is doing it's boot stuff late (because it has to
  473.  * fork idle threads) - but it also needs low mappings for the
  474.  * protected-mode entry to work. We zap these entries only after
  475.  * the WP-bit has been tested.
  476.  */
  477. #ifndef CONFIG_SMP
  478. zap_low_mappings();
  479. #endif
  480. }
  481. /* Put this after the callers, so that it cannot be inlined */
  482. static int do_test_wp_bit(unsigned long vaddr)
  483. {
  484. char tmp_reg;
  485. int flag;
  486. __asm__ __volatile__(
  487. " movb %0,%1 n"
  488. "1: movb %1,%0 n"
  489. " xorl %2,%2 n"
  490. "2: n"
  491. ".section __ex_table,"a"n"
  492. " .align 4 n"
  493. " .long 1b,2b n"
  494. ".previous n"
  495. :"=m" (*(char *) vaddr),
  496.  "=q" (tmp_reg),
  497.  "=r" (flag)
  498. :"2" (1)
  499. :"memory");
  500. return flag;
  501. }
  502. void free_initmem(void)
  503. {
  504. unsigned long addr;
  505. addr = (unsigned long)(&__init_begin);
  506. for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
  507. ClearPageReserved(virt_to_page(addr));
  508. set_page_count(virt_to_page(addr), 1);
  509. free_page(addr);
  510. totalram_pages++;
  511. }
  512. printk (KERN_INFO "Freeing unused kernel memory: %dk freedn", (&__init_end - &__init_begin) >> 10);
  513. }
  514. #ifdef CONFIG_BLK_DEV_INITRD
  515. void free_initrd_mem(unsigned long start, unsigned long end)
  516. {
  517. if (start < end)
  518. printk (KERN_INFO "Freeing initrd memory: %ldk freedn", (end - start) >> 10);
  519. for (; start < end; start += PAGE_SIZE) {
  520. ClearPageReserved(virt_to_page(start));
  521. set_page_count(virt_to_page(start), 1);
  522. free_page(start);
  523. totalram_pages++;
  524. }
  525. }
  526. #endif
  527. void si_meminfo(struct sysinfo *val)
  528. {
  529. val->totalram = totalram_pages;
  530. val->sharedram = 0;
  531. val->freeram = nr_free_pages();
  532. val->bufferram = atomic_read(&buffermem_pages);
  533. val->totalhigh = totalhigh_pages;
  534. val->freehigh = nr_free_highpages();
  535. val->mem_unit = PAGE_SIZE;
  536. return;
  537. }
  538. #if defined(CONFIG_X86_PAE)
  539. struct kmem_cache_s *pae_pgd_cachep;
  540. void __init pgtable_cache_init(void)
  541. {
  542. /*
  543.  * PAE pgds must be 16-byte aligned:
  544.  */
  545. pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
  546. SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
  547. if (!pae_pgd_cachep)
  548. panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
  549. }
  550. #endif /* CONFIG_X86_PAE */