⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * Add low memory identity-mappings - SMP needs it when	 * starting up on an AP from real-mode. In the non-PAE	 * case we already have these mappings through head.S.	 * All user-space mappings are explicitly cleared after	 * SMP startup.	 */	set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);#endif}#ifdef CONFIG_SOFTWARE_SUSPEND/* * Swap suspend & friends need this for resume because things like the intel-agp * driver might have split up a kernel 4MB mapping. */char __nosavedata swsusp_pg_dir[PAGE_SIZE]	__attribute__ ((aligned (PAGE_SIZE)));static inline void save_pg_dir(void){	memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);}#elsestatic inline void save_pg_dir(void){}#endifvoid zap_low_mappings (void){	int i;	save_pg_dir();	/*	 * Zap initial low-memory mappings.	 *	 * Note that "pgd_clear()" doesn't do it for	 * us, because pgd_clear() is a no-op on i386.	 */	for (i = 0; i < USER_PTRS_PER_PGD; i++)#ifdef CONFIG_X86_PAE		set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));#else		set_pgd(swapper_pg_dir+i, __pgd(0));#endif	flush_tlb_all();}static int disable_nx __initdata = 0;u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;/* * noexec = on|off * * Control non executable mappings. * * on      Enable * off     Disable */void __init noexec_setup(const char *str){	if (!strncmp(str, "on",2) && cpu_has_nx) {		__supported_pte_mask |= _PAGE_NX;		disable_nx = 0;	} else if (!strncmp(str,"off",3)) {		disable_nx = 1;		__supported_pte_mask &= ~_PAGE_NX;	}}int nx_enabled = 0;#ifdef CONFIG_X86_PAEstatic void __init set_nx(void){	unsigned int v[4], l, h;	if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {		cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);		if ((v[3] & (1 << 20)) && !disable_nx) {			rdmsr(MSR_EFER, l, h);			l |= EFER_NX;			wrmsr(MSR_EFER, l, h);			nx_enabled = 1;			__supported_pte_mask |= _PAGE_NX;		}	}}/* * Enables/disables executability of a given kernel page and * returns the previous setting. */int __init set_kernel_exec(unsigned long vaddr, int enable){	pte_t *pte;	int ret = 1;	if (!nx_enabled)		goto out;	pte = lookup_address(vaddr);	BUG_ON(!pte);	if (!pte_exec_kernel(*pte))		ret = 0;	if (enable)		pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));	else		pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);	__flush_tlb_all();out:	return ret;}#endif/* * paging_init() sets up the page tables - note that the first 8MB are * already mapped by head.S. * * This routines also unmaps the page at virtual kernel address 0, so * that we can trap those pesky NULL-reference errors in the kernel. */void __init paging_init(void){#ifdef CONFIG_X86_PAE	set_nx();	if (nx_enabled)		printk("NX (Execute Disable) protection: active\n");#endif	pagetable_init();	load_cr3(swapper_pg_dir);#ifdef CONFIG_X86_PAE	/*	 * We will bail out later - printk doesn't work right now so	 * the user would just see a hanging kernel.	 */	if (cpu_has_pae)		set_in_cr4(X86_CR4_PAE);#endif	__flush_tlb_all();	kmap_init();}/* * Test if the WP bit works in supervisor mode. It isn't supported on 386's * and also on some strange 486's (NexGen etc.). All 586+'s are OK. This * used to involve black magic jumps to work around some nasty CPU bugs, * but fortunately the switch to using exceptions got rid of all that. */static void __init test_wp_bit(void){	printk("Checking if this processor honours the WP bit even in supervisor mode... ");	/* Any page-aligned address will do, the test is non-destructive */	__set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_READONLY);	boot_cpu_data.wp_works_ok = do_test_wp_bit();	clear_fixmap(FIX_WP_TEST);	if (!boot_cpu_data.wp_works_ok) {		printk("No.\n");#ifdef CONFIG_X86_WP_WORKS_OK		panic("This kernel doesn't support CPU's with broken WP. Recompile it for a 386!");#endif	} else {		printk("Ok.\n");	}}static void __init set_max_mapnr_init(void){#ifdef CONFIG_HIGHMEM	num_physpages = highend_pfn;#else	num_physpages = max_low_pfn;#endif#ifdef CONFIG_FLATMEM	max_mapnr = num_physpages;#endif}static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void){	extern int ppro_with_ram_bug(void);	int codesize, reservedpages, datasize, initsize;	int tmp;	int bad_ppro;#ifdef CONFIG_FLATMEM	if (!mem_map)		BUG();#endif		bad_ppro = ppro_with_ram_bug();#ifdef CONFIG_HIGHMEM	/* check that fixmap and pkmap do not overlap */	if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {		printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");		printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",				PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);		BUG();	}#endif 	set_max_mapnr_init();#ifdef CONFIG_HIGHMEM	high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;#else	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;#endif	/* this will put all low memory onto the freelists */	totalram_pages += free_all_bootmem();	reservedpages = 0;	for (tmp = 0; tmp < max_low_pfn; tmp++)		/*		 * Only count reserved RAM pages		 */		if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))			reservedpages++;	set_highmem_pages_init(bad_ppro);	codesize =  (unsigned long) &_etext - (unsigned long) &_text;	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;	kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 	kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 		   VMALLOC_END-VMALLOC_START);	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),		num_physpages << (PAGE_SHIFT-10),		codesize >> 10,		reservedpages << (PAGE_SHIFT-10),		datasize >> 10,		initsize >> 10,		(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))	       );#ifdef CONFIG_X86_PAE	if (!cpu_has_pae)		panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");#endif	if (boot_cpu_data.wp_works_ok < 0)		test_wp_bit();	/*	 * Subtle. SMP is doing it's boot stuff late (because it has to	 * fork idle threads) - but it also needs low mappings for the	 * protected-mode entry to work. We zap these entries only after	 * the WP-bit has been tested.	 */#ifndef CONFIG_SMP	zap_low_mappings();#endif}/* * this is for the non-NUMA, single node SMP system case. * Specifically, in the case of x86, we will always add * memory to the highmem for now. */#ifndef CONFIG_NEED_MULTIPLE_NODESint add_memory(u64 start, u64 size){	struct pglist_data *pgdata = &contig_page_data;	struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;	unsigned long start_pfn = start >> PAGE_SHIFT;	unsigned long nr_pages = size >> PAGE_SHIFT;	return __add_pages(zone, start_pfn, nr_pages);}int remove_memory(u64 start, u64 size){	return -EINVAL;}#endifkmem_cache_t *pgd_cache;kmem_cache_t *pmd_cache;void __init pgtable_cache_init(void){	if (PTRS_PER_PMD > 1) {		pmd_cache = kmem_cache_create("pmd",					PTRS_PER_PMD*sizeof(pmd_t),					PTRS_PER_PMD*sizeof(pmd_t),					0,					pmd_ctor,					NULL);		if (!pmd_cache)			panic("pgtable_cache_init(): cannot create pmd cache");	}	pgd_cache = kmem_cache_create("pgd",				PTRS_PER_PGD*sizeof(pgd_t),				PTRS_PER_PGD*sizeof(pgd_t),				0,				pgd_ctor,				PTRS_PER_PMD == 1 ? pgd_dtor : NULL);	if (!pgd_cache)		panic("pgtable_cache_init(): Cannot create pgd cache");}/* * This function cannot be __init, since exceptions don't work in that * section.  Put this after the callers, so that it cannot be inlined. */static int noinline do_test_wp_bit(void){	char tmp_reg;	int flag;	__asm__ __volatile__(		"	movb %0,%1	\n"		"1:	movb %1,%0	\n"		"	xorl %2,%2	\n"		"2:			\n"		".section __ex_table,\"a\"\n"		"	.align 4	\n"		"	.long 1b,2b	\n"		".previous		\n"		:"=m" (*(char *)fix_to_virt(FIX_WP_TEST)),		 "=q" (tmp_reg),		 "=r" (flag)		:"2" (1)		:"memory");		return flag;}void free_initmem(void){	unsigned long addr;	addr = (unsigned long)(&__init_begin);	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {		ClearPageReserved(virt_to_page(addr));		set_page_count(virt_to_page(addr), 1);		memset((void *)addr, 0xcc, PAGE_SIZE);		free_page(addr);		totalram_pages++;	}	printk (KERN_INFO "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 (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);	for (; start < end; start += PAGE_SIZE) {		ClearPageReserved(virt_to_page(start));		set_page_count(virt_to_page(start), 1);		free_page(start);		totalram_pages++;	}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -