📄 init.c
字号:
unsigned long last_valid_pfn;void __init paging_init(void){ switch(sparc_cpu_model) { case sun4c: case sun4e: case sun4: sun4c_paging_init(); sparc_unmapped_base = 0xe0000000; BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); break; case sun4m: case sun4d: srmmu_paging_init(); sparc_unmapped_base = 0x50000000; BTFIXUPSET_SETHI(sparc_unmapped_base, 0x50000000); break; default: prom_printf("paging_init: Cannot init paging on this Sparc\n"); prom_printf("paging_init: sparc_cpu_model = %d\n", sparc_cpu_model); prom_printf("paging_init: Halting...\n"); prom_halt(); }; /* Initialize the protection map with non-constant, MMU dependent values. */ protection_map[0] = PAGE_NONE; protection_map[1] = PAGE_READONLY; protection_map[2] = PAGE_COPY; protection_map[3] = PAGE_COPY; protection_map[4] = PAGE_READONLY; protection_map[5] = PAGE_READONLY; protection_map[6] = PAGE_COPY; protection_map[7] = PAGE_COPY; protection_map[8] = PAGE_NONE; protection_map[9] = PAGE_READONLY; protection_map[10] = PAGE_SHARED; protection_map[11] = PAGE_SHARED; protection_map[12] = PAGE_READONLY; protection_map[13] = PAGE_READONLY; protection_map[14] = PAGE_SHARED; protection_map[15] = PAGE_SHARED; btfixup(); device_scan();}struct cache_palias *sparc_aliases;static void __init taint_real_pages(void){ int i; for (i = 0; sp_banks[i].num_bytes; i++) { unsigned long start, end; start = sp_banks[i].base_addr; end = start + sp_banks[i].num_bytes; while (start < end) { set_bit (start >> 20, sparc_valid_addr_bitmap); start += PAGE_SIZE; } }}void __init free_mem_map_range(struct page *first, struct page *last){ first = (struct page *) PAGE_ALIGN((unsigned long)first); last = (struct page *) ((unsigned long)last & PAGE_MASK);#ifdef DEBUG_BOOTMEM prom_printf("[%p,%p] ", first, last);#endif while (first < last) { ClearPageReserved(virt_to_page(first)); set_page_count(virt_to_page(first), 1); free_page((unsigned long)first); totalram_pages++; num_physpages++; first = (struct page *)((unsigned long)first + PAGE_SIZE); }}/* Walk through holes in sp_banks regions, if the mem_map array * areas representing those holes consume a page or more, free * up such pages. This helps a lot on machines where physical * ram is configured such that it begins at some hugh value. * * The sp_banks array is sorted by base address. */void __init free_unused_mem_map(void){ int i;#ifdef DEBUG_BOOTMEM prom_printf("free_unused_mem_map: ");#endif for (i = 0; sp_banks[i].num_bytes; i++) { if (i == 0) { struct page *first, *last; first = mem_map; last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; free_mem_map_range(first, last); } else { struct page *first, *last; unsigned long prev_end; prev_end = sp_banks[i-1].base_addr + sp_banks[i-1].num_bytes; prev_end = PAGE_ALIGN(prev_end); first = &mem_map[prev_end >> PAGE_SHIFT]; last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; free_mem_map_range(first, last); if (!sp_banks[i+1].num_bytes) { prev_end = sp_banks[i].base_addr + sp_banks[i].num_bytes; first = &mem_map[prev_end >> PAGE_SHIFT]; last = &mem_map[last_valid_pfn]; free_mem_map_range(first, last); } } }#ifdef DEBUG_BOOTMEM prom_printf("\n");#endif}void map_high_region(unsigned long start_pfn, unsigned long end_pfn){ unsigned long tmp;#ifdef DEBUG_HIGHMEM printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn);#endif for (tmp = start_pfn; tmp < end_pfn; tmp++) { struct page *page = mem_map + tmp; ClearPageReserved(page); set_bit(PG_highmem, &page->flags); atomic_set(&page->count, 1); __free_page(page); totalhigh_pages++; }}void __init mem_init(void){ int codepages = 0; int datapages = 0; int initpages = 0; int i;#ifdef CONFIG_BLK_DEV_INITRD unsigned long addr, last;#endif highmem_start_page = mem_map + highstart_pfn; /* Saves us work later. */ memset((void *)&empty_zero_page, 0, PAGE_SIZE); i = last_valid_pfn >> (8 + 5); i += 1; sparc_valid_addr_bitmap = (unsigned long *) __alloc_bootmem(i << 2, SMP_CACHE_BYTES, 0UL); if (sparc_valid_addr_bitmap == NULL) { prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); prom_halt(); } memset(sparc_valid_addr_bitmap, 0, i << 2); taint_real_pages(); max_mapnr = last_valid_pfn; high_memory = __va(max_low_pfn << PAGE_SHIFT);#ifdef DEBUG_BOOTMEM prom_printf("mem_init: Calling free_all_bootmem().\n");#endif num_physpages = totalram_pages = free_all_bootmem();#if 0 free_unused_mem_map();#endif for (i = 0; sp_banks[i].num_bytes != 0; i++) { unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT; unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT; if (end_pfn <= highstart_pfn) continue; if (start_pfn < highstart_pfn) start_pfn = highstart_pfn; map_high_region(start_pfn, end_pfn); } totalram_pages += totalhigh_pages; codepages = (((unsigned long) &etext) - ((unsigned long)&_start)); codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; datapages = (((unsigned long) &edata) - ((unsigned long)&etext)); datapages = PAGE_ALIGN(datapages) >> PAGE_SHIFT; initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin)); initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT; printk("Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n", nr_free_pages() << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10), totalhigh_pages << (PAGE_SHIFT-10), (unsigned long)PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT)); /* NOTE NOTE NOTE NOTE * Please keep track of things and make sure this * always matches the code in mm/page_alloc.c -DaveM */ i = nr_free_pages() >> 7; if (i < 48) i = 48; if (i > 256) i = 256; freepages.min = i; freepages.low = i << 1; freepages.high = freepages.low + i;}void free_initmem (void){ unsigned long addr; addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { unsigned long page; struct page *p; page = addr + phys_base; p = virt_to_page(page); ClearPageReserved(p); set_page_count(p, 1); __free_page(p); totalram_pages++; num_physpages++; } printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);}#ifdef CONFIG_BLK_DEV_INITRDvoid free_initrd_mem(unsigned long start, unsigned long end){ if (start < end) printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { struct page *p = virt_to_page(start); ClearPageReserved(p); set_page_count(p, 1); __free_page(p); num_physpages++; }}#endifvoid si_meminfo(struct sysinfo *val){ val->totalram = totalram_pages; val->sharedram = 0; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); val->totalhigh = totalhigh_pages; val->freehigh = nr_free_highpages(); val->mem_unit = PAGE_SIZE;}void flush_page_to_ram(struct page *page){ unsigned long vaddr = (unsigned long)page_address(page); if (vaddr) __flush_page_to_ram(vaddr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -