kernel startup

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.时钟中断(看门狗/电源管理)/进程调度
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值