📄 setup.c
字号:
from += len; p->fn(&from); while (*from != ' ' && *from != '\0') from++; break; } } } c = *from++; if (!c) break; if (COMMAND_LINE_SIZE <= ++len) break; *to++ = c; } *to = '\0'; *cmdline_p = command_line;}static void __initsetup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz){#ifdef CONFIG_BLK_DEV_RAM extern int rd_size, rd_image_start, rd_prompt, rd_doload; rd_image_start = image_start; rd_prompt = prompt; rd_doload = doload; if (rd_sz) rd_size = rd_sz;#endif}static void __initrequest_standard_resources(struct meminfo *mi, struct machine_desc *mdesc){ struct resource *res; int i; kernel_code.start = virt_to_phys(&_text); kernel_code.end = virt_to_phys(&_etext - 1); kernel_data.start = virt_to_phys(&__data_start); kernel_data.end = virt_to_phys(&_end - 1); for (i = 0; i < mi->nr_banks; i++) { unsigned long virt_start, virt_end; if (mi->bank[i].size == 0) continue; virt_start = __phys_to_virt(mi->bank[i].start); virt_end = virt_start + mi->bank[i].size - 1; res = alloc_bootmem_low(sizeof(*res)); res->name = "System RAM"; res->start = __virt_to_phys(virt_start); res->end = __virt_to_phys(virt_end); res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); if (kernel_code.start >= res->start && kernel_code.end <= res->end) request_resource(res, &kernel_code); if (kernel_data.start >= res->start && kernel_data.end <= res->end) request_resource(res, &kernel_data); } if (mdesc->video_start) { video_ram.start = mdesc->video_start; video_ram.end = mdesc->video_end; request_resource(&iomem_resource, &video_ram); } /* * Some machines don't have the possibility of ever * possessing lp0, lp1 or lp2 */ if (mdesc->reserve_lp0) request_resource(&ioport_resource, &lp0); if (mdesc->reserve_lp1) request_resource(&ioport_resource, &lp1); if (mdesc->reserve_lp2) request_resource(&ioport_resource, &lp2);}/* * Tag parsing. * * This is the new way of passing data to the kernel at boot time. Rather * than passing a fixed inflexible structure to the kernel, we pass a list * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE * tag for the list to be recognised (to distinguish the tagged list from * a param_struct). The list is terminated with a zero-length tag (this tag * is not parsed in any way). */static int __init parse_tag_core(const struct tag *tag){ if (tag->hdr.size > 2) { if ((tag->u.core.flags & 1) == 0) root_mountflags &= ~MS_RDONLY; ROOT_DEV = old_decode_dev(tag->u.core.rootdev); } return 0;}__tagtable(ATAG_CORE, parse_tag_core);static int __init parse_tag_mem32(const struct tag *tag){ if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_WARNING "Ignoring memory bank 0x%08x size %dKB\n", tag->u.mem.start, tag->u.mem.size / 1024); return -EINVAL; } arm_add_memory(tag->u.mem.start, tag->u.mem.size); return 0;}__tagtable(ATAG_MEM, parse_tag_mem32);#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)struct screen_info screen_info = { .orig_video_lines = 30, .orig_video_cols = 80, .orig_video_mode = 0, .orig_video_ega_bx = 0, .orig_video_isVGA = 1, .orig_video_points = 8};static int __init parse_tag_videotext(const struct tag *tag){ screen_info.orig_x = tag->u.videotext.x; screen_info.orig_y = tag->u.videotext.y; screen_info.orig_video_page = tag->u.videotext.video_page; screen_info.orig_video_mode = tag->u.videotext.video_mode; screen_info.orig_video_cols = tag->u.videotext.video_cols; screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; screen_info.orig_video_lines = tag->u.videotext.video_lines; screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; screen_info.orig_video_points = tag->u.videotext.video_points; return 0;}__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);#endifstatic int __init parse_tag_ramdisk(const struct tag *tag){ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, (tag->u.ramdisk.flags & 2) == 0, tag->u.ramdisk.start, tag->u.ramdisk.size); return 0;}__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);static int __init parse_tag_initrd(const struct tag *tag){ printk(KERN_WARNING "ATAG_INITRD is deprecated; " "please update your bootloader.\n"); phys_initrd_start = __virt_to_phys(tag->u.initrd.start); phys_initrd_size = tag->u.initrd.size; return 0;}__tagtable(ATAG_INITRD, parse_tag_initrd);static int __init parse_tag_initrd2(const struct tag *tag){ phys_initrd_start = tag->u.initrd.start; phys_initrd_size = tag->u.initrd.size; return 0;}__tagtable(ATAG_INITRD2, parse_tag_initrd2);static int __init parse_tag_serialnr(const struct tag *tag){ system_serial_low = tag->u.serialnr.low; system_serial_high = tag->u.serialnr.high; return 0;}__tagtable(ATAG_SERIAL, parse_tag_serialnr);static int __init parse_tag_revision(const struct tag *tag){ system_rev = tag->u.revision.rev; return 0;}__tagtable(ATAG_REVISION, parse_tag_revision);static int __init parse_tag_cmdline(const struct tag *tag){ strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); return 0;}__tagtable(ATAG_CMDLINE, parse_tag_cmdline);/* * Scan the tag table for this tag, and call its parse function. * The tag table is built by the linker from all the __tagtable * declarations. */static int __init parse_tag(const struct tag *tag){ extern struct tagtable __tagtable_begin, __tagtable_end; struct tagtable *t; for (t = &__tagtable_begin; t < &__tagtable_end; t++) if (tag->hdr.tag == t->tag) { t->parse(tag); break; } return t < &__tagtable_end;}/* * Parse all tags in the list, checking both the global and architecture * specific tag tables. */static void __init parse_tags(const struct tag *t){ for (; t->hdr.size; t = tag_next(t)) if (!parse_tag(t)) printk(KERN_WARNING "Ignoring unrecognised tag 0x%08x\n", t->hdr.tag);}/* * This holds our defaults. */static struct init_tags { struct tag_header hdr1; struct tag_core core; struct tag_header hdr2; struct tag_mem32 mem; struct tag_header hdr3;} init_tags __initdata = { { tag_size(tag_core), ATAG_CORE }, { 1, PAGE_SIZE, 0xff }, { tag_size(tag_mem32), ATAG_MEM }, { MEM_SIZE, PHYS_OFFSET }, { 0, ATAG_NONE }};static void (*init_machine)(void) __initdata;static int __init customize_machine(void){ /* customizes platform devices, or adds new ones */ if (init_machine) init_machine(); return 0;}arch_initcall(customize_machine);#ifdef CONFIG_KEXEC/* Physical addr of where the boot params should be for this machine */extern unsigned long kexec_boot_params_address;/* Physical addr of the buffer into which the boot params are copied */extern unsigned long kexec_boot_params_copy;/* Pointer to the boot params buffer, for manipulation and display */unsigned long kexec_boot_params;EXPORT_SYMBOL(kexec_boot_params);/* The buffer itself - make sure it is sized correctly */static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];#endifvoid __init setup_arch(char **cmdline_p){ struct tag *tags = (struct tag *)&init_tags; struct machine_desc *mdesc; char *from = default_command_line; setup_processor(); mdesc = setup_machine(machine_arch_type); machine_name = mdesc->name; if (mdesc->soft_reboot) reboot_setup("s"); if (__atags_pointer) tags = phys_to_virt(__atags_pointer); else if (mdesc->boot_params) tags = phys_to_virt(mdesc->boot_params);#ifdef CONFIG_KEXEC kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf); kexec_boot_params = (unsigned long)kexec_boot_params_buf; if (__atags_pointer) { kexec_boot_params_address = __atags_pointer; memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); } else if (mdesc->boot_params) { kexec_boot_params_address = mdesc->boot_params; memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE); }#endif /* * If we have the old style parameters, convert them to * a tag list. */ if (tags->hdr.tag != ATAG_CORE) convert_to_tag_list(tags); if (tags->hdr.tag != ATAG_CORE) tags = (struct tag *)&init_tags; if (mdesc->fixup) mdesc->fixup(mdesc, tags, &from, &meminfo); if (tags->hdr.tag == ATAG_CORE) { if (meminfo.nr_banks != 0) squash_mem_tags(tags); parse_tags(tags); } 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; memcpy(boot_command_line, from, COMMAND_LINE_SIZE); boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; parse_cmdline(cmdline_p, from); paging_init(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc);#ifdef CONFIG_SMP smp_init_cpus();#endif cpu_init(); /* * Set up various architecture-specific pointers */ init_arch_irq = mdesc->init_irq; system_timer = mdesc->timer; init_machine = mdesc->init_machine;#ifdef CONFIG_VT#if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con;#elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con;#endif#endif}static int __init topology_init(void){ int cpu; for_each_possible_cpu(cpu) { struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); cpuinfo->cpu.hotpluggable = 1; register_cpu(&cpuinfo->cpu, cpu); } return 0;}subsys_initcall(topology_init);static const char *hwcap_str[] = { "swp", "half", "thumb", "26bit", "fastmult", "fpa", "vfp", "edsp", "java", "iwmmxt", "crunch", NULL};static voidc_show_cache(struct seq_file *m, const char *type, unsigned int cache){ unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); seq_printf(m, "%s size\t\t: %d\n" "%s assoc\t\t: %d\n" "%s line length\t: %d\n" "%s sets\t\t: %d\n", type, mult << (8 + CACHE_SIZE(cache)), type, (mult << CACHE_ASSOC(cache)) >> 1, type, 8 << CACHE_LINE(cache), type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) - CACHE_LINE(cache)));}static int c_show(struct seq_file *m, void *v){ int i; seq_printf(m, "Processor\t: %s rev %d (%s)\n", cpu_name, (int)processor_id & 15, elf_platform);#if defined(CONFIG_SMP) for_each_online_cpu(i) { /* * glibc reads /proc/cpuinfo to determine the number of * online processors, looking for lines beginning with * "processor". Give glibc what it expects. */ seq_printf(m, "processor\t: %d\n", i); seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); }#else /* CONFIG_SMP */ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000/HZ), (loops_per_jiffy / (5000/HZ)) % 100);#endif /* dump out the processor features */ seq_puts(m, "Features\t: "); for (i = 0; hwcap_str[i]; i++) if (elf_hwcap & (1 << i)) seq_printf(m, "%s ", hwcap_str[i]); seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24); seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]); if ((processor_id & 0x0008f000) == 0x00000000) { /* pre-ARM7 */ seq_printf(m, "CPU part\t: %07x\n", processor_id >> 4); } else { if ((processor_id & 0x0008f000) == 0x00007000) { /* ARM7 */ seq_printf(m, "CPU variant\t: 0x%02x\n", (processor_id >> 16) & 127); } else { /* post-ARM7 */ seq_printf(m, "CPU variant\t: 0x%x\n", (processor_id >> 20) & 15); } seq_printf(m, "CPU part\t: 0x%03x\n", (processor_id >> 4) & 0xfff); } seq_printf(m, "CPU revision\t: %d\n", processor_id & 15); { unsigned int cache_info = read_cpuid(CPUID_CACHETYPE); if (cache_info != processor_id) { seq_printf(m, "Cache type\t: %s\n" "Cache clean\t: %s\n" "Cache lockdown\t: %s\n" "Cache format\t: %s\n", cache_types[CACHE_TYPE(cache_info)], cache_clean[CACHE_TYPE(cache_info)], cache_lockdown[CACHE_TYPE(cache_info)], CACHE_S(cache_info) ? "Harvard" : "Unified"); if (CACHE_S(cache_info)) { c_show_cache(m, "I", CACHE_ISIZE(cache_info)); c_show_cache(m, "D", CACHE_DSIZE(cache_info)); } else { c_show_cache(m, "Cache", CACHE_ISIZE(cache_info)); } } } seq_puts(m, "\n"); seq_printf(m, "Hardware\t: %s\n", machine_name); seq_printf(m, "Revision\t: %04x\n", system_rev); seq_printf(m, "Serial\t\t: %08x%08x\n", system_serial_high, system_serial_low); return 0;}static void *c_start(struct seq_file *m, loff_t *pos){ return *pos < 1 ? (void *)1 : NULL;}static void *c_next(struct seq_file *m, void *v, loff_t *pos){ ++*pos; return NULL;}static void c_stop(struct seq_file *m, void *v){}struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, .show = c_show};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -