setup.c
来自「linux2.6.16版本」· C语言 代码 · 共 1,413 行 · 第 1/3 页
C
1,413 行
/* * linux/arch/x86-64/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds * * Nov 2001 Dave Jones <davej@suse.de> * Forked from i386 setup code. * * $Id$ *//* * 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/initrd.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 <linux/crash_dump.h>#include <linux/root_dev.h>#include <linux/pci.h>#include <linux/acpi.h>#include <linux/kallsyms.h>#include <linux/edd.h>#include <linux/mmzone.h>#include <linux/kexec.h>#include <linux/cpufreq.h>#include <linux/dmi.h>#include <linux/dma-mapping.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 <video/edid.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>#include <asm/setup.h>#include <asm/mach_apic.h>#include <asm/numa.h>#include <asm/swiotlb.h>#include <asm/sections.h>#include <asm/gart-mapping.h>/* * Machine setup.. */struct cpuinfo_x86 boot_cpu_data __read_mostly;unsigned long mmu_cr4_features;int acpi_disabled;EXPORT_SYMBOL(acpi_disabled);#ifdef CONFIG_ACPIextern int __initdata acpi_ht;extern acpi_interrupt_flags acpi_sci_flags;int __initdata acpi_force = 0;#endifint acpi_numa __initdata;/* Boot loader ID as an integer, for the benefit of proc_dointvec */int bootloader_type;unsigned long saved_video_mode;/* * Setup options */struct screen_info screen_info;struct sys_desc_table_struct { unsigned short length; unsigned char table[0];};struct edid_info edid_info;struct e820map e820;extern int root_mountflags;char command_line[COMMAND_LINE_SIZE];struct resource standard_io_resources[] = { { .name = "dma1", .start = 0x00, .end = 0x1f, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "timer0", .start = 0x40, .end = 0x43, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "timer1", .start = 0x50, .end = 0x53, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "keyboard", .start = 0x60, .end = 0x6f, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "dma page reg", .start = 0x80, .end = 0x8f, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "dma2", .start = 0xc0, .end = 0xdf, .flags = IORESOURCE_BUSY | IORESOURCE_IO }, { .name = "fpu", .start = 0xf0, .end = 0xff, .flags = IORESOURCE_BUSY | IORESOURCE_IO }};#define STANDARD_IO_RESOURCES \ (sizeof standard_io_resources / sizeof standard_io_resources[0])#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)struct resource data_resource = { .name = "Kernel data", .start = 0, .end = 0, .flags = IORESOURCE_RAM,};struct resource code_resource = { .name = "Kernel code", .start = 0, .end = 0, .flags = IORESOURCE_RAM,};#define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)static struct resource system_rom_resource = { .name = "System ROM", .start = 0xf0000, .end = 0xfffff, .flags = IORESOURCE_ROM,};static struct resource extension_rom_resource = { .name = "Extension ROM", .start = 0xe0000, .end = 0xeffff, .flags = IORESOURCE_ROM,};static struct resource adapter_rom_resources[] = { { .name = "Adapter ROM", .start = 0xc8000, .end = 0, .flags = IORESOURCE_ROM }, { .name = "Adapter ROM", .start = 0, .end = 0, .flags = IORESOURCE_ROM }, { .name = "Adapter ROM", .start = 0, .end = 0, .flags = IORESOURCE_ROM }, { .name = "Adapter ROM", .start = 0, .end = 0, .flags = IORESOURCE_ROM }, { .name = "Adapter ROM", .start = 0, .end = 0, .flags = IORESOURCE_ROM }, { .name = "Adapter ROM", .start = 0, .end = 0, .flags = IORESOURCE_ROM }};#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_ROM,};static struct resource video_ram_resource = { .name = "Video RAM area", .start = 0xa0000, .end = 0xbffff, .flags = IORESOURCE_RAM,};#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 __init void parse_cmdline_early (char ** cmdline_p){ char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; int userdef = 0; for (;;) { if (c != ' ') goto next_char; #ifdef CONFIG_SMP /* * If the BIOS enumerates physical processors before logical, * maxcpus=N at enumeration-time can be used to disable HT. */ else if (!memcmp(from, "maxcpus=", 8)) { extern unsigned int maxcpus; maxcpus = simple_strtoul(from + 8, NULL, 0); }#endif#ifdef CONFIG_ACPI /* "acpi=off" disables both ACPI table parsing and interpreter init */ if (!memcmp(from, "acpi=off", 8)) disable_acpi(); if (!memcmp(from, "acpi=force", 10)) { /* add later when we do DMI horrors: */ acpi_force = 1; acpi_disabled = 0; } /* acpi=ht just means: do ACPI MADT parsing at bootup, but don't enable the full ACPI interpreter */ if (!memcmp(from, "acpi=ht", 7)) { if (!acpi_force) disable_acpi(); acpi_ht = 1; } else if (!memcmp(from, "pci=noacpi", 10)) acpi_disable_pci(); else if (!memcmp(from, "acpi=noirq", 10)) acpi_noirq_set(); else if (!memcmp(from, "acpi_sci=edge", 13)) acpi_sci_flags.trigger = 1; else if (!memcmp(from, "acpi_sci=level", 14)) acpi_sci_flags.trigger = 3; else if (!memcmp(from, "acpi_sci=high", 13)) acpi_sci_flags.polarity = 1; else if (!memcmp(from, "acpi_sci=low", 12)) acpi_sci_flags.polarity = 3; /* acpi=strict disables out-of-spec workarounds */ else if (!memcmp(from, "acpi=strict", 11)) { acpi_strict = 1; }#ifdef CONFIG_X86_IO_APIC else if (!memcmp(from, "acpi_skip_timer_override", 24)) acpi_skip_timer_override = 1;#endif#endif if (!memcmp(from, "disable_timer_pin_1", 19)) disable_timer_pin_1 = 1; if (!memcmp(from, "enable_timer_pin_1", 18)) disable_timer_pin_1 = -1; if (!memcmp(from, "nolapic", 7) || !memcmp(from, "disableapic", 11)) disable_apic = 1; /* Don't confuse with noapictimer */ if (!memcmp(from, "noapic", 6) && (from[6] == ' ' || from[6] == 0)) skip_ioapic_setup = 1; /* Make sure to not confuse with apic= */ if (!memcmp(from, "apic", 4) && (from[4] == ' ' || from[4] == 0)) { skip_ioapic_setup = 0; ioapic_force = 1; } if (!memcmp(from, "mem=", 4)) parse_memopt(from+4, &from); if (!memcmp(from, "memmap=", 7)) { /* exactmap option is for used defined memory */ if (!memcmp(from+7, "exactmap", 8)) {#ifdef CONFIG_CRASH_DUMP /* If we are doing a crash dump, we * still need to know the real mem * size before original memory map is * reset. */ saved_max_pfn = e820_end_of_ram();#endif from += 8+7; end_pfn_map = 0; e820.nr_map = 0; userdef = 1; } else { parse_memmapopt(from+7, &from); userdef = 1; } }#ifdef CONFIG_NUMA if (!memcmp(from, "numa=", 5)) numa_setup(from+5); #endif if (!memcmp(from,"iommu=",6)) { iommu_setup(from+6); } if (!memcmp(from,"oops=panic", 10)) panic_on_oops = 1; if (!memcmp(from, "noexec=", 7)) nonx_setup(from + 7);#ifdef CONFIG_KEXEC /* crashkernel=size@addr specifies the location to reserve for * a crash kernel. By reserving this memory we guarantee * that linux never set's it up as a DMA target. * Useful for holding code to do something appropriate * after a kernel panic. */ else if (!memcmp(from, "crashkernel=", 12)) { unsigned long size, base; size = memparse(from+12, &from); if (*from == '@') { base = memparse(from+1, &from); /* FIXME: Do I want a sanity check * to validate the memory range? */ crashk_res.start = base; crashk_res.end = base + size - 1; } }#endif#ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header * stored by the crashed kernel. This option will be passed * by kexec loader to the capture kernel. */ else if(!memcmp(from, "elfcorehdr=", 11)) elfcorehdr_addr = memparse(from+11, &from);#endif#ifdef CONFIG_HOTPLUG_CPU else if (!memcmp(from, "additional_cpus=", 16)) setup_additional_cpus(from+16);#endif next_char: c = *(from++); if (!c) break; if (COMMAND_LINE_SIZE <= ++len) break; *(to++) = c; } if (userdef) { printk(KERN_INFO "user-defined physical RAM map:\n"); e820_print_map("user"); } *to = '\0'; *cmdline_p = command_line;}#ifndef CONFIG_NUMAstatic void __initcontig_initmem_init(unsigned long start_pfn, unsigned long end_pfn){ 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(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); reserve_bootmem(bootmap, bootmap_size);} #endif/* Use inline assembly to define this because the nops are defined as inline assembly strings in the include files and we cannot get them easily into strings. */asm("\t.data\nk8nops: " K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 K8_NOP7 K8_NOP8); extern unsigned char k8nops[];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?