start_kernel调用setup_arch()函数作为执行的第一步,在其中完成特定于体系结构的设置
1 void __init 2 setup_arch(char **cmdline_p) 3 { 4 extern char _end[]; 5 6 struct alpha_machine_vector *vec = NULL; 7 struct percpu_struct *cpu; 8 char *type_name, *var_name, *p; 9 void *kernel_end = _end; /* end of kernel */ 10 char *args = command_line; 11 12 hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr); 13 boot_cpuid = hard_smp_processor_id(); 14 15 /* 16 * Pre-process the system type to make sure it will be valid. 17 * 18 * This may restore real CABRIO and EB66+ family names, ie 19 * EB64+ and EB66. 20 * 21 * Oh, and "white box" AS800 (aka DIGITAL Server 3000 series) 22 * and AS1200 (DIGITAL Server 5000 series) have the type as 23 * the negative of the real one. 24 */ 25 if ((long)hwrpb->sys_type < 0) { 26 hwrpb->sys_type = -((long)hwrpb->sys_type); 27 hwrpb_update_checksum(hwrpb); 28 } 29 30 /* Register a call for panic conditions. */ 31 atomic_notifier_chain_register(&panic_notifier_list, 32 &alpha_panic_block); 33 34 #ifdef CONFIG_ALPHA_GENERIC 35 /* Assume that we've booted from SRM if we haven't booted from MILO. 36 Detect the later by looking for "MILO" in the system serial nr. */ 37 alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0; 38 #endif 39 40 /* If we are using SRM, we want to allow callbacks 41 as early as possible, so do this NOW, and then 42 they should work immediately thereafter. 43 */ 44 kernel_end = callback_init(kernel_end); 45 46 /* 47 * Locate the command line. 48 */ 49 /* Hack for Jensen... since we're restricted to 8 or 16 chars for 50 boot flags depending on the boot mode, we need some shorthand. 51 This should do for installation. */ 52 if (strcmp(COMMAND_LINE, "INSTALL") == 0) { 53 strlcpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof command_line); 54 } else { 55 strlcpy(command_line, COMMAND_LINE, sizeof command_line); 56 } 57 strcpy(boot_command_line, command_line); 58 *cmdline_p = command_line; 59 /* 60 * Process command-line arguments. 61 */ 62 while ((p = strsep(&args, " \t")) != NULL) { 63 if (!*p) continue; 64 if (strncmp(p, "alpha_mv=", 9) == 0) { 65 vec = get_sysvec_byname(p+9); 66 continue; 67 } 68 if (strncmp(p, "cycle=", 6) == 0) { 69 est_cycle_freq = simple_strtol(p+6, NULL, 0); 70 continue; 71 } 72 if (strncmp(p, "mem=", 4) == 0) { 73 mem_size_limit = get_mem_size_limit(p+4); 74 continue; 75 } 76 if (strncmp(p, "srmcons", 7) == 0) { 77 srmcons_output |= 1; 78 continue; 79 } 80 if (strncmp(p, "console=srm", 11) == 0) { 81 srmcons_output |= 2; 82 continue; 83 } 84 if (strncmp(p, "gartsize=", 9) == 0) { 85 alpha_agpgart_size = 86 get_mem_size_limit(p+9) << PAGE_SHIFT; 87 continue; 88 } 89 #ifdef CONFIG_VERBOSE_MCHECK 90 if (strncmp(p, "verbose_mcheck=", 15) == 0) { 91 alpha_verbose_mcheck = simple_strtol(p+15, NULL, 0); 92 continue; 93 } 94 #endif 95 } 96 /* Replace the command line, now that we've killed it with strsep. */ 97 strcpy(command_line, boot_command_line); 98 99 /* If we want SRM console printk echoing early, do it now. */ 100 if (alpha_using_srm && srmcons_output) { 101 register_srm_console(); 102 103 /* 104 * If "console=srm" was specified, clear the srmcons_output 105 * flag now so that time.c won't unregister_srm_console 106 */ 107 if (srmcons_output & 2) 108 srmcons_output = 0; 109 } 110 111 #ifdef CONFIG_MAGIC_SYSRQ 112 /* If we're using SRM, make sysrq-b halt back to the prom, 113 not auto-reboot. */ 114 if (alpha_using_srm) { 115 struct sysrq_key_op *op = __sysrq_get_key_op('b'); 116 op->handler = (void *) machine_halt; 117 } 118 #endif 119 120 /* 121 * Identify and reconfigure for the current system. 122 */ 123 cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); 124 125 get_sysnames(hwrpb->sys_type, hwrpb->sys_variation, 126 cpu->type, &type_name, &var_name); 127 if (*var_name == '0') 128 var_name = ""; 129 130 if (!vec) { 131 vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation, 132 cpu->type); 133 } 134 if (!vec) { 135 panic("Unsupported system type: %s%s%s (%ld %ld)\n", 136 type_name, (*var_name ? " variation " : ""), var_name, 137 hwrpb->sys_type, hwrpb->sys_variation); 138 } 139 if (vec != &alpha_mv) { 140 alpha_mv = *vec; 141 } 142 143 printk("Booting " 144 #ifdef CONFIG_ALPHA_GENERIC 145 "GENERIC " 146 #endif 147 "on %s%s%s using machine vector %s from %s\n", 148 type_name, (*var_name ? " variation " : ""), 149 var_name, alpha_mv.vector_name, 150 (alpha_using_srm ? "SRM" : "MILO")); 151 152 printk("Major Options: " 153 #ifdef CONFIG_SMP 154 "SMP " 155 #endif 156 #ifdef CONFIG_ALPHA_EV56 157 "EV56 " 158 #endif 159 #ifdef CONFIG_ALPHA_EV67 160 "EV67 " 161 #endif 162 #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS 163 "LEGACY_START " 164 #endif 165 #ifdef CONFIG_VERBOSE_MCHECK 166 "VERBOSE_MCHECK " 167 #endif 168 169 #ifdef CONFIG_DISCONTIGMEM 170 "DISCONTIGMEM " 171 #ifdef CONFIG_NUMA 172 "NUMA " 173 #endif 174 #endif 175 #ifdef CONFIG_DEBUG_SPINLOCK 176 "DEBUG_SPINLOCK " 177 #endif 178 #ifdef CONFIG_MAGIC_SYSRQ 179 "MAGIC_SYSRQ " 180 #endif 181 "\n"); 182 183 printk("Command line: %s\n", command_line); 184 185 /* 186 * Sync up the HAE. 187 * Save the SRM's current value for restoration. 188 */ 189 srm_hae = *alpha_mv.hae_register; 190 __set_hae(alpha_mv.hae_cache); 191 192 /* Reset enable correctable error reports. */ 193 wrmces(0x7); 194 195 /* Find our memory. */ 196 setup_memory(kernel_end); 197 198 /* First guess at cpu cache sizes. Do this before init_arch. */ 199 determine_cpu_caches(cpu->type); 200 201 /* Initialize the machine. Usually has to do with setting up 202 DMA windows and the like. */ 203 if (alpha_mv.init_arch) 204 alpha_mv.init_arch(); 205 /* Reserve standard resources. */ 206 reserve_std_resources(); 207 208 /* 209 * Give us a default console. TGA users will see nothing until 210 * chr_dev_init is called, rather late in the boot sequence. 211 */ 212 213 #ifdef CONFIG_VT 214 #if defined(CONFIG_VGA_CONSOLE) 215 conswitchp = &vga_con; 216 #elif defined(CONFIG_DUMMY_CONSOLE) 217 conswitchp = &dummy_con; 218 #endif 219 #endif 220 221 /* Default root filesystem to sda2. */ 222 ROOT_DEV = Root_SDA2; 223 224 #ifdef CONFIG_EISA 225 /* FIXME: only set this when we actually have EISA in this box? */ 226 EISA_bus = 1; 227 #endif 228 229 /* 230 * Check ASN in HWRPB for validity, report if bad. 231 * FIXME: how was this failing? Should we trust it instead, 232 * and copy the value into alpha_mv.max_asn? 233 */ 234 235 if (hwrpb->max_asn != MAX_ASN) { 236 printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn); 237 } 238 239 /* 240 * Identify the flock of penguins. 241 */ 242 #ifdef CONFIG_SMP 243 setup_smp(); 244 #endif 245 paging_init(); 246 }
先存档,分析见后续更新