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

📄 setup.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/arch/i386/kernel/setup.c * *  Copyright (C) 1995  Linus Torvalds * *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 * *  Memory region support *	David Parsons <orc@pell.chi.il.us>, July-August 1999 * *  Added E820 sanitization routine (removes overlapping memory regions); *  Brian Moyle <bmoyle@mvista.com>, February 2001 * * Moved CPU detection code to cpu/${cpu}.c *    Patrick Mochel <mochel@osdl.org>, March 2002 * *  Provisions for empty E820 memory regions (reported by certain BIOSes). *  Alex Achenbach <xela@slit.de>, December 2002. * *//* * This file handles the architecture-dependent parts of initialization */#include <linux/config.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/mmzone.h>#include <linux/tty.h>#include <linux/ioport.h>#include <linux/acpi.h>#include <linux/apm_bios.h>#include <linux/initrd.h>#include <linux/bootmem.h>#include <linux/seq_file.h>#include <linux/console.h>#include <linux/mca.h>#include <linux/root_dev.h>#include <linux/highmem.h>#include <linux/module.h>#include <linux/efi.h>#include <linux/init.h>#include <linux/edd.h>#include <linux/nodemask.h>#include <linux/kexec.h>#include <linux/crash_dump.h>#include <video/edid.h>#include <asm/apic.h>#include <asm/e820.h>#include <asm/mpspec.h>#include <asm/setup.h>#include <asm/arch_hooks.h>#include <asm/sections.h>#include <asm/io_apic.h>#include <asm/ist.h>#include <asm/io.h>#include "setup_arch_pre.h"#include <bios_ebda.h>/* Forward Declaration. */void __init find_max_pfn(void);/* This value is set up by the early boot code to point to the value   immediately after the boot time page tables.  It contains a *physical*   address, and must not be in the .bss segment! */unsigned long init_pg_tables_end __initdata = ~0UL;int disable_pse __devinitdata = 0;/* * Machine setup.. */#ifdef CONFIG_EFIint efi_enabled = 0;EXPORT_SYMBOL(efi_enabled);#endif/* cpu data as detected by the assembly code in head.S */struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };/* common cpu data for all cpus */struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };EXPORT_SYMBOL(boot_cpu_data);unsigned long mmu_cr4_features;#ifdef	CONFIG_ACPI	int acpi_disabled = 0;#else	int acpi_disabled = 1;#endifEXPORT_SYMBOL(acpi_disabled);#ifdef	CONFIG_ACPIint __initdata acpi_force = 0;extern acpi_interrupt_flags	acpi_sci_flags;#endif/* for MCA, but anyone else can use it if they want */unsigned int machine_id;#ifdef CONFIG_MCAEXPORT_SYMBOL(machine_id);#endifunsigned int machine_submodel_id;unsigned int BIOS_revision;unsigned int mca_pentium_flag;/* For PCI or other memory-mapped resources */unsigned long pci_mem_start = 0x10000000;#ifdef CONFIG_PCIEXPORT_SYMBOL(pci_mem_start);#endif/* Boot loader ID as an integer, for the benefit of proc_dointvec */int bootloader_type;/* user-defined highmem size */static unsigned int highmem_pages = -1;/* * Setup options */struct drive_info_struct { char dummy[32]; } drive_info;#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)EXPORT_SYMBOL(drive_info);#endifstruct screen_info screen_info;EXPORT_SYMBOL(screen_info);struct apm_info apm_info;EXPORT_SYMBOL(apm_info);struct sys_desc_table_struct {	unsigned short length;	unsigned char table[0];};struct edid_info edid_info;EXPORT_SYMBOL_GPL(edid_info);struct ist_info ist_info;#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \	defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)EXPORT_SYMBOL(ist_info);#endifstruct e820map e820;extern void early_cpu_init(void);extern void dmi_scan_machine(void);extern void generic_apic_probe(char *);extern int root_mountflags;unsigned long saved_videomode;#define RAMDISK_IMAGE_START_MASK  	0x07FF#define RAMDISK_PROMPT_FLAG		0x8000#define RAMDISK_LOAD_FLAG		0x4000	static char command_line[COMMAND_LINE_SIZE];unsigned char __initdata boot_params[PARAM_SIZE];static struct resource data_resource = {	.name	= "Kernel data",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM};static struct resource code_resource = {	.name	= "Kernel code",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM};static struct resource system_rom_resource = {	.name	= "System ROM",	.start	= 0xf0000,	.end	= 0xfffff,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM};static struct resource extension_rom_resource = {	.name	= "Extension ROM",	.start	= 0xe0000,	.end	= 0xeffff,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM};static struct resource adapter_rom_resources[] = { {	.name 	= "Adapter ROM",	.start	= 0xc8000,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM}, {	.name 	= "Adapter ROM",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM}, {	.name 	= "Adapter ROM",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM}, {	.name 	= "Adapter ROM",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM}, {	.name 	= "Adapter ROM",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM}, {	.name 	= "Adapter ROM",	.start	= 0,	.end	= 0,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM} };#define ADAPTER_ROM_RESOURCES \	(sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])static struct resource video_rom_resource = {	.name 	= "Video ROM",	.start	= 0xc0000,	.end	= 0xc7fff,	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM};static struct resource video_ram_resource = {	.name	= "Video RAM area",	.start	= 0xa0000,	.end	= 0xbffff,	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM};static struct resource standard_io_resources[] = { {	.name	= "dma1",	.start	= 0x0000,	.end	= 0x001f,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "pic1",	.start	= 0x0020,	.end	= 0x0021,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name   = "timer0",	.start	= 0x0040,	.end    = 0x0043,	.flags  = IORESOURCE_BUSY | IORESOURCE_IO}, {	.name   = "timer1",	.start  = 0x0050,	.end    = 0x0053,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "keyboard",	.start	= 0x0060,	.end	= 0x006f,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "dma page reg",	.start	= 0x0080,	.end	= 0x008f,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "pic2",	.start	= 0x00a0,	.end	= 0x00a1,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "dma2",	.start	= 0x00c0,	.end	= 0x00df,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO}, {	.name	= "fpu",	.start	= 0x00f0,	.end	= 0x00ff,	.flags	= IORESOURCE_BUSY | IORESOURCE_IO} };#define STANDARD_IO_RESOURCES \	(sizeof standard_io_resources / sizeof standard_io_resources[0])#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)static int __init romchecksum(unsigned char *rom, unsigned long length){	unsigned char *p, sum = 0;	for (p = rom; p < rom + length; p++)		sum += *p;	return sum == 0;}static void __init probe_roms(void){	unsigned long start, length, upper;	unsigned char *rom;	int	      i;	/* video rom */	upper = adapter_rom_resources[0].start;	for (start = video_rom_resource.start; start < upper; start += 2048) {		rom = isa_bus_to_virt(start);		if (!romsignature(rom))			continue;		video_rom_resource.start = start;		/* 0 < length <= 0x7f * 512, historically */		length = rom[2] * 512;		/* if checksum okay, trust length byte */		if (length && romchecksum(rom, length))			video_rom_resource.end = start + length - 1;		request_resource(&iomem_resource, &video_rom_resource);		break;	}	start = (video_rom_resource.end + 1 + 2047) & ~2047UL;	if (start < upper)		start = upper;	/* system rom */	request_resource(&iomem_resource, &system_rom_resource);	upper = system_rom_resource.start;	/* check for extension rom (ignore length byte!) */	rom = isa_bus_to_virt(extension_rom_resource.start);	if (romsignature(rom)) {		length = extension_rom_resource.end - extension_rom_resource.start + 1;		if (romchecksum(rom, length)) {			request_resource(&iomem_resource, &extension_rom_resource);			upper = extension_rom_resource.start;		}	}	/* check for adapter roms on 2k boundaries */	for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {		rom = isa_bus_to_virt(start);		if (!romsignature(rom))			continue;		/* 0 < length <= 0x7f * 512, historically */		length = rom[2] * 512;		/* but accept any length that fits if checksum okay */		if (!length || start + length > upper || !romchecksum(rom, length))			continue;		adapter_rom_resources[i].start = start;		adapter_rom_resources[i].end = start + length - 1;		request_resource(&iomem_resource, &adapter_rom_resources[i]);		start = adapter_rom_resources[i++].end & ~2047UL;	}}static void __init limit_regions(unsigned long long size){	unsigned long long current_addr = 0;	int i;	if (efi_enabled) {		efi_memory_desc_t *md;		void *p;		for (p = memmap.map, i = 0; p < memmap.map_end;			p += memmap.desc_size, i++) {			md = p;			current_addr = md->phys_addr + (md->num_pages << 12);			if (md->type == EFI_CONVENTIONAL_MEMORY) {				if (current_addr >= size) {					md->num_pages -=						(((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);					memmap.nr_map = i + 1;					return;				}			}		}	}	for (i = 0; i < e820.nr_map; i++) {		current_addr = e820.map[i].addr + e820.map[i].size;		if (current_addr < size)			continue;		if (e820.map[i].type != E820_RAM)			continue;		if (e820.map[i].addr >= size) {			/*			 * This region starts past the end of the			 * requested size, skip it completely.			 */			e820.nr_map = i;		} else {			e820.nr_map = i + 1;			e820.map[i].size -= current_addr - size;		}		return;	}}static void __init add_memory_region(unsigned long long start,                                  unsigned long long size, int type){	int x;	if (!efi_enabled) {       		x = e820.nr_map;		if (x == E820MAX) {		    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");		    return;		}		e820.map[x].addr = start;		e820.map[x].size = size;		e820.map[x].type = type;		e820.nr_map++;	}} /* add_memory_region */#define E820_DEBUG	1static void __init print_memory_map(char *who){	int i;	for (i = 0; i < e820.nr_map; i++) {		printk(" %s: %016Lx - %016Lx ", who,			e820.map[i].addr,			e820.map[i].addr + e820.map[i].size);		switch (e820.map[i].type) {		case E820_RAM:	printk("(usable)\n");				break;		case E820_RESERVED:				printk("(reserved)\n");				break;		case E820_ACPI:				printk("(ACPI data)\n");				break;		case E820_NVS:				printk("(ACPI NVS)\n");				break;		default:	printk("type %lu\n", e820.map[i].type);				break;		}	}}/* * Sanitize the BIOS e820 map. * * Some e820 responses include overlapping entries.  The following  * replaces the original e820 map with a new one, removing overlaps. * */struct change_member {	struct e820entry *pbios; /* pointer to original bios entry */	unsigned long long addr; /* address for this change point */};static struct change_member change_point_list[2*E820MAX] __initdata;static struct change_member *change_point[2*E820MAX] __initdata;static struct e820entry *overlap_list[E820MAX] __initdata;static struct e820entry new_bios[E820MAX] __initdata;static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map){	struct change_member *change_tmp;	unsigned long current_type, last_type;	unsigned long long last_addr;	int chgidx, still_changing;	int overlap_entries;	int new_bios_entry;	int old_nr, new_nr, chg_nr;	int i;	/*		Visually we're performing the following (1,2,3,4 = memory types)...		Sample memory map (w/overlaps):		   ____22__________________		   ______________________4_		   ____1111________________		   _44_____________________		   11111111________________		   ____________________33__		   ___________44___________		   __________33333_________		   ______________22________		   ___________________2222_		   _________111111111______		   _____________________11_		   _________________4______		Sanitized equivalent (no overlap):		   1_______________________		   _44_____________________		   ___1____________________		   ____22__________________		   ______11________________		   _________1______________		   __________3_____________		   ___________44___________		   _____________33_________		   _______________2________		   ________________1_______		   _________________4______		   ___________________2____		   ____________________33__		   ______________________4_	*/	/* if there's only one memory region, don't bother */	if (*pnr_map < 2)		return -1;	old_nr = *pnr_map;	/* bail out if we find any unreasonable addresses in bios map */	for (i=0; i<old_nr; i++)		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)			return -1;	/* create pointers for initial change-point information (for sorting) */	for (i=0; i < 2*old_nr; i++)		change_point[i] = &change_point_list[i];	/* record all known change-points (starting and ending addresses),	   omitting those that are for empty memory regions */	chgidx = 0;	for (i=0; i < old_nr; i++)	{		if (biosmap[i].size != 0) {			change_point[chgidx]->addr = biosmap[i].addr;			change_point[chgidx++]->pbios = &biosmap[i];			change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;			change_point[chgidx++]->pbios = &biosmap[i];

⌨️ 快捷键说明

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