asmlinkage void __init start_kernel(void) // init/main.c
+-- lockdep_init();
+-- smp_setup_processor_id();
+-- debug_objects_early_init();
+-- boot_init_stack_canary();
+-- cgroup_init_early();
+-- local_irq_disable();
+-- early_boot_irqs_disabled = true;
+-- tick_init();
+-- boot_cpu_init();
+-- page_address_init();
+-- setup_arch(&command_line); //arch/arm/kernel/setup.c
+-- setup_processor();
+-- mdesc = setup_machine_fdt(__atags_pointer);
+-- if (!mdesc)
mdesc = setup_machine_tags(machine_arch_type);
+-- init_tags.mem.start = PHYS_OFFSET;
+-- for_each_machine_desc(p){
if (nr == p->nr) {
mdesc = p;
break;
}
}
+-- if (__atags_pointer)
tags = phys_to_virt(__atags_pointer);
else if (mdesc->atag_offset)
tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
+-- if (tags->hdr.tag != ATAG_CORE) {
tags = (struct tag *)&init_tags;
}
+-- if (mdesc->fixup)
//machine_desc.fixup()
mdesc->fixup(tags, &from, &meminfo);
+-- if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
save_atags(tags);
parse_tags(tags);
}
+-- strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+-- machine_desc = mdesc;
+-- machine_name = mdesc->name;
+--if (mdesc->dma_zone_size){
extern unsigned long arm_dma_zone_size;
arm_dma_zone_size = mdesc->dma_zone_size;
}
+-- if (mdesc->restart_mode)
reboot_setup(&mdesc->restart_mode);
+-- init_mm.start_code = (unsigned long) _text;
+-- init_mm.end_code = (unsigned long) _etext;
+-- init_mm.end_data = (unsigned long) _edata;
+-- init_mm.brk = (unsigned long) _end;
+-- strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+-- *cmdline_p = cmd_line;
+-- parse_early_param();
+-- sort(&meminfo.bank, meminfo.nr_banks,
sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+-- sanity_check_meminfo();
+-- arm_memblock_init(&meminfo, mdesc);
+-- for (i = 0; i < mi->nr_banks; i++)
memblock_add(mi->bank[i].start, mi->bank[i].size);
+-- memblock_reserve(__pa(_stext), _end - _stext);
+-- if (phys_initrd_size &&
!memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
phys_initrd_start = phys_initrd_size = 0;
}
if (phys_initrd_size &&
memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
phys_initrd_start = phys_initrd_size = 0;
}
if (phys_initrd_size) {
memblock_reserve(phys_initrd_start, phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
+-- arm_mm_memblock_reserve();
+-- arm_dt_memblock_reserve();
/* reserve any platform specific memblock areas */
+-- if (mdesc->reserve)
mdesc->reserve(); //machine_desc.reserve()
+-- arm_memblock_steal_permitted = false;
+-- memblock_allow_resize();
+-- memblock_dump_all();
+-- paging_init(mdesc);
+-- memblock_set_current_limit(lowmem_limit);
+-- build_mem_type_table();
+-- prepare_page_table();
+-- map_lowmem();
+-- devicemaps_init(mdesc);
+-- vectors = early_alloc(PAGE_SIZE);
+-- early_trap_init(vectors);
+-- for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
+-- pmd_clear(pmd_off_k(addr));
+-- map.pfn = __phys_to_pfn(virt_to_phys(vectors));
+-- map.virtual = 0xffff0000;
+-- map.length = PAGE_SIZE;
+-- map.type = MT_HIGH_VECTORS;
+-- create_mapping(&map);
+-- if (!vectors_high()) {
map.virtual = 0;
map.type = MT_LOW_VECTORS;
create_mapping(&map);
}
+-- if (mdesc->map_io)
mdesc->map_io(); //machine_desc.map_io()
+-- local_flush_tlb_all();
+-- flush_cache_all();
+-- kmap_init();
+-- top_pmd = pmd_off_k(0xffff0000);
+-- zero_page = early_alloc(PAGE_SIZE);
+-- bootmem_init();
+-- empty_zero_page = virt_to_page(zero_page);
+-- __flush_dcache_page(NULL, empty_zero_page);
+-- request_standard_resources(mdesc);
+-- if (mdesc->restart)arm_pm_restart = mdesc->restart;
+-- unflatten_device_tree();
+-- if (is_smp())smp_init_cpus();
+-- reserve_crashkernel();
+-- tcm_init();
//./include/asm/mach/irq.h:24:
// extern void (*handle_arch_irq)(struct pt_regs *);
//./kernel/entry-armv.S:40: ldr r1, =handle_arch_irq
//./kernel/entry-armv.S:1159: .globl handle_arch_irq
//这个应该是中断处理的时候用的,具体暂时没看过
+-- handle_arch_irq = mdesc->handle_irq; //machine_desc.handle_irq()
+-- if (mdesc->init_early)
mdesc->init_early(); //machine_desc.init_early()
+-- mm_init_owner(&init_mm, &init_task);
+-- mm_init_cpumask(&init_mm);
+-- setup_command_line(command_line);
+-- setup_nr_cpu_ids();
+-- setup_per_cpu_areas();
+-- smp_prepare_boot_cpu();
+-- build_all_zonelists(NULL);
+-- page_alloc_init();
+-- printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
+-- parse_early_param();
+-- strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+-- parse_early_options(tmp_cmdline);
+-- parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
+-- parse_args("Booting kernel", static_command_line,
__start___param, __stop___param - __start___param,
0, 0, &unknown_bootoption);
+-- args = skip_spaces(args);
+-- while (*args)
ret = parse_one(param, val, doing, params, num,
min_level, max_level, unknown);
+-- for (i = 0; i < num_params; i++) {
if (parameq(param, params[i].name)) {
err = params[i].ops->set(val, ¶ms[i]);
}
}
+-- if (handle_unknown) {
//这里调用unknown_bootoption
//handle_unknown就是unknown_bootoption
return handle_unknown(param, val, doing);
+-- repair_env_string(param, val, unused);
+-- obsolete_checksetup(param)
+-- p = __setup_start;
do {
p->setup_func(line + n);
p++;
}while (p < __setup_end);
+-- if (val) {
/* Environment option */
unsigned int i;
for (i = 0; envp_init[i]; i++) {
if (i == MAX_INIT_ENVS) {
panic_later = "Too many
boot env vars at `%s'";
panic_param = param;
}
if (!strncmp(param, envp_init[i],
val - param))
break;
}
envp_init[i] = param;
} else {
/* Command line option */
unsigned int i;
for (i = 0; argv_init[i]; i++) {
if (i == MAX_INIT_ARGS) {
panic_later = "Too many
boot init vars at `%s'";
panic_param = param;
}
}
argv_init[i] = param;
}
+-- jump_label_init();
+-- setup_log_buf(0);
+-- pidhash_init();
+-- vfs_caches_init_early();
+-- sort_main_extable();
+-- trap_init();
+-- mm_init();
+-- sched_init();
+-- preempt_disable();
+-- if (!irqs_disabled()) {
printk(KERN_WARNING "start_kernel(): bug: interrupts were "
"enabled *very* early, fixing it\n");
local_irq_disable();
}
+-- idr_init_cache();
+-- perf_event_init();
+-- rcu_init();
+-- radix_tree_init();
+-- early_irq_init();
+-- init_IRQ();
+-- machine_desc->init_irq(); //machine_desc.init_irq()
+-- prio_tree_init();
+-- init_timers();
+-- hrtimers_init();
+-- softirq_init();
+-- timekeeping_init();
+-- time_init();
+-- system_timer = machine_desc->timer; //machine_desc.timer
+-- system_timer->init();
+-- sched_clock_postinit();
+-- profile_init();
+-- call_function_init();
+-- if (!irqs_disabled())
printk(KERN_CRIT "start_kernel(): bug: interrupts were "
"enabled early\n");
+-- early_boot_irqs_disabled = false;
+-- local_irq_enable();
+-- gfp_allowed_mask = __GFP_BITS_MASK;
+-- kmem_cache_init_late();
+-- console_init();
+-- if (panic_later)panic(panic_later, panic_param);
+-- lockdep_info();
+-- locking_selftest();
+-- page_cgroup_init();
+-- debug_objects_mem_init();
+-- kmemleak_init();
+-- setup_per_cpu_pageset();
+-- numa_policy_init();
+-- if (late_time_init)
late_time_init();
+-- sched_clock_init();
+-- calibrate_delay();
+-- pidmap_init();
+-- anon_vma_init();
+-- thread_info_cache_init();
+-- cred_init();
+-- fork_init(totalram_pages);
+-- proc_caches_init();
+-- buffer_init();
+-- key_init();
+-- security_init();
+-- dbg_late_init();
+-- vfs_caches_init(totalram_pages);
+-- signals_init();
+-- page_writeback_init();
+-- proc_root_init();
+-- cgroup_init();
+-- cpuset_init();
+-- taskstats_init_early();
+-- delayacct_init();
+-- check_bugs();
+-- acpi_early_init();
+-- sfi_init_late();
+-- ftrace_init();
+-- rest_init();
+-- rcu_scheduler_starting();
// 创建kernel_init进程
+-- kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
+-- numa_default_policy();
// 创建kthreadd进程
+-- pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
+-- rcu_read_lock();
+-- kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
+-- rcu_read_unlock();
+-- complete(&kthreadd_done);
+-- init_idle_bootup_task(current);
+-- schedule_preempt_disabled();
+-- cpu_idle();
static int __init kernel_init(void * unused)
+-- wait_for_completion(&kthreadd_done);
+-- set_mems_allowed(node_states[N_HIGH_MEMORY]);
+-- set_cpus_allowed_ptr(current, cpu_all_mask);
+-- cad_pid = task_pid(current);
+-- smp_prepare_cpus(setup_max_cpus);
+-- do_pre_smp_initcalls();
+-- lockup_detector_init();
+-- smp_init();
+-- sched_init_smp();
+-- do_basic_setup();
+-- cpuset_init_smp();
+-- usermodehelper_init();
+-- shmem_init();
+-- driver_init();
+-- init_irq_proc();
+-- do_ctors();
+-- usermodehelper_enable();
+-- do_initcalls();
+-- for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
+-- for (fn = initcall_levels[level];
fn < initcall_levels[level+1]; fn++)
+-- do_one_initcall(*fn);
+-- ret = fn();
//这里调用各个level的initcall函数;
//由arch_initcall(customize_machine);
//customize_machine()也是在这里调用的;
/*
customize_machine();
+-- if (machine_desc->init_machine)
machine_desc->init_machine();
*/
+-- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk(KERN_WARNING "Warning: unable to open an initial console.\n");
+-- (void) sys_dup(0);
+-- (void) sys_dup(0);
+-- if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
+-- if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
prepare_namespace();
+-- wait_for_device_probe();
+-- md_run_setup();
+-- if (saved_root_name[0]) {
root_device_name = saved_root_name;
if (!strncmp(root_device_name, "mtd", 3) ||
!strncmp(root_device_name, "ubi", 3)) {
mount_block_root(root_device_name, root_mountflags);
goto out;
}
ROOT_DEV = name_to_dev_t(root_device_name);
if (strncmp(root_device_name, "/dev/", 5) == 0)
root_device_name += 5;
}
+-- if (initrd_load())
goto out;
+-- mount_root();
+-- create_dev("/dev/root", ROOT_DEV);
+-- mount_block_root("/dev/root", root_mountflags);
+-- out :
devtmpfs_mount("dev");
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
}
+-- init_post();
+-- async_synchronize_full();
+-- free_initmem();
+-- mark_rodata_ro();
+-- system_state = SYSTEM_RUNNING;
+-- numa_default_policy();
+-- current->signal->flags |= SIGNAL_UNKILLABLE;
+-- if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
+-- if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
+-- run_init_process("/sbin/init");
+-- run_init_process("/etc/init");
+-- run_init_process("/bin/init");
+-- run_init_process("/bin/sh");
+-- panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
struct machine_desc {
unsigned int nr; /* architecture number */
const char *name; /* architecture name */
unsigned long atag_offset; /* tagged list (relative) */
const char *const *dt_compat; /* array of device tree
* 'compatible' strings */
unsigned int nr_irqs; /* number of IRQs */
#ifdef CONFIG_ZONE_DMA
unsigned long dma_zone_size; /* size of DMA-able area */
#endif
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned char reserve_lp0 :1; /* never has lp0 */
unsigned char reserve_lp1 :1; /* never has lp1 */
unsigned char reserve_lp2 :1; /* never has lp2 */
char restart_mode; /* default restart mode */
void (*fixup)(struct tag *, char **,
struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
void (*handle_irq)(struct pt_regs *);
#endif
void (*restart)(char, const char *);
};
MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
.fixup = msm8960_fixup,
.reserve = msm8960_reserve,
.map_io = msm8960_map_io,
.init_irq = msm8960_init_irq,
.timer = &msm_timer,
.handle_irq = gic_handle_irq,
.init_machine = msm8960_rumi3_init,
MACHINE_END
//各种initcall >>
//各个init函数的调用 >>
//各个device/driver在总线上注册 >>
//probe函数的调用>>
//物理设备的初始化/设备专属的数据结构的初始化/各种内核线程的创建>>
//响应:
//1.用户空间进行的各种系统调用
//2.各种外设产生的中断
//3.时钟中断(看门狗/电源管理)/进程调度