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

📄 setup.c

📁 一个2.4.21版本的嵌入式linux内核
💻 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>#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/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 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.4.20), 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;#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, long, char **, char **);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(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[] = {		{ "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_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(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(KERN_INFO "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;	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;	}	/*	 * 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 == -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;

⌨️ 快捷键说明

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