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

📄 setup.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
					add_memory_region(0, LOWMEMSIZE(), E820_RAM);				}				mem_size = memparse(from+4, &from);				if (*from == '@')					start_at = memparse(from+1, &from);				else {					start_at = HIGH_MEMORY;					mem_size -= HIGH_MEMORY;					usermem=0;				}				add_memory_region(start_at, mem_size, E820_RAM);			}		}		c = *(from++);		if (!c)			break;		if (COMMAND_LINE_SIZE <= ++len)			break;		*(to++) = c;	}	*to = '\0';	*cmdline_p = command_line;	if (usermem) {		printk("user-defined physical RAM map:\n");		print_memory_map("user");	}}void __init setup_arch(char **cmdline_p){	unsigned long bootmap_size;	unsigned long start_pfn, max_pfn, max_low_pfn;	int i;#ifdef CONFIG_VISWS	visws_get_board_type_and_rev();#endif 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); 	drive_info = DRIVE_INFO; 	screen_info = SCREEN_INFO;	apm_info.bios = APM_BIOS_INFO;	if( SYS_DESC_TABLE.length != 0 ) {		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;		machine_id = SYS_DESC_TABLE.table[0];		machine_submodel_id = SYS_DESC_TABLE.table[1];		BIOS_revision = SYS_DESC_TABLE.table[2];	}	aux_device_present = AUX_DEVICE_INFO;#ifdef CONFIG_BLK_DEV_RAM	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);#endif	setup_memory_region();	if (!MOUNT_ROOT_RDONLY)		root_mountflags &= ~MS_RDONLY;	init_mm.start_code = (unsigned long) &_text;	init_mm.end_code = (unsigned long) &_etext;	init_mm.end_data = (unsigned long) &_edata;	init_mm.brk = (unsigned long) &_end;	code_resource.start = virt_to_bus(&_text);	code_resource.end = virt_to_bus(&_etext)-1;	data_resource.start = virt_to_bus(&_etext);	data_resource.end = virt_to_bus(&_edata)-1;	parse_mem_cmdline(cmdline_p);#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)#define PFN_PHYS(x)	((x) << PAGE_SHIFT)/* * 128MB for vmalloc and initrd */#define VMALLOC_RESERVE	(unsigned long)(128 << 20)#define MAXMEM		(unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)#define MAXMEM_PFN	PFN_DOWN(MAXMEM)#define MAX_NONPAE_PFN	(1 << 20)	/*	 * partially used pages are not usable - thus	 * we are rounding upwards:	 */	start_pfn = PFN_UP(__pa(&_end));	/*	 * Find the highest page frame number we have available	 */	max_pfn = 0;	for (i = 0; i < e820.nr_map; i++) {		unsigned long start, end;		/* RAM? */		if (e820.map[i].type != E820_RAM)			continue;		start = PFN_UP(e820.map[i].addr);		end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);		if (start >= end)			continue;		if (end > max_pfn)			max_pfn = end;	}	/*	 * Determine low and high memory ranges:	 */	max_low_pfn = max_pfn;	if (max_low_pfn > MAXMEM_PFN) {		max_low_pfn = MAXMEM_PFN;#ifndef CONFIG_HIGHMEM		/* Maximum memory usable is what is directly addressable */		printk(KERN_WARNING "Warning only %ldMB will be used.\n",					MAXMEM>>20);		if (max_pfn > MAX_NONPAE_PFN)			printk(KERN_WARNING "Use a PAE enabled kernel.\n");		else			printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");#else /* !CONFIG_HIGHMEM */#ifndef CONFIG_X86_PAE		if (max_pfn > MAX_NONPAE_PFN) {			max_pfn = MAX_NONPAE_PFN;			printk(KERN_WARNING "Warning only 4GB will be used.\n");			printk(KERN_WARNING "Use a PAE enabled kernel.\n");		}#endif /* !CONFIG_X86_PAE */#endif /* !CONFIG_HIGHMEM */	}#ifdef CONFIG_HIGHMEM	highstart_pfn = highend_pfn = max_pfn;	if (max_pfn > MAXMEM_PFN) {		highstart_pfn = MAXMEM_PFN;		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",			pages_to_mb(highend_pfn - highstart_pfn));	}#endif	/*	 * Initialize the boot-time allocator (with low memory only):	 */	bootmap_size = init_bootmem(start_pfn, max_low_pfn);	/*	 * Register fully available low RAM pages with the bootmem allocator.	 */	for (i = 0; i < e820.nr_map; i++) {		unsigned long curr_pfn, last_pfn, size; 		/*		 * Reserve usable low memory		 */		if (e820.map[i].type != E820_RAM)			continue;		/*		 * We are rounding up the start address of usable memory:		 */		curr_pfn = PFN_UP(e820.map[i].addr);		if (curr_pfn >= max_low_pfn)			continue;		/*		 * ... and at the end of the usable range downwards:		 */		last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);		if (last_pfn > max_low_pfn)			last_pfn = max_low_pfn;		/*		 * .. finally, did all the rounding and playing		 * around just make the area go away?		 */		if (last_pfn <= curr_pfn)			continue;		size = last_pfn - curr_pfn;		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));	}	/*	 * Reserve the bootmem bitmap itself as well. We do this in two	 * steps (first step was init_bootmem()) because this catches	 * the (very unlikely) case of us accidentally initializing the	 * bootmem allocator with an invalid RAM area.	 */	reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +			 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));	/*	 * reserve physical page 0 - it's a special BIOS page on many boxes,	 * enabling clean reboots, SMP operation, laptop functions.	 */	reserve_bootmem(0, PAGE_SIZE);#ifdef CONFIG_SMP	/*	 * But first pinch a few for the stack/trampoline stuff	 * FIXME: Don't need the extra page at 4K, but need to fix	 * trampoline before removing it. (see the GDT stuff)	 */	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/#endif#ifdef CONFIG_X86_IO_APIC	/*	 * Find and reserve possible boot-time SMP configuration:	 */	find_smp_config();#endif	paging_init();#ifdef CONFIG_X86_IO_APIC	/*	 * get boot-time SMP configuration:	 */	if (smp_found_config)		get_smp_config();#endif#ifdef CONFIG_X86_LOCAL_APIC	init_apic_mappings();#endif#ifdef CONFIG_BLK_DEV_INITRD	if (LOADER_TYPE && INITRD_START) {		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {			reserve_bootmem(INITRD_START, INITRD_SIZE);			initrd_start =				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;			initrd_end = initrd_start+INITRD_SIZE;		}		else {			printk("initrd extends beyond end of memory "			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",			    INITRD_START + INITRD_SIZE,			    max_low_pfn << PAGE_SHIFT);			initrd_start = 0;		}	}#endif	/*	 * Request address space for all standard RAM and ROM resources	 * and also for regions reported as reserved by the e820.	 */	probe_roms();	for (i = 0; i < e820.nr_map; i++) {		struct resource *res;		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)			continue;		res = alloc_bootmem_low(sizeof(struct resource));		switch (e820.map[i].type) {		case E820_RAM:	res->name = "System RAM"; break;		case E820_ACPI:	res->name = "ACPI Tables"; break;		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;		default:	res->name = "reserved";		}		res->start = e820.map[i].addr;		res->end = res->start + e820.map[i].size - 1;		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;		request_resource(&iomem_resource, res);		if (e820.map[i].type == E820_RAM) {			/*			 *  We dont't know which RAM region contains kernel data,			 *  so we try it repeatedly and let the resource manager			 *  test it.			 */			request_resource(res, &code_resource);			request_resource(res, &data_resource);		}	}	request_resource(&iomem_resource, &vram_resource);	/* request I/O space for devices used on all i[345]86 PCs */	for (i = 0; i < STANDARD_IO_RESOURCES; i++)		request_resource(&ioport_resource, standard_io_resources+i);#ifdef CONFIG_VT#if defined(CONFIG_VGA_CONSOLE)	conswitchp = &vga_con;#elif defined(CONFIG_DUMMY_CONSOLE)	conswitchp = &dummy_con;#endif#endif}#ifndef CONFIG_X86_TSCstatic int tsc_disable __initdata = 0;static int __init tsc_setup(char *str){	tsc_disable = 1;	return 1;}__setup("notsc", tsc_setup);#endifstatic int __init get_model_name(struct cpuinfo_x86 *c){	unsigned int *v;	char *p, *q;	if (cpuid_eax(0x80000000) < 0x80000004)		return 0;	v = (unsigned int *) c->x86_model_id;	cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);	cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);	cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);	c->x86_model_id[48] = 0;	/* Intel chips right-justify this string for some dumb reason;	   undo that brain damage */	p = q = &c->x86_model_id[0];	while ( *p == ' ' )	     p++;	if ( p != q ) {	     while ( *p )		  *q++ = *p++;	     while ( q <= &c->x86_model_id[48] )		  *q++ = '\0';	/* Zero-pad the rest */	}	return 1;}static void __init display_cacheinfo(struct cpuinfo_x86 *c){	unsigned int n, dummy, ecx, edx, l2size;	n = cpuid_eax(0x80000000);	if (n >= 0x80000005) {		cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);		printk("CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",			edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);		c->x86_cache_size=(ecx>>24)+(edx>>24);		}	if (n < 0x80000006)	/* Some chips just has a large L1. */		return;	ecx = cpuid_ecx(0x80000006);	l2size = ecx >> 16;	/* AMD errata T13 (order #21922) */	if (c->x86_vendor == X86_VENDOR_AMD &&	    c->x86 == 6 &&	    c->x86_model == 3 &&	    c->x86_mask == 0) {		l2size = 64;	}	if ( l2size == 0 )		return;		/* Again, no L2 cache is possible */	c->x86_cache_size = l2size;	printk("CPU: L2 Cache: %dK (%d bytes/line)\n",	       l2size, ecx & 0xFF);}/* *	B step AMD K6 before B 9730xxxx have hardware bugs that can cause *	misexecution of code under Linux. Owners of such processors should *	contact AMD for precise details and a CPU swap. * *	See	http://www.mygale.com/~poulot/k6bug.html *		http://www.amd.com/K6/k6docs/revgd.html * *	The following test is erm.. interesting. AMD neglected to up *	the chip setting when fixing the bug but they also tweaked some *	performance at the same time.. */ extern void vide(void);__asm__(".align 4\nvide: ret");static int __init init_amd(struct cpuinfo_x86 *c){	u32 l, h;	unsigned long flags;	int mbytes = max_mapnr >> (20-PAGE_SHIFT);	int r;	/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */	clear_bit(0*32+31, &c->x86_capability);		r = get_model_name(c);	switch(c->x86)	{		case 5:			if( c->x86_model < 6 )			{				/* Based on AMD doc 20734R - June 2000 */				if ( c->x86_model == 0 ) {					clear_bit(X86_FEATURE_APIC, &c->x86_capability);					set_bit(X86_FEATURE_PGE, &c->x86_capability);				}				break;			}						if ( c->x86_model == 6 && c->x86_mask == 1 ) {				const int K6_BUG_LOOP = 1000000;				int n;				void (*f_vide)(void);				unsigned long d, d2;								printk(KERN_INFO "AMD K6 stepping B detected - ");								/*				 * It looks like AMD fixed the 2.6.2 bug and improved indirect 				 * calls at the same time.				 */				n = K6_BUG_LOOP;				f_vide = vide;				rdtscl(d);				while (n--) 					f_vide();				rdtscl(d2);				d = d2-d;								/* Knock these two lines out if it debugs out ok */				printk(KERN_INFO "K6 BUG %ld %d (Report these if test report is incorrect)\n", d, 20*K6_BUG_LOOP);				printk(KERN_INFO "AMD K6 stepping B detected - ");				/* -- cut here -- */				if (d > 20*K6_BUG_LOOP) 					printk("system stability may be impaired when more than 32 MB are used.\n");				else 					printk("probably OK (after B9730xxxx).\n");				printk(KERN_INFO "Please see http://www.mygale.com/~poulot/k6bug.html\n");			}			/* K6 with old style WHCR */			if( c->x86_model < 8 ||				(c->x86_model== 8 && c->x86_mask < 8))			{				/* We can only write allocate on the low 508Mb */				if(mbytes>508)					mbytes=508;									rdmsr(0xC0000082, l, h);				if((l&0x0000FFFF)==0)				{							l=(1<<0)|((mbytes/4)<<1);					save_flags(flags);					__cli();					__asm__ __volatile__ ("wbinvd": : :"memory");					wrmsr(0xC0000082, l, h);					restore_flags(flags);					printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",						mbytes);									}				break;			}			if (c->x86_model == 8 || c->x86_model == 9 || c->x86_model == 13)			{				/* The more serious chips .. */								if(mbytes>4092)					mbytes=4092;				rdmsr(0xC0000082, l, h);				if((l&0xFFFF0000)==0)				{					l=((mbytes>>2)<<22)|(1<<16);					save_flags(flags);					__cli();					__asm__ __volatile__ ("wbinvd": : :"memory");					wrmsr(0xC0000082, l, h);					restore_flags(flags);					printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",						mbytes);				}				/*  Set MTRR capability flag if appropriate */				if ( (c->x86_model == 13) ||				     (c->x86_model == 9) ||				     ((c->x86_model == 8) && 				     (c->x86_mask >= 8)) )					set_bit(X86_FEATURE_K6_MTRR, &c->x86_capability);				break;			}			break;		case 6:	/* An Athlon/Duron. We can trust the BIOS probably */			break;			}	display_cacheinfo(c);	return r;}/* * Read Cyrix DEVID registers (DIR) to get more detailed info. about the CPU */static inline void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1){	unsigned char ccr2, ccr3;	/* we test for DEVID by checking whether CCR3 is writable */	cli();	ccr3 = getCx86(CX86_CCR3);	setCx86(CX86_CCR3, ccr3 ^ 0x80);	getCx86(0xc0);   /* dummy to change bus */	if (getCx86(CX86_CCR3) == ccr3) {       /* no DEVID regs. */		ccr2 = getCx86(CX86_CCR2);		setCx86(CX86_CCR2, ccr2 ^ 0x04);		getCx86(0xc0);  /* dummy */		if (getCx86(CX86_CCR2) == ccr2) /* old Cx486SLC/DLC */			*dir0 = 0xfd;		else {                          /* Cx486S A step */			setCx86(CX86_CCR2, ccr2);			*dir0 = 0xfe;		}	}	else {		setCx86(CX86_CCR3, ccr3);  /* restore CCR3 */		/* read DIR0 and DIR1 CPU registers */		*dir0 = getCx86(CX86_DIR0);		*dir1 = getCx86(CX86_DIR1);	}	sti();}/* * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in * order to identify the Cyrix CPU model after we're out of setup.c */unsigned char Cx86_dir0_msb __initdata = 0;static char Cx86_model[][9] __initdata = {	"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",	"M II ", "Unknown"};static char Cx486_name[][5] __initdata = {	"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",	"SRx2", "DRx2"};static char Cx486S_name[][4] __initdata = {	"S", "S2", "Se", "S2e"};static char Cx486D_name[][4] __initdata = {	"DX", "DX2", "?", "?", "?", "DX4"};static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock";static char cyrix_model_mult1[] __initdata = "12??43";static char cyrix_model_mult2[] __initdata = "12233445";/* * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old * BIOSes for compatability with DOS games.  This makes the udelay loop * work correctly, and improves performance. */extern void calibrate_delay(void) __init;static void __init check_cx686_slop(struct cpuinfo_x86 *c){	if (Cx86_dir0_msb == 3) {		unsigned char ccr3, ccr5;

⌨️ 快捷键说明

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