asmlinkage __visible void __init start_kernel(void){    char *command_line;    setup_arch(&command_line);    setup_command_line(command_line);}//////////////////////////////////////////////////////////////////// //这个setup_arch就是各个架构自己的设置函数,哪个参与了编译就调用哪个,arm架构应当是arch/arm/kernel/setup.c中的 setup_arch。void __init setup_arch(char **cmdline_p){    const struct machine_desc *mdesc;    setup_processor();////setup_machine_fdt函数获取内核前期初始化所需的bootargs,cmd_line等系统引导参数   //__atags_pointer是bootloader传递参数的物理地址      mdesc = setup_machine_fdt(__atags_pointer);    if (!mdesc)        mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);    /* populate cmd_line too for later use, preserving boot_command_line */    strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);//这是setup_arch的参数出参赋值    *cmdline_p = cmd_line;    parse_early_param();////解析设备树     unflatten_device_tree();    arm_dt_init_cpu_maps();    psci_init();    if (!is_smp())        hyp_mode_check();    reserve_crashkernel();    if (mdesc->init_early)        mdesc->init_early();}/////////////////////////////////////** * unflatten_device_tree - create tree of device_nodes from flat blob * * unflattens the device-tree passed by the firmware, creating the * tree of struct device_node. It also fills the "name" and "type" * pointers of the nodes so the normal device-tree walking functions * can be used. */void __init unflatten_device_tree(void){    __unflatten_device_tree(initial_boot_params, &of_root,                early_init_dt_alloc_memory_arch);    /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */    of_alias_scan(early_init_dt_alloc_memory_arch);}////////////////////////////////////////////////////* * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree * and builds the cpu logical map array containing MPIDR values related to * logical cpus * * Updates the cpu possible mask with the number of parsed cpu nodes */void __init arm_dt_init_cpu_maps(void){    /*     * Temp logical map is initialized with UINT_MAX values that are     * considered invalid logical map entries since the logical map must     * contain a list of MPIDR[23:0] values where MPIDR[31:24] must     * read as 0.     */    struct device_node *cpu, *cpus;    int found_method = 0;    u32 i, j, cpuidx = 1;    u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;    u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID };    bool bootcpu_valid = false;    cpus = of_find_node_by_path("/cpus");    if (!cpus)        return;    for_each_child_of_node(cpus, cpu) {        u32 hwid;        if (of_node_cmp(cpu->type, "cpu"))            continue;        pr_debug(" * %s...\n", cpu->full_name);        /*         * A device tree containing CPU nodes with missing "reg"         * properties is considered invalid to build the         * cpu_logical_map.         */        if (of_property_read_u32(cpu, "reg", &hwid)) {            pr_debug(" * %s missing reg property\n",                     cpu->full_name);            return;        }        /*         * 8 MSBs must be set to 0 in the DT since the reg property         * defines the MPIDR[23:0].         */        if (hwid & ~MPIDR_HWID_BITMASK)            return;        /*         * Duplicate MPIDRs are a recipe for disaster.         * Scan all initialized entries and check for         * duplicates. If any is found just bail out.         * temp values were initialized to UINT_MAX         * to avoid matching valid MPIDR[23:0] values.         */        for (j = 0; j            if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg "                             "properties in the DT\n"))                return;        /*         * Build a stashed array of MPIDR values. Numbering scheme         * requires that if detected the boot CPU must be assigned         * logical id 0. Other CPUs get sequential indexes starting         * from 1. If a CPU node with a reg property matching the         * boot CPU MPIDR is detected, this is recorded so that the         * logical map built from DT is validated and can be used         * to override the map created in smp_setup_processor_id().         */        if (hwid == mpidr) {            i = 0;            bootcpu_valid = true;        } else {            i = cpuidx++;        }        if (WARN(cpuidx > nr_cpu_ids, "DT /cpu %u nodes greater than "                           "max cores %u, capping them\n",                           cpuidx, nr_cpu_ids)) {            cpuidx = nr_cpu_ids;            break;        }        tmp_map[i] = hwid;        if (!found_method)            found_method = set_smp_ops_by_method(cpu);    }    /*     * Fallback to an enable-method in the cpus node if nothing found in     * a cpu node.     */    if (!found_method)        set_smp_ops_by_method(cpus);    if (!bootcpu_valid) {        pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");        return;    }    /*     * Since the boot CPU node contains proper data, and all nodes have     * a reg property, the DT CPU list can be considered valid and the     * logical map created in smp_setup_processor_id() can be overridden     */    for (i = 0; i        set_cpu_possible(i, true);        cpu_logical_map(i) = tmp_map[i];        pr_debug("cpu logical map 0x%x\n", cpu_logical_map(i));    }}///////////////////////////////////////////////////////////////static const struct of_device_id psci_of_match[] __initconst = {    { .compatible = "arm,psci", .data = psci_0_1_init},    { .compatible = "arm,psci-0.2", .data = psci_0_2_init},    {},};int __init psci_init(void){    struct device_node *np;    const struct of_device_id *matched_np;    psci_initcall_t init_fn;    np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);    if (!np)        return -ENODEV;    init_fn = (psci_initcall_t)matched_np->data;    return init_fn(np);}
12-28 12:20