linux 4.1设备树解析源码跟踪
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函数获取内核前期初始化所需的bootargscmd_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 blobunflattens the device-tree passed by the firmware, creating thetree of struct device_node. It also fills the “name” and “type”pointers of the nodes so the normal device-tree walking functionscan 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 treeand builds the cpu logical map array containing MPIDR values related tological cpusUpdates 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 areconsidered invalid logical map entries since the logical map mustcontain a list of MPIDR[23:0] values where MPIDR[31:24] mustread 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 cpuidx; 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 ina 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 havea reg property, the DT CPU list can be considered valid and thelogical map created in smp_setup_processor_id() can be overridden*/for (i 0; i cpuidx; 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);}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2430168.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!