📄 setup.c
字号:
set_prefix((u32)(unsigned long) lc);}static void __initsetup_resources(void){ struct resource *res; int i; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { res = alloc_bootmem_low(sizeof(struct resource)); res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; switch (memory_chunk[i].type) { case CHUNK_READ_WRITE: res->name = "System RAM"; break; case CHUNK_READ_ONLY: res->name = "System ROM"; res->flags |= IORESOURCE_READONLY; break; default: res->name = "reserved"; } res->start = memory_chunk[i].addr; res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; request_resource(&iomem_resource, res); request_resource(res, &code_resource); request_resource(res, &data_resource); }}static void __initsetup_memory(void){ unsigned long bootmap_size; unsigned long start_pfn, end_pfn, init_pfn; unsigned long last_rw_end; int i; /* * partially used pages are not usable - thus * we are rounding upwards: */ start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; end_pfn = max_pfn = memory_end >> PAGE_SHIFT; /* Initialize storage key for kernel pages */ for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++) page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); /* * Initialize the boot-time allocator (with low memory only): */ bootmap_size = init_bootmem(start_pfn, end_pfn); /* * Register RAM areas with the bootmem allocator. */ last_rw_end = start_pfn; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { unsigned long start_chunk, end_chunk; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); start_chunk >>= PAGE_SHIFT; end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); end_chunk >>= PAGE_SHIFT; if (start_chunk < start_pfn) start_chunk = start_pfn; if (end_chunk > end_pfn) end_chunk = end_pfn; if (start_chunk < end_chunk) { /* Initialize storage key for RAM pages */ for (init_pfn = start_chunk ; init_pfn < end_chunk; init_pfn++) page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); free_bootmem(start_chunk << PAGE_SHIFT, (end_chunk - start_chunk) << PAGE_SHIFT); if (last_rw_end < start_chunk) add_memory_hole(last_rw_end, start_chunk - 1); last_rw_end = end_chunk; } } psw_set_key(PAGE_DEFAULT_KEY); if (last_rw_end < end_pfn - 1) add_memory_hole(last_rw_end, end_pfn - 1); /* * Reserve the bootmem bitmap itself as well. We do this in two * steps (first step was init_bootmem()) because this catches * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);#ifdef CONFIG_BLK_DEV_INITRD if (INITRD_START) { if (INITRD_START + INITRD_SIZE <= memory_end) { reserve_bootmem(INITRD_START, INITRD_SIZE); initrd_start = INITRD_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", initrd_start + INITRD_SIZE, memory_end); initrd_start = initrd_end = 0; } }#endif}/* * Setup function called from init/main.c just after the banner * was printed. */void __initsetup_arch(char **cmdline_p){ /* * print what head.S has found out about the machine */#ifndef CONFIG_ARCH_S390X printk((MACHINE_IS_VM) ? "We are running under VM (31 bit mode)\n" : "We are running native (31 bit mode)\n"); printk((MACHINE_HAS_IEEE) ? "This machine has an IEEE fpu\n" : "This machine has no IEEE fpu\n");#else /* CONFIG_ARCH_S390X */ printk((MACHINE_IS_VM) ? "We are running under VM (64 bit mode)\n" : "We are running native (64 bit mode)\n");#endif /* CONFIG_ARCH_S390X */ ROOT_DEV = Root_RAM0;#ifndef CONFIG_ARCH_S390X memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ /* * We need some free virtual space to be able to do vmalloc. * On a machine with 2GB memory we make sure that we have at * least 128 MB free space for vmalloc. */ if (memory_end > 1920*1024*1024) memory_end = 1920*1024*1024;#else /* CONFIG_ARCH_S390X */ memory_end = memory_size & ~0x200000UL; /* detected in head.s */#endif /* CONFIG_ARCH_S390X */ init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; parse_cmdline_early(cmdline_p); setup_memory(); setup_resources(); setup_lowcore(); cpu_init(); __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; /* * Create kernel page tables and switch to virtual addressing. */ paging_init(); /* Setup default console */ conmode_default();}void print_cpu_info(struct cpuinfo_S390 *cpuinfo){ printk("cpu %d "#ifdef CONFIG_SMP "phys_idx=%d "#endif "vers=%02X ident=%06X machine=%04X unused=%04X\n", cpuinfo->cpu_nr,#ifdef CONFIG_SMP cpuinfo->cpu_addr,#endif cpuinfo->cpu_id.version, cpuinfo->cpu_id.ident, cpuinfo->cpu_id.machine, cpuinfo->cpu_id.unused);}/* * show_cpuinfo - Get information on one CPU for use by procfs. */static int show_cpuinfo(struct seq_file *m, void *v){ struct cpuinfo_S390 *cpuinfo; unsigned long n = (unsigned long) v - 1; preempt_disable(); if (!n) { seq_printf(m, "vendor_id : IBM/S390\n" "# processors : %i\n" "bogomips per cpu: %lu.%02lu\n", num_online_cpus(), loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ))%100); } if (cpu_online(n)) {#ifdef CONFIG_SMP if (smp_processor_id() == n) cpuinfo = &S390_lowcore.cpu_data; else cpuinfo = &lowcore_ptr[n]->cpu_data;#else cpuinfo = &S390_lowcore.cpu_data;#endif seq_printf(m, "processor %li: " "version = %02X, " "identification = %06X, " "machine = %04X\n", n, cpuinfo->cpu_id.version, cpuinfo->cpu_id.ident, cpuinfo->cpu_id.machine); } preempt_enable(); return 0;}static void *c_start(struct seq_file *m, loff_t *pos){ return *pos < NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL;}static void *c_next(struct seq_file *m, void *v, loff_t *pos){ ++*pos; return c_start(m, pos);}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 = show_cpuinfo,};#define DEFINE_IPL_ATTR(_name, _format, _value) \static ssize_t ipl_##_name##_show(struct subsystem *subsys, \ char *page) \{ \ return sprintf(page, _format, _value); \} \static struct subsys_attribute ipl_##_name##_attr = \ __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long) IPL_PARMBLOCK_START->fcp.wwpn);DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long) IPL_PARMBLOCK_START->fcp.lun);DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long) IPL_PARMBLOCK_START->fcp.bootprog);DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long) IPL_PARMBLOCK_START->fcp.br_lba);enum ipl_type_type { ipl_type_unknown, ipl_type_ccw, ipl_type_fcp,};static enum ipl_type_typeget_ipl_type(void){ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; if (!IPL_DEVNO_VALID) return ipl_type_unknown; if (!IPL_PARMBLOCK_VALID) return ipl_type_ccw; if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION) return ipl_type_unknown; if (ipl->fcp.pbt != IPL_TYPE_FCP) return ipl_type_unknown; return ipl_type_fcp;}static ssize_tipl_type_show(struct subsystem *subsys, char *page){ switch (get_ipl_type()) { case ipl_type_ccw: return sprintf(page, "ccw\n"); case ipl_type_fcp: return sprintf(page, "fcp\n"); default: return sprintf(page, "unknown\n"); }}static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);static ssize_tipl_device_show(struct subsystem *subsys, char *page){ struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; switch (get_ipl_type()) { case ipl_type_ccw: return sprintf(page, "0.0.%04x\n", ipl_devno); case ipl_type_fcp: return sprintf(page, "0.0.%04x\n", ipl->fcp.devno); default: return 0; }}static struct subsys_attribute ipl_device_attr = __ATTR(device, S_IRUGO, ipl_device_show, NULL);static struct attribute *ipl_fcp_attrs[] = { &ipl_type_attr.attr, &ipl_device_attr.attr, &ipl_wwpn_attr.attr, &ipl_lun_attr.attr, &ipl_bootprog_attr.attr, &ipl_br_lba_attr.attr, NULL,};static struct attribute_group ipl_fcp_attr_group = { .attrs = ipl_fcp_attrs,};static struct attribute *ipl_ccw_attrs[] = { &ipl_type_attr.attr, &ipl_device_attr.attr, NULL,};static struct attribute_group ipl_ccw_attr_group = { .attrs = ipl_ccw_attrs,};static struct attribute *ipl_unknown_attrs[] = { &ipl_type_attr.attr, NULL,};static struct attribute_group ipl_unknown_attr_group = { .attrs = ipl_unknown_attrs,};static ssize_tipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count){ unsigned int size = IPL_PARMBLOCK_SIZE; if (off > size) return 0; if (off + count > size) count = size - off; memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count); return count;}static struct bin_attribute ipl_parameter_attr = { .attr = { .name = "binary_parameter", .mode = S_IRUGO, .owner = THIS_MODULE, }, .size = PAGE_SIZE, .read = &ipl_parameter_read,};static ssize_tipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count){ unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len; void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data; if (off > size) return 0; if (off + count > size) count = size - off; memcpy(buf, scp_data + off, count); return count;}static struct bin_attribute ipl_scp_data_attr = { .attr = { .name = "scp_data", .mode = S_IRUGO, .owner = THIS_MODULE, }, .size = PAGE_SIZE, .read = &ipl_scp_data_read,};static decl_subsys(ipl, NULL, NULL);static int __initipl_device_sysfs_register(void) { int rc; rc = firmware_register(&ipl_subsys); if (rc) return rc; switch (get_ipl_type()) { case ipl_type_ccw: sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group); break; case ipl_type_fcp: sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); sysfs_create_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr); sysfs_create_bin_file(&ipl_subsys.kset.kobj, &ipl_scp_data_attr); break; default: sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_unknown_attr_group); break; } return 0;}__initcall(ipl_device_sysfs_register);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -