一 setup_arch
setup_arch顾名思义就是架构相关的初始化函数,这里选取arm64结构进行分析。
1.0 setup_arch
定义在arch/arm64/kernel/setup.c中
void __init setup_arch(char **cmdline_p)
{
setup_processor(); // 检测处理器类型,并初始化处理器相关的底层变量
setup_machine_fdt(__fdt_pointer); // 获取device tree信息,并设置一些device tree相关全局变量信息
init_mm.start_code = (unsigned long) _text; // 记录kernel代码段的虚拟启始地址
init_mm.end_code = (unsigned long) _etext; // 记录kernel代码段的虚拟结束地址
init_mm.end_data = (unsigned long) _edata; // 记录kernel数据段的虚拟结束地址
init_mm.brk = (unsigned long) _end; // brk指向kernel全部段的虚拟结束地址
*cmdline_p = boot_command_line; // 将boot_command_line的地址保存到start_kernel局部指针变量cmdline_p中
parse_early_param(); // 解析需要'早期'处理的启动参数用
arm64_memblock_init(); // 初始化memblock,用于引导阶段的内存管理
paging_init(); // 初始化分页机制
request_standard_resources(); // 申请内核代码段和数据段内存资源
unflatten_device_tree(); // DTB转换成节点是device_node的树状结构
psci_init(); // Power State Coordination Interface,和多核启动相关,暂时没有用到
cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
cpu_read_bootcpu_ops(); // 获取cpu0的enable method
#ifdef CONFIG_SMP
smp_init_cpus(); // 获取除cpu0外的其他cpu信息,并将它们设为possible状态
smp_build_mpidr_hash(); // 生成MPIDR(cpu id) hash
#endif
#ifdef CONFIG_VT // 虚拟终端
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
#endif
}
1.1 setup_processor
定义在arch/arm64/kernel/setup.c中
static void __init setup_processor(void)
{
struct cpu_info *cpu_info;
/*
* locate processor in the list of supported processor
* types. The linker builds this table for us from the
* entries in arch/arm/mm/proc.S
*/
cpu_info = lookup_processor_type(read_cpuid_id());
if (!cpu_info) {
printk("CPU configuration botched (ID %08x), unable to continue.\n",
read_cpuid_id());
while (1);
}
cpu_name = cpu_info->cpu_name;
printk("CPU: %s [%08x] revision %d\n",
cpu_name, read_cpuid_id(), read_cpuid_id() & 15);
sprintf(init_utsname()->machine, "aarch64");
elf_hwcap = 0;
}
struct cpu_info cpu_table[] = {
{
.cpu_id_val = 0x000f0000,
.cpu_id_mask = 0x000f0000,
.cpu_name = "AArch64 Processor",
.cpu_setup = __cpu_setup,
},
{ /* Empty */ },
};
1.2 setup_machine_fdt
定义在arch/arm64/kernel/setup.c中
static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
struct boot_param_header *devtree;
unsigned long dt_root;
/* Check we have a non-NULL DT pointer */
if (!dt_phys) {
early_print("\n"
"Error: NULL or invalid device tree blob\n"
"The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
"\nPlease check your bootloader.\n");
while (true)
cpu_relax();
}
devtree = phys_to_virt(dt_phys);
/* Check device tree validity */
if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) {
early_print("\n"
"Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
"Expected 0x%x, found 0x%x\n"
"\nPlease check your bootloader.\n",
dt_phys, devtree, OF_DT_HEADER,
be32_to_cpu(devtre