setup.c

来自「linux-2.4.29操作系统的源码」· C语言 代码 · 共 921 行 · 第 1/2 页

C
921
字号
/* *  linux/arch/x86-64/kernel/setup.c * *  Copyright (C) 1995  Linus Torvalds * *  Nov 2001 Dave Jones <davej@suse.de> *  Forked from i386 setup code. *//* * This file handles the architecture-dependent parts of initialization */#include <linux/errno.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/ptrace.h>#include <linux/slab.h>#include <linux/user.h>#include <linux/a.out.h>#include <linux/tty.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/config.h>#include <linux/init.h>#include <linux/acpi.h>#include <linux/blk.h>#include <linux/highmem.h>#include <linux/bootmem.h>#include <linux/module.h>#include <asm/processor.h>#include <linux/console.h>#include <linux/seq_file.h>#include <asm/mtrr.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/io.h>#include <asm/smp.h>#include <asm/msr.h>#include <asm/desc.h>#include <asm/e820.h>#include <asm/dma.h>#include <asm/mpspec.h>#include <asm/mmu_context.h>#include <asm/bootsetup.h>#include <asm/proto.h>int acpi_disabled;EXPORT_SYMBOL(acpi_disabled);int swiotlb;EXPORT_SYMBOL(swiotlb);extern	int phys_proc_id[NR_CPUS];/* * Machine setup.. */struct cpuinfo_x86 boot_cpu_data = { 	cpuid_level: -1, };unsigned long mmu_cr4_features;EXPORT_SYMBOL(mmu_cr4_features);/* For PCI or other memory-mapped resources */unsigned long pci_mem_start = 0x10000000;/* * Setup options */struct drive_info_struct { char dummy[32]; } drive_info;struct screen_info screen_info;struct sys_desc_table_struct {	unsigned short length;	unsigned char table[0];};struct e820map e820;unsigned char aux_device_present;extern int root_mountflags;extern char _text, _etext, _edata, _end;char command_line[COMMAND_LINE_SIZE];char saved_command_line[COMMAND_LINE_SIZE];struct resource standard_io_resources[] = {	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },	{ "pic1", 0x20, 0x3f, IORESOURCE_BUSY },	{ "timer", 0x40, 0x5f, IORESOURCE_BUSY },	{ "keyboard", 0x60, 0x6f, IORESOURCE_BUSY },	{ "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },	{ "pic2", 0xa0, 0xbf, IORESOURCE_BUSY },	{ "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },	{ "fpu", 0xf0, 0xff, IORESOURCE_BUSY }};#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))struct resource code_resource = { "Kernel code", 0x100000, 0 };struct resource data_resource = { "Kernel data", 0, 0 };struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };/* System ROM resources */#define MAXROMS 6static struct resource rom_resources[MAXROMS] = {	{ "System ROM", 0xF0000, 0xFFFFF, IORESOURCE_BUSY },	{ "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_BUSY }};#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)static void __init probe_roms(void){	int roms = 1;	unsigned long base;	unsigned char *romstart;	request_resource(&iomem_resource, rom_resources+0);	/* Video ROM is standard at C000:0000 - C7FF:0000, check signature */	for (base = 0xC0000; base < 0xE0000; base += 2048) {		romstart = bus_to_virt(base);		if (!romsignature(romstart))			continue;		request_resource(&iomem_resource, rom_resources + roms);		roms++;		break;	}	/* Extension roms at C800:0000 - DFFF:0000 */	for (base = 0xC8000; base < 0xE0000; base += 2048) {		unsigned long length;		romstart = bus_to_virt(base);		if (!romsignature(romstart))			continue;		length = romstart[2] * 512;		if (length) {			unsigned int i;			unsigned char chksum;			chksum = 0;			for (i = 0; i < length; i++)				chksum += romstart[i];			/* Good checksum? */			if (!chksum) {				rom_resources[roms].start = base;				rom_resources[roms].end = base + length - 1;				rom_resources[roms].name = "Extension ROM";				rom_resources[roms].flags = IORESOURCE_BUSY;				request_resource(&iomem_resource, rom_resources + roms);				roms++;				if (roms >= MAXROMS)					return;			}		}	}	/* Final check for motherboard extension rom at E000:0000 */	base = 0xE0000;	romstart = bus_to_virt(base);	if (romsignature(romstart)) {		rom_resources[roms].start = base;		rom_resources[roms].end = base + 65535;		rom_resources[roms].name = "Extension ROM";		rom_resources[roms].flags = IORESOURCE_BUSY;		request_resource(&iomem_resource, rom_resources + roms);	}}unsigned long start_pfn, end_pfn; extern unsigned long table_start, table_end;#ifndef CONFIG_DISCONTIGMEMstatic void __init contig_initmem_init(void){	unsigned long bootmap_size, bootmap; 	bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;	bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);	if (bootmap == -1L) 		panic("Cannot find bootmem map of size %ld\n",bootmap_size);	bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);	e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 	reserve_bootmem(bootmap, bootmap_size);}#endifvoid __init setup_arch(char **cmdline_p){	int i;	unsigned long kernel_end;  	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); 	drive_info = DRIVE_INFO; 	screen_info = SCREEN_INFO;	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);	e820_end_of_ram();	check_efer();	init_memory_mapping(); #ifdef CONFIG_BLK_DEV_INITRD	if (LOADER_TYPE && INITRD_START) {		if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {			initrd_start =				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;			initrd_end = initrd_start+INITRD_SIZE;	}		else {			printk(KERN_ERR "initrd extends beyond end of memory "			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",			    (unsigned long)INITRD_START + INITRD_SIZE,			    (unsigned long)(end_pfn << PAGE_SHIFT));			initrd_start = 0;	}	}#endif#ifdef CONFIG_DISCONTIGMEM	numa_initmem_init(0, end_pfn); 	#else	contig_initmem_init(); #endif		/* Reserve direct mapping */	reserve_bootmem_generic(table_start << PAGE_SHIFT, 				(table_end - table_start) << PAGE_SHIFT);#ifdef CONFIG_BLK_DEV_INITRD	if (initrd_start) 		reserve_bootmem_generic(INITRD_START, INITRD_SIZE);#endif	/* Reserve BIOS data page. Some things still need it */	reserve_bootmem_generic(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_generic(PAGE_SIZE, PAGE_SIZE); 	/* Reserve SMP trampoline */	reserve_bootmem_generic(0x6000, PAGE_SIZE);#endif	/* Reserve Kernel */	kernel_end = round_up(__pa_symbol(&_end), PAGE_SIZE);	reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);#ifdef CONFIG_ACPI_SLEEP	/* 	 * Reserve low memory region for sleep support. 	 */ 	acpi_reserve_bootmem();#endif#ifdef CONFIG_X86_LOCAL_APIC	/*	 * Find and reserve possible boot-time SMP configuration:	 */	find_smp_config();#endif#ifdef CONFIG_SMP	/* AP processor realmode stacks in low memory*/	smp_alloc_memory();#endif	paging_init();#if !defined(CONFIG_SMP) && defined(CONFIG_X86_IO_APIC)	extern void check_ioapic(void);	check_ioapic();#endif#ifdef CONFIG_ACPI_BOOT	/*	 * Parse the ACPI tables for possible boot-time SMP configuration.	 */	acpi_boot_init();#endif#ifdef CONFIG_X86_LOCAL_APIC	/*	 * get boot-time SMP configuration:	 */	if (smp_found_config)		get_smp_config();	init_apic_mappings();	#endif	/*	 * Request address space for all standard RAM and ROM resources	 * and also for regions reported as reserved by the e820.	 */	probe_roms();	e820_reserve_resources(); 	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);	/* We put PCI memory up to make sure VALID_PAGE with DISCONTIGMEM	   never returns true for it */ 	/* Tell the PCI layer not to allocate too close to the RAM area.. */	pci_mem_start = IOMAP_START;#ifdef CONFIG_GART_IOMMU	iommu_hole_init();#endif#ifdef CONFIG_SWIOTLB       if (!iommu_aperture && end_pfn >= 0xffffffff>>PAGE_SHIFT) {               swiotlb_init();              swiotlb = 1;       }#endif#ifdef CONFIG_VT#if defined(CONFIG_VGA_CONSOLE)	conswitchp = &vga_con;#elif defined(CONFIG_DUMMY_CONSOLE)	conswitchp = &dummy_con;#endif#endif	num_mappedpages = end_pfn;}static int __init get_model_name(struct cpuinfo_x86 *c){	unsigned int *v;	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;	return 1;}static void __init display_cacheinfo(struct cpuinfo_x86 *c){	unsigned int n, dummy, ecx, edx, eax, ebx, eax_2, ebx_2, ecx_2;	n = cpuid_eax(0x80000000);	if (n >= 0x80000005) {		if (n >= 0x80000006) 			cpuid(0x80000006, &eax_2, &ebx_2, &ecx_2, &dummy); 			cpuid(0x80000005, &eax, &ebx, &ecx, &edx);		printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line/%d way), D cache %dK (%d bytes/line/%d way)\n",		       edx>>24, edx&0xFF, (edx>>16)&0xff, 		       ecx>>24, ecx&0xFF, (ecx>>16)&0xff);		c->x86_cache_size=(ecx>>24)+(edx>>24);			if (n >= 0x80000006) {			printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line/%d way)\n",			       ecx_2>>16, ecx_2&0xFF, 			       /*  use bits[15:13] as power of 2 for # of ways */			       1 << ((ecx>>13) & 0x7) 			       /* Direct and Full associative L2 are very unlikely */);			c->x86_cache_size = ecx_2 >> 16;		c->x86_tlbsize = ((ebx>>16)&0xff) + ((ebx_2>>16)&0xfff) + 			(ebx&0xff) + ((ebx_2)&0xfff);	}		if (n >= 0x80000007)			cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power); 		if (n >= 0x80000008) {			cpuid(0x80000008, &eax, &dummy, &dummy, &dummy); 			c->x86_virt_bits = (eax >> 8) & 0xff;			c->x86_phys_bits = eax & 0xff;		}	}}#define LVL_1_INST      1#define LVL_1_DATA      2#define LVL_2           3#define LVL_3           4#define LVL_TRACE       5struct _cache_table{        unsigned char descriptor;        char cache_type;        short size;};/* all the cache descriptor types we care about (no TLB or trace cache entries) */static struct _cache_table cache_table[] __initdata ={	{ 0x06, LVL_1_INST, 8 },	{ 0x08, LVL_1_INST, 16 },	{ 0x0A, LVL_1_DATA, 8 },	{ 0x0C, LVL_1_DATA, 16 },	{ 0x22, LVL_3,      512 },	{ 0x23, LVL_3,      1024 },	{ 0x25, LVL_3,      2048 },	{ 0x29, LVL_3,      4096 },	{ 0x39, LVL_2,      128 },	{ 0x3C, LVL_2,      256 },	{ 0x41, LVL_2,      128 },	{ 0x42, LVL_2,      256 },	{ 0x43, LVL_2,      512 },	{ 0x44, LVL_2,      1024 },	{ 0x45, LVL_2,      2048 },	{ 0x66, LVL_1_DATA, 8 },	{ 0x67, LVL_1_DATA, 16 },	{ 0x68, LVL_1_DATA, 32 },	{ 0x70, LVL_TRACE,  12 },	{ 0x71, LVL_TRACE,  16 },	{ 0x72, LVL_TRACE,  32 },	{ 0x79, LVL_2,      128 },	{ 0x7A, LVL_2,      256 },	{ 0x7B, LVL_2,      512 },	{ 0x7C, LVL_2,      1024 },	{ 0x82, LVL_2,      256 },	{ 0x83, LVL_2,      512 },	{ 0x84, LVL_2,      1024 },	{ 0x85, LVL_2,      2048 },	{ 0x00, 0, 0}

⌨️ 快捷键说明

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