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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/s390/mm/init.c
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Hartmut Penner (hpenner@de.ibm.com)
  7.  *
  8.  *  Derived from "arch/i386/mm/init.c"
  9.  *    Copyright (C) 1995  Linus Torvalds
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/signal.h>
  13. #include <linux/sched.h>
  14. #include <linux/kernel.h>
  15. #include <linux/errno.h>
  16. #include <linux/string.h>
  17. #include <linux/types.h>
  18. #include <linux/ptrace.h>
  19. #include <linux/mman.h>
  20. #include <linux/mm.h>
  21. #include <linux/swap.h>
  22. #include <linux/smp.h>
  23. #include <linux/init.h>
  24. #ifdef CONFIG_BLK_DEV_INITRD
  25. #include <linux/blk.h>
  26. #endif
  27. #include <linux/pagemap.h>
  28. #include <linux/bootmem.h>
  29. #include <asm/processor.h>
  30. #include <asm/system.h>
  31. #include <asm/uaccess.h>
  32. #include <asm/pgtable.h>
  33. #include <asm/pgalloc.h>
  34. #include <asm/dma.h>
  35. #include <asm/lowcore.h>
  36. #include <asm/tlb.h>
  37. mmu_gather_t mmu_gathers[NR_CPUS];
  38. static unsigned long totalram_pages;
  39. pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
  40. char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
  41. int do_check_pgt_cache(int low, int high)
  42. {
  43.         int freed = 0;
  44.         if(pgtable_cache_size > high) {
  45.                 do {
  46.                         if(pgd_quicklist) {
  47. free_pgd_slow(get_pgd_fast());
  48. freed += 4;
  49. }
  50.                         if(pmd_quicklist) {
  51. pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
  52. freed += 4;
  53. }
  54.                         if(pte_quicklist) {
  55. pte_free_slow(pte_alloc_one_fast(NULL, 0));
  56. freed += 1;
  57. }
  58.                 } while(pgtable_cache_size > low);
  59.         }
  60.         return freed;
  61. }
  62. void show_mem(void)
  63. {
  64.         int i, total = 0,reserved = 0;
  65.         int shared = 0, cached = 0;
  66.         printk("Mem-info:n");
  67.         show_free_areas();
  68.         printk("Free swap:       %6dkBn",nr_swap_pages<<(PAGE_SHIFT-10));
  69.         i = max_mapnr;
  70.         while (i-- > 0) {
  71.                 total++;
  72.                 if (PageReserved(mem_map+i))
  73.                         reserved++;
  74.                 else if (PageSwapCache(mem_map+i))
  75.                         cached++;
  76.                 else if (page_count(mem_map+i))
  77.                         shared += atomic_read(&mem_map[i].count) - 1;
  78.         }
  79.         printk("%d pages of RAMn",total);
  80.         printk("%d reserved pagesn",reserved);
  81.         printk("%d pages sharedn",shared);
  82.         printk("%d pages swap cachedn",cached);
  83.         printk("%ld pages in page table cachen",pgtable_cache_size);
  84.         show_buffers();
  85. }
  86. /* References to section boundaries */
  87. extern unsigned long _text;
  88. extern unsigned long _etext;
  89. extern unsigned long _edata;
  90. extern unsigned long __bss_start;
  91. extern unsigned long _end;
  92. extern unsigned long __init_begin;
  93. extern unsigned long __init_end;
  94. /*
  95.  * paging_init() sets up the page tables
  96.  */
  97. unsigned long last_valid_pfn;
  98. void __init paging_init(void)
  99. {
  100.         pgd_t * pg_dir;
  101. pmd_t * pm_dir;
  102.         pte_t * pt_dir;
  103.         pte_t   pte;
  104. int     i,j,k;
  105.         unsigned long address=0;
  106.         unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) |
  107.           _KERN_REGION_TABLE;
  108. unsigned long end_mem = (unsigned long) __va(max_low_pfn*PAGE_SIZE);
  109. static const int ssm_mask = 0x04000000L;
  110. unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
  111. unsigned long dma_pfn, high_pfn;
  112. dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
  113. high_pfn = max_low_pfn;
  114. if (dma_pfn > high_pfn)
  115. zones_size[ZONE_DMA] = high_pfn;
  116. else {
  117. zones_size[ZONE_DMA] = dma_pfn;
  118. zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
  119. }
  120. /* Initialize mem_map[].  */
  121. free_area_init(zones_size);
  122. /*
  123.  * map whole physical memory to virtual memory (identity mapping) 
  124.  */
  125.         pg_dir = swapper_pg_dir;
  126.         for (i = 0 ; i < PTRS_PER_PGD ; i++,pg_dir++) {
  127.                 if (address >= end_mem) {
  128.                         pgd_clear(pg_dir);
  129.                         continue;
  130.                 }          
  131.         
  132.         pm_dir = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE*4);
  133.                 pgd_populate(&init_mm, pg_dir, pm_dir);
  134.                 for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) {
  135.                         if (address >= end_mem) {
  136.                                 pmd_clear(pm_dir);
  137.                                 continue; 
  138.                         }          
  139.                         
  140.                         pt_dir = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  141.                         pmd_populate(&init_mm, pm_dir, pt_dir);
  142.                         for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) {
  143.                                 pte = mk_pte_phys(address, PAGE_KERNEL);
  144.                                 if (address >= end_mem) {
  145.                                         pte_clear(&pte); 
  146.                                         continue;
  147.                                 }
  148.                                 set_pte(pt_dir, pte);
  149.                                 address += PAGE_SIZE;
  150.                         }
  151.                 }
  152.         }
  153.         
  154.         /* enable virtual mapping in kernel mode */
  155.         __asm__ __volatile__("lctlg 1,1,%0nt"
  156.                              "lctlg 7,7,%0nt"
  157.                              "lctlg 13,13,%0nt"
  158.                              "ssm   %1"
  159.      : :"m" (pgdir_k), "m" (ssm_mask));
  160.         local_flush_tlb();
  161.         return;
  162. }
  163. void __init mem_init(void)
  164. {
  165. unsigned long codesize, reservedpages, datasize, initsize;
  166.         max_mapnr = num_physpages = max_low_pfn;
  167.         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
  168.         /* clear the zero-page */
  169.         memset(empty_zero_page, 0, PAGE_SIZE);
  170. /* this will put all low memory onto the freelists */
  171. totalram_pages += free_all_bootmem();
  172. reservedpages = 0;
  173. codesize =  (unsigned long) &_etext - (unsigned long) &_text;
  174. datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
  175. initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
  176.         printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)n",
  177.                 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
  178.                 max_mapnr << (PAGE_SHIFT-10),
  179.                 codesize >> 10,
  180.                 reservedpages << (PAGE_SHIFT-10),
  181.                 datasize >>10,
  182.                 initsize >> 10);
  183. }
  184. void free_initmem(void)
  185. {
  186.         unsigned long addr;
  187.         addr = (unsigned long)(&__init_begin);
  188.         for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
  189. ClearPageReserved(virt_to_page(addr));
  190. set_page_count(virt_to_page(addr), 1);
  191. free_page(addr);
  192. totalram_pages++;
  193.         }
  194.         printk ("Freeing unused kernel memory: %ldk freedn",
  195. (&__init_end - &__init_begin) >> 10);
  196. }
  197. #ifdef CONFIG_BLK_DEV_INITRD
  198. void free_initrd_mem(unsigned long start, unsigned long end)
  199. {
  200.         if (start < end)
  201.                 printk ("Freeing initrd memory: %ldk freedn", (end - start) >> 10);
  202. for (; start < end; start += PAGE_SIZE) {
  203.                 ClearPageReserved(virt_to_page(start));
  204.                 set_page_count(virt_to_page(start), 1);
  205. free_page(start);
  206. totalram_pages++;
  207. }
  208. }
  209. #endif
  210. void si_meminfo(struct sysinfo *val)
  211. {
  212.         val->totalram = totalram_pages;
  213. val->sharedram = 0;
  214. val->freeram = nr_free_pages();
  215. val->bufferram = atomic_read(&buffermem_pages);
  216. val->totalhigh = 0;
  217. val->freehigh = 0;
  218. val->mem_unit = PAGE_SIZE;
  219. }
  220. /*
  221.  * Overrides for Emacs so that we follow Linus's tabbing style.
  222.  * Emacs will notice this stuff at the end of the file and automatically
  223.  * adjust the settings for this buffer only.  This must remain at the end
  224.  * of the file.
  225.  * ---------------------------------------------------------------------------
  226.  * Local variables:
  227.  * c-indent-level: 4 
  228.  * c-brace-imaginary-offset: 0
  229.  * c-brace-offset: -4
  230.  * c-argdecl-indent: 4
  231.  * c-label-offset: -4
  232.  * c-continued-statement-offset: 4
  233.  * c-continued-brace-offset: 0
  234.  * indent-tabs-mode: nil
  235.  * tab-width: 8
  236.  * End:
  237.  */