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

📄 setup.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  linux/arch/alpha/kernel/setup.c * *  Copyright (C) 1995  Linus Torvalds *//* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> *//* * Bootup setup stuff. */#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/delay.h>#include <linux/config.h>	/* CONFIG_ALPHA_LCA etc */#include <linux/mc146818rtc.h>#include <linux/console.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/string.h>#include <linux/ioport.h>#include <linux/bootmem.h>#include <linux/pci.h>#include <linux/seq_file.h>#include <linux/root_dev.h>#include <linux/initrd.h>#include <linux/eisa.h>#ifdef CONFIG_MAGIC_SYSRQ#include <linux/sysrq.h>#include <linux/reboot.h>#endif#include <linux/notifier.h>#include <asm/setup.h>#include <asm/io.h>extern struct notifier_block *panic_notifier_list;static int alpha_panic_event(struct notifier_block *, unsigned long, void *);static struct notifier_block alpha_panic_block = {	alpha_panic_event,        NULL,        INT_MAX /* try to do it first */};#include <asm/uaccess.h>#include <asm/pgtable.h>#include <asm/system.h>#include <asm/hwrpb.h>#include <asm/dma.h>#include <asm/io.h>#include <asm/mmu_context.h>#include <asm/console.h>#include "proto.h"#include "pci_impl.h"struct hwrpb_struct *hwrpb;unsigned long srm_hae;int alpha_l1i_cacheshape;int alpha_l1d_cacheshape;int alpha_l2_cacheshape;int alpha_l3_cacheshape;#ifdef CONFIG_VERBOSE_MCHECK/* 0=minimum, 1=verbose, 2=all *//* These can be overridden via the command line, ie "verbose_mcheck=2") */unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON;#endif/* Which processor we booted from.  */int boot_cpuid;/* * Using SRM callbacks for initial console output. This works from * setup_arch() time through the end of time_init(), as those places * are under our (Alpha) control. * "srmcons" specified in the boot command arguments allows us to * see kernel messages during the period of time before the true * console device is "registered" during console_init().  * As of this version (2.5.59), console_init() will call * disable_early_printk() as the last action before initializing * the console drivers. That's the last possible time srmcons can be  * unregistered without interfering with console behavior. * * By default, OFF; set it with a bootcommand arg of "srmcons" or  * "console=srm". The meaning of these two args is: *     "srmcons"     - early callback prints  *     "console=srm" - full callback based console, including early prints */int srmcons_output = 0;/* Enforce a memory size limit; useful for testing. By default, none. */unsigned long mem_size_limit = 0;/* Set AGP GART window size (0 means disabled). */unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;#ifdef CONFIG_ALPHA_GENERICstruct alpha_machine_vector alpha_mv;int alpha_using_srm;#endif#define N(a) (sizeof(a)/sizeof(a[0]))static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,					       unsigned long);static struct alpha_machine_vector *get_sysvec_byname(const char *);static void get_sysnames(unsigned long, unsigned long, unsigned long,			 char **, char **);static void determine_cpu_caches (unsigned int);static char command_line[COMMAND_LINE_SIZE];/* * The format of "screen_info" is strange, and due to early * i386-setup code. This is just enough to make the console * code think we're on a VGA color display. */struct screen_info screen_info = {	.orig_x = 0,	.orig_y = 25,	.orig_video_cols = 80,	.orig_video_lines = 25,	.orig_video_isVGA = 1,	.orig_video_points = 16};/* * The direct map I/O window, if any.  This should be the same * for all busses, since it's used by virt_to_bus. */unsigned long __direct_map_base;unsigned long __direct_map_size;/* * Declare all of the machine vectors. *//* GCC 2.7.2 (on alpha at least) is lame.  It does not support either    __attribute__((weak)) or #pragma weak.  Bypass it and talk directly   to the assembler.  */#define WEAK(X) \	extern struct alpha_machine_vector X; \	asm(".weak "#X)WEAK(alcor_mv);WEAK(alphabook1_mv);WEAK(avanti_mv);WEAK(cabriolet_mv);WEAK(clipper_mv);WEAK(dp264_mv);WEAK(eb164_mv);WEAK(eb64p_mv);WEAK(eb66_mv);WEAK(eb66p_mv);WEAK(eiger_mv);WEAK(jensen_mv);WEAK(lx164_mv);WEAK(lynx_mv);WEAK(marvel_ev7_mv);WEAK(miata_mv);WEAK(mikasa_mv);WEAK(mikasa_primo_mv);WEAK(monet_mv);WEAK(nautilus_mv);WEAK(noname_mv);WEAK(noritake_mv);WEAK(noritake_primo_mv);WEAK(p2k_mv);WEAK(pc164_mv);WEAK(privateer_mv);WEAK(rawhide_mv);WEAK(ruffian_mv);WEAK(rx164_mv);WEAK(sable_mv);WEAK(sable_gamma_mv);WEAK(shark_mv);WEAK(sx164_mv);WEAK(takara_mv);WEAK(titan_mv);WEAK(webbrick_mv);WEAK(wildfire_mv);WEAK(xl_mv);WEAK(xlt_mv);#undef WEAK/* * I/O resources inherited from PeeCees.  Except for perhaps the * turbochannel alphas, everyone has these on some sort of SuperIO chip. * * ??? If this becomes less standard, move the struct out into the * machine vector. */static void __initreserve_std_resources(void){	static struct resource standard_io_resources[] = {		{ .name = "rtc", .start = -1, .end = -1 },        	{ .name = "dma1", .start = 0x00, .end = 0x1f },        	{ .name = "pic1", .start = 0x20, .end = 0x3f },        	{ .name = "timer", .start = 0x40, .end = 0x5f },        	{ .name = "keyboard", .start = 0x60, .end = 0x6f },        	{ .name = "dma page reg", .start = 0x80, .end = 0x8f },        	{ .name = "pic2", .start = 0xa0, .end = 0xbf },        	{ .name = "dma2", .start = 0xc0, .end = 0xdf },	};	struct resource *io = &ioport_resource;	size_t i;	if (hose_head) {		struct pci_controller *hose;		for (hose = hose_head; hose; hose = hose->next)			if (hose->index == 0) {				io = hose->io_space;				break;			}	}	/* Fix up for the Jensen's queer RTC placement.  */	standard_io_resources[0].start = RTC_PORT(0);	standard_io_resources[0].end = RTC_PORT(0) + 0x10;	for (i = 0; i < N(standard_io_resources); ++i)		request_resource(io, standard_io_resources+i);}#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)#define PFN_PHYS(x)	((x) << PAGE_SHIFT)#define PFN_MAX		PFN_DOWN(0x80000000)#define for_each_mem_cluster(memdesc, cluster, i)		\	for ((cluster) = (memdesc)->cluster, (i) = 0;		\	     (i) < (memdesc)->numclusters; (i)++, (cluster)++)static unsigned long __initget_mem_size_limit(char *s){        unsigned long end = 0;        char *from = s;        end = simple_strtoul(from, &from, 0);        if ( *from == 'K' || *from == 'k' ) {                end = end << 10;                from++;        } else if ( *from == 'M' || *from == 'm' ) {                end = end << 20;                from++;        } else if ( *from == 'G' || *from == 'g' ) {                end = end << 30;                from++;        }        return end >> PAGE_SHIFT; /* Return the PFN of the limit. */}#ifdef CONFIG_BLK_DEV_INITRDvoid * __initmove_initrd(unsigned long mem_limit){	void *start;	unsigned long size;	size = initrd_end - initrd_start;	start = __alloc_bootmem(PAGE_ALIGN(size), PAGE_SIZE, 0);	if (!start || __pa(start) + size > mem_limit) {		initrd_start = initrd_end = 0;		return NULL;	}	memmove(start, (void *)initrd_start, size);	initrd_start = (unsigned long)start;	initrd_end = initrd_start + size;	printk("initrd moved to %p\n", start);	return start;}#endif#ifndef CONFIG_DISCONTIGMEMstatic void __initsetup_memory(void *kernel_end){	struct memclust_struct * cluster;	struct memdesc_struct * memdesc;	unsigned long start_kernel_pfn, end_kernel_pfn;	unsigned long bootmap_size, bootmap_pages, bootmap_start;	unsigned long start, end;	unsigned long i;	/* Find free clusters, and init and free the bootmem accordingly.  */	memdesc = (struct memdesc_struct *)	  (hwrpb->mddt_offset + (unsigned long) hwrpb);	for_each_mem_cluster(memdesc, cluster, i) {		printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n",		       i, cluster->usage, cluster->start_pfn,		       cluster->start_pfn + cluster->numpages);		/* Bit 0 is console/PALcode reserved.  Bit 1 is		   non-volatile memory -- we might want to mark		   this for later.  */		if (cluster->usage & 3)			continue;		end = cluster->start_pfn + cluster->numpages;		if (end > max_low_pfn)			max_low_pfn = end;	}	/*	 * Except for the NUMA systems (wildfire, marvel) all of the 	 * Alpha systems we run on support 32GB of memory or less.	 * Since the NUMA systems introduce large holes in memory addressing,	 * we can get into a situation where there is not enough contiguous	 * memory for the memory map. 	 *	 * Limit memory to the first 32GB to limit the NUMA systems to 	 * memory on their first node (wildfire) or 2 (marvel) to avoid 	 * not being able to produce the memory map. In order to access 	 * all of the memory on the NUMA systems, build with discontiguous	 * memory support.	 *	 * If the user specified a memory limit, let that memory limit stand.	 */	if (!mem_size_limit) 		mem_size_limit = (32ul * 1024 * 1024 * 1024) >> PAGE_SHIFT;	if (mem_size_limit && max_low_pfn >= mem_size_limit)	{		printk("setup: forcing memory size to %ldK (from %ldK).\n",		       mem_size_limit << (PAGE_SHIFT - 10),		       max_low_pfn    << (PAGE_SHIFT - 10));		max_low_pfn = mem_size_limit;	}	/* Find the bounds of kernel memory.  */	start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS);	end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end));	bootmap_start = -1; try_again:	if (max_low_pfn <= end_kernel_pfn)		panic("not enough memory to boot");	/* We need to know how many physically contiguous pages	   we'll need for the bootmap.  */	bootmap_pages = bootmem_bootmap_pages(max_low_pfn);	/* Now find a good region where to allocate the bootmap.  */	for_each_mem_cluster(memdesc, cluster, i) {		if (cluster->usage & 3)			continue;		start = cluster->start_pfn;		end = start + cluster->numpages;		if (start >= max_low_pfn)			continue;		if (end > max_low_pfn)			end = max_low_pfn;		if (start < start_kernel_pfn) {			if (end > end_kernel_pfn			    && end - end_kernel_pfn >= bootmap_pages) {				bootmap_start = end_kernel_pfn;				break;			} else if (end > start_kernel_pfn)				end = start_kernel_pfn;		} else if (start < end_kernel_pfn)			start = end_kernel_pfn;		if (end - start >= bootmap_pages) {			bootmap_start = start;			break;		}	}	if (bootmap_start == ~0UL) {		max_low_pfn >>= 1;		goto try_again;	}	/* Allocate the bootmap and mark the whole MM as reserved.  */	bootmap_size = init_bootmem(bootmap_start, max_low_pfn);	/* Mark the free regions.  */	for_each_mem_cluster(memdesc, cluster, i) {		if (cluster->usage & 3)			continue;		start = cluster->start_pfn;		end = cluster->start_pfn + cluster->numpages;		if (start >= max_low_pfn)			continue;		if (end > max_low_pfn)			end = max_low_pfn;		if (start < start_kernel_pfn) {			if (end > end_kernel_pfn) {				free_bootmem(PFN_PHYS(start),					     (PFN_PHYS(start_kernel_pfn)					      - PFN_PHYS(start)));				printk("freeing pages %ld:%ld\n",				       start, start_kernel_pfn);				start = end_kernel_pfn;			} else if (end > start_kernel_pfn)				end = start_kernel_pfn;		} else if (start < end_kernel_pfn)			start = end_kernel_pfn;		if (start >= end)			continue;		free_bootmem(PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start));		printk("freeing pages %ld:%ld\n", start, end);	}	/* Reserve the bootmap memory.  */	reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);	printk("reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size));#ifdef CONFIG_BLK_DEV_INITRD	initrd_start = INITRD_START;	if (initrd_start) {		initrd_end = initrd_start+INITRD_SIZE;		printk("Initial ramdisk at: 0x%p (%lu bytes)\n",		       (void *) initrd_start, INITRD_SIZE);		if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {			if (!move_initrd(PFN_PHYS(max_low_pfn)))				printk("initrd extends beyond end of memory "				       "(0x%08lx > 0x%p)\ndisabling initrd\n",				       initrd_end,				       phys_to_virt(PFN_PHYS(max_low_pfn)));		} else {			reserve_bootmem(virt_to_phys((void *)initrd_start),					INITRD_SIZE);		}	}#endif /* CONFIG_BLK_DEV_INITRD */}#elseextern void setup_memory(void *);#endif /* !CONFIG_DISCONTIGMEM */int __initpage_is_ram(unsigned long pfn){	struct memclust_struct * cluster;	struct memdesc_struct * memdesc;	unsigned long i;	memdesc = (struct memdesc_struct *)		(hwrpb->mddt_offset + (unsigned long) hwrpb);	for_each_mem_cluster(memdesc, cluster, i)	{		if (pfn >= cluster->start_pfn  &&		    pfn < cluster->start_pfn + cluster->numpages) {			return (cluster->usage & 3) ? 0 : 1;		}	}	return 0;}#undef PFN_UP#undef PFN_DOWN#undef PFN_PHYS#undef PFN_MAXvoid __initsetup_arch(char **cmdline_p){	extern char _end[];	struct alpha_machine_vector *vec = NULL;	struct percpu_struct *cpu;	char *type_name, *var_name, *p;	void *kernel_end = _end; /* end of kernel */	char *args = command_line;	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);	boot_cpuid = hard_smp_processor_id();        /*	 * Pre-process the system type to make sure it will be valid.	 *

⌨️ 快捷键说明

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