init.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:14k
源码类别:

嵌入式Linux

开发平台:

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