zoukankan      html  css  js  c++  java
  • imx6的kernel3.4.15启动流程

    //最开始的定义为
    DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
        .smp        = smp_ops(imx_smp_ops),
        .map_io        = imx6q_map_io,
        .init_irq    = imx6q_init_irq,    //中断的板级初始化
        .init_machine    = imx6q_init_machine,    //
        .init_late      = imx6q_init_late,    
        .dt_compat    = imx6q_dt_compat,    //比较得到设备树
    MACHINE_END
    
    //后面函数都是在start_kernel中
    setup_arch
        setup_machine_fdt
            DT_MACHINE_START        //在这里定义一个machine描述符,编译的时候会放入.arch.info.init段中
            MACHINE_END
            of_flat_dt_match_machine    //找到最合适的machine描述符
            early_init_dt_scan_nodes    //找到几个比较重要的节点
                early_init_dt_scan_chosen    //找到 chosen 节点,并将值放入boot_command_line中
                early_init_dt_scan_root        //扫描根节点,获取 {size,address}-cells信息,并保存在dt_root_size_cells和dt_root_addr_cells全局变量中
                early_init_dt_scan_memory    //扫描DTB中的 memory node,并把相关信息保存在meminfo中,全局变量meminfo保存了系统内存相关的信息
        paging_init(mdesc)            //
            devicemaps_init(mdesc)
                mdesc->map_io    //这里就是调用了DT_MACHINE_START中的imx6q_map_io
            
        unflatten_device_tree    //需要将DTB转换成节点是 device_node 的树状结构,也就是把所有节点保存在C代码中的device_node中
            __unflatten_device_tree
                fdt_magic    //检查设备树magic
                fdt_totalsize    //检测大小
                fdt_version    //检测版本
                fdt_check_header    //检测头
                unflatten_dt_node    //第一轮的scan,主要目的是为了获取设备树的大小
                dt_alloc            //将获取的大小在内存中申请一段内存(device_node数量的大小)
                unflatten_dt_node    //第二轮scan,将设备树中所有信息挂在上一步申请内存中(以结构体device_node为链表)
        arm_dt_init_cpu_maps    //获取cpu的节点
        
    init_IRQ
        machine_desc->init_irq()    //这里也就是上面DT_MACHINE_START中的 imx6q_init_irq
            imx_gpc_check_dt
            irqchip_init
                of_irq_init        //遍历Device Tree,找到interrupt controller,并挂在intc_desc,然后系统开始匹配中断,一旦匹配上,进行中断初始化
    
    time_init    //时钟初始化,非常重要,在这里面对各种时钟倍频,分频操作
        of_clk_init
            matches = &__clk_of_table; //__clk_of_table就是保存clk结构体的内存,拿到后依次运行,我们在文件中定义了CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
                
    rest_init
        kernel_init
            kernel_init_freeable
                do_basic_setup
                    driver_init
                        of_core_init
                            for_each_of_allnodes    //从根节点轮训所有节点
                                __of_attach_node_sysfs    //sys/firmware/devicetree/base目录下面为设备树展开成sysfs的目录和二进制属性文件,所有的node节点就是一个目录,所有的property属性就是一个二进制属性文件。
    
                                
                    do_initcalls
                        while(0~7)    //会依次初始化0~7,其中3是架构,6是设备
                        do_initcall_level(3)    //在代码中有arch_initcall(customize_machine)
                            customize_machine
                                machine_desc->init_machine()    //这里就是DT_MACHINE_START定义的imx6q_init_machine 
                                    of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);    //加载platform设备
                                        for_each_child_of_node    //轮训根节点
                                            of_platform_bus_create    //创建platform总线, 这里会把i2c adapter之类的设备进行了初始化
                                    imx6q_enet_init
                                    imx_anatop_init
                                    imx6q_csi_mux_init
                                    imx6q_pm_init    //电源管理初始化
                                    imx6q_axi_init
                                    
                        do_initcall_level(6)    //在代码中的device_initcall/module_init/device_initcall都是这个等级的,为设备驱动
                        do_initcall_level(7)    //最低优先级的,late_initcall为这个等级,其中有late_initcall(init_machine_late)
                            init_machine_late
                                machine_desc->init_late()    //这里就是DT_MACHINE_START定义的 init_late
            try_to_run_init_process("/sbin/init")//尝试运行sbin/init
            try_to_run_init_process("/etc/init")
            try_to_run_init_process("/bin/init") 
            try_to_run_init_process("/bin/sh")
        kthreadd
        
        
    从上面流程可以看出chosen、memory、cpus节点未挂在device_node上
  • 相关阅读:
    使用StoryBoard执行动画
    导航控制器里边添加UIScrollView (automaticallyAdjustsScrollViewInsets)
    IOS中手势UIGestureRecognizer
    已知UIScrollView放大后的Frame和放大之前的Frame计算放大的瞄点坐标
    UIScrollView 在手指点击的坐标处放大
    [ZOJ3899]State Reversing
    多项式操作汇总
    [BZOJ4916]神犇和蒟蒻
    [BZOJ4176]Lucas的数论
    [BZOJ3309]DZY Loves Math
  • 原文地址:https://www.cnblogs.com/maogefff/p/9502545.html
Copyright © 2011-2022 走看看