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

📄 setup.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  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/malloc.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>#ifdef CONFIG_BLK_DEV_INITRD#include <linux/blk.h>#endif#include <linux/notifier.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/pci.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;/* 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 init_IRQ(), as those places   are under our control.   By default, OFF; set it with a bootcommand arg of "srmcons".*/int srmcons_output = 0;/* Enforce a memory size limit; useful for testing. By default, none. */unsigned long mem_size_limit = 0;#ifdef CONFIG_ALPHA_GENERICstruct alpha_machine_vector alpha_mv;int alpha_using_srm;#endifunsigned char aux_device_present = 0xaa;#define N(a) (sizeof(a)/sizeof(a[0]))static struct alpha_machine_vector *get_sysvec(long, long, long);static struct alpha_machine_vector *get_sysvec_byname(const char *);static void get_sysnames(long, long, char **, char **);/* * This is setup by the secondary bootstrap loader.  Because * the zero page is zeroed out as soon as the vm system is * initialized, we need to copy things out into a more permanent * place. */#define PARAM			ZERO_PGE#define COMMAND_LINE		((char*)(PARAM + 0x0000))#define COMMAND_LINE_SIZE	256#define INITRD_START		(*(unsigned long *) (PARAM+0x100))#define INITRD_SIZE		(*(unsigned long *) (PARAM+0x108))static char command_line[COMMAND_LINE_SIZE];char saved_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(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(sx164_mv);WEAK(takara_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[] = {		{ "rtc", -1, -1 },        	{ "dma1", 0x00, 0x1f },        	{ "pic1", 0x20, 0x3f },        	{ "timer", 0x40, 0x5f },        	{ "keyboard", 0x60, 0x6f },        	{ "dma page reg", 0x80, 0x8f },        	{ "pic2", 0xa0, 0xbf },        	{ "dma2", 0xc0, 0xdf },	};	struct resource *io = &ioport_resource;	long i;	if (hose_head) {		struct pci_controler *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. */}static 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;	int 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 %d, 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;	}	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 == -1) {		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);#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))) {			printk("initrd extends beyond end of memory "			       "(0x%08lx > 0x%p)\ndisabling initrd\n",			       initrd_end,			       phys_to_virt(PFN_PHYS(max_low_pfn)));			initrd_start = initrd_end = 0;		} else {			reserve_bootmem(virt_to_phys((void *)initrd_start),					INITRD_SIZE);		}	}#endif /* CONFIG_BLK_DEV_INITRD */}int __initpage_is_ram(unsigned long pfn){	struct memclust_struct * cluster;	struct memdesc_struct * memdesc;	int 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_MAX#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)/* *      Manage the SRM callbacks as a "console". */static struct console srmcons;void __init register_srm_console(void){        register_console(&srmcons);}void __init unregister_srm_console(void){        unregister_console(&srmcons);}static void srm_console_write(struct console *co, const char *s,                                unsigned count){	srm_printk(s);}static kdev_t srm_console_device(struct console *c){  /* Huh? */        return MKDEV(TTY_MAJOR, 64 + c->index);}static int srm_console_wait_key(struct console *co){  /* Huh? */	return 1;}static int __init srm_console_setup(struct console *co, char *options){	return 1;}static struct console srmcons = {	name:		"srm0",	write:		srm_console_write,	device:		srm_console_device,	wait_key:	srm_console_wait_key,	setup:		srm_console_setup,	flags:		CON_PRINTBUFFER | CON_ENABLED, /* fake it out */	index:		-1,};#elsevoid __init register_srm_console(void){}void __init unregister_srm_console(void){}#endifvoid __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 */	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);	boot_cpuid = hard_smp_processor_id();	/* Register a call for panic conditions. */	notifier_chain_register(&panic_notifier_list, &alpha_panic_block);#ifdef CONFIG_ALPHA_GENERIC	/* Assume that we've booted from SRM if we havn't booted from MILO.	   Detect the later by looking for "MILO" in the system serial nr.  */	alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;#endif	/* If we are using SRM, we want to allow callbacks	   as early as possible, so do this NOW, and then	   they should work immediately thereafter.	*/	kernel_end = callback_init(kernel_end);	/* 	 * Locate the command line.	 */	/* Hack for Jensen... since we're restricted to 8 or 16 chars for	   boot flags depending on the boot mode, we need some shorthand.	   This should do for installation.  */	if (strcmp(COMMAND_LINE, "INSTALL") == 0) {		strcpy(command_line, "root=/dev/fd0 load_ramdisk=1");	} else {		strncpy(command_line, COMMAND_LINE, sizeof command_line);		command_line[sizeof(command_line)-1] = 0;	}	strcpy(saved_command_line, command_line);	*cmdline_p = command_line;	/* 	 * Process command-line arguments.	 */	for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) {		if (strncmp(p, "alpha_mv=", 9) == 0) {			vec = get_sysvec_byname(p+9);			continue;		}		if (strncmp(p, "cycle=", 6) == 0) {			est_cycle_freq = simple_strtol(p+6, NULL, 0);			continue;		}		if (strncmp(p, "mem=", 4) == 0) {			mem_size_limit = get_mem_size_limit(p+4);			continue;		}		if (strncmp(p, "srmcons", 7) == 0) {			srmcons_output = 1;			continue;		}	}	/* Replace the command line, now that we've killed it with strtok.  */	strcpy(command_line, saved_command_line);	/* If we want SRM console printk echoing early, do it now. */	if (alpha_using_srm && srmcons_output) {		register_srm_console();	}	/*	 * Indentify and reconfigure for the current system.	 */	get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,		     &type_name, &var_name);	if (*var_name == '0')		var_name = "";	if (!vec) {		cpu = (struct percpu_struct*)			((char*)hwrpb + hwrpb->processor_offset);		vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,				 cpu->type);	}	if (!vec) {		panic("Unsupported system type: %s%s%s (%ld %ld)\n",

⌨️ 快捷键说明

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