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 + -
显示快捷键?