Skip to the content.

u-boot启动详细的代码调用流程

u-boot.lds:(arch/arm/cpu/u-boot.lds)
    |-->_start:(arch/arm/lib/vectors.S)
        |-->reset(arch/arm/cpu/armv7/start.S)    
            |-->save_boot_params(arch/arm/cpu/armv7/start.S)        /* 将引导参数保存到内存中 */
                |-->save_boot_params_ret(arch/arm/cpu/armv7/start.S)
                    |-->cpu_init_cp15(arch/arm/cpu/armv7/start.S)   /* 初始化 */
                    |-->cpu_init_crit(arch/arm/cpu/armv7/start.S)
                        |-->lowlevel_init(arch/arm/cpu/armv7/lowlevel_init.S)
                    |-->_main(arch/arm/lib/crt0.S)
                        |-->board_init_f_alloc_reserve(common/init/board_init.c)/* 为u-boot的gd结构体分配空间 */
                        |-->board_init_f_init_reserve(common/init/board_init.c) /* 将gd结构体清零 */
                        |-->board_init_f(common/board_f.c)
                            |-->initcall_run_list(include/initcall.h)           /* 初始化序列函数 */
                                |-->init_sequence_f[](common/board_f.c)         /* 初始化序列函数数组 */
                                    |-->board_early_init_f(board/freescale/mx6ull_toto/mx6ull_toto.c)   /*初始化串口的IO配置 */
                                    |-->timer_init(arch/arm/imx-common/timer.c) /* 初始化内核定时器,为uboot提供时钟节拍 */
                                    |-->init_baud_rate(common/board_f.c)        /* 初始化波特率 */
                                    |-->serial_init(drivers/serial/serial.c)    /* 初始化串口通信设置 */
                                    |-->console_init_f(common/console.c)        /* 初始化控制台 */
                                    |-->...
                        |-->relocate_code(arch/arm/lib/relocate.S)      /* 主要完成镜像拷贝和重定位 */
                        |-->relocate_vectors(arch/arm/lib/relocate.S)   /* 重定位向量表 */
                        |-->board_init_r(common/board_r.c)              /* 板级初始化 */
                            |-->initcall_run_list(include/initcall.h)   /* 初始化序列函数 */
                                |-->init_sequence_r[](common/board_f.c) /* 序列函数 */
                                    |-->initr_reloc(common/board_r.c)   /* 设置 gd->flags,标记重定位完成 */
                                    |-->serial_initialize(drivers/serial/serial-uclass.c)   /* 初始化串口 */
                                        |-->serial_init(drivers/serial/serial-uclass.c)     /* 初始化串口 */
                                    |-->initr_mmc(common/board_r.c)                         /* 初始化emmc */
                                        |-->mmc_initialize(drivers/mmc/mmc.c)
                                            |-->mmc_do_preinit(drivers/mmc/mmc.c)
                                                |-->mmc_start_init(drivers/mmc/mmc.c)
                                    |-->console_init_r(common/console.c)                    /* 初始化控制台*/
                                    |-->interrupt_init(arch/arm/lib/interrupts.c)           /* 初始化中断*/
                                    |-->initr_net(common/board_r.c)                         /* 初始化网络设备*/
                                        |-->eth_initialize(net/eth-uclass.c)
                                            |-->eth_common_init(net/eth_common.c)
                                                |-->phy_init(drivers/net/phy/phy.c)
                                            |-->uclass_first_device_check(drivers/core/uclass.c)
                                                |-->uclass_find_first_device(drivers/core/uclass.c)
                                                |-->device_probe(drivers/core/device.c)
                                                    |-->device_of_to_plat(drivers/core/device.c)
                                                        |-->drv->of_to_plat
                                                            |-->fecmxc_of_to_plat(drivers/net/fec_mxc.c)    /* 解析设备树信息 */
                                                    |-->device_get_uclass_id(drivers/core/device.c)
                                                    |-->uclass_pre_probe_device(drivers/core/uclass.c)
                                                    |-->drv->probe(dev)
                                                        /* drivers/net/fec_mxc.c */
                                                        U_BOOT_DRIVER(fecmxc_gem) = {
                                                            .name       = "fecmxc",
                                                            .id         = UCLASS_ETH,
                                                            .of_match   = fecmxc_ids,
                                                            .of_to_plat = fecmxc_of_to_plat,
                                                            .probe      = fecmxc_probe,
                                                            .remove     = fecmxc_remove,
                                                            .ops        = &fecmxc_ops,
                                                            .priv_auto  = sizeof(struct fec_priv),
                                                            .plat_auto  = sizeof(struct eth_pdata),
                                                        };
                                                        |-->fecmxc_probe(drivers/net/fec_mxc.c) /* 探测和初始化 */
                                                            |-->fec_get_miibus(drivers/net/fec_mxc.c)
                                                                |-->mdio_alloc(drivers/net/fec_mxc.c)
                                                                |-->bus->read = fec_phy_read;
                                                                |-->bus->write = fec_phy_write;
                                                                |-->mdio_register(common/miiphyutil.c)
                                                                |-->fec_mii_setspeed(drivers/net/fec_mxc.c)
                                                            |-->fec_phy_init(drivers/net/fec_mxc.c)
                                                                |-->device_get_phy_addr(drivers/net/fec_mxc.c)
                                                                |-->phy_connect(drivers/net/phy/phy.c)
                                                                    |-->phy_find_by_mask(drivers/net/phy/phy.c)
                                                                        |-->bus->reset(bus)
                                                                        |-->get_phy_device_by_mask(drivers/net/phy/phy.c)
                                                                            |-->create_phy_by_mask(drivers/net/phy/phy.c)
                                                                                |-->phy_device_create(drivers/net/phy/phy.c)
                                                                                    |-->phy_probe(drivers/net/phy/phy.c)
                                                                    |-->phy_connect_dev(drivers/net/phy/phy.c)
                                                                        |-->phy_reset(drivers/net/phy/phy.c)
                                                                |-->phy_config(drivers/net/phy/phy.c)
                                                                    |-->board_phy_config(drivers/net/phy/phy.c)
                                                                        |-->phydev->drv->config(phydev)
                                                                            /*drivers/net/phy/smsc.c*/
                                                                            static struct phy_driver lan8710_driver = {
                                                                                .name       = "SMSC LAN8710/LAN8720",
                                                                                .uid        = 0x0007c0f0,
                                                                                .mask       = 0xffff0,
                                                                                .features   = PHY_BASIC_FEATURES,
                                                                                .config     = &genphy_config_aneg,
                                                                                .startup    = &genphy_startup,
                                                                                .shutdown   = &genphy_shutdown,
                                                                            };
                                                                            |-->genphy_config_aneg(drivers/net/phy/phy.c)
                                                                                |-->phy_reset(需要手动调用)(drivers/net/phy/phy.c)
                                                                                |-->genphy_setup_forced(drivers/net/phy/phy.c)
                                                                                |-->genphy_config_advert(drivers/net/phy/phy.c)
                                                                                |-->genphy_restart_aneg(drivers/net/phy/phy.c)
                                                    |-->uclass_post_probe_device(drivers/core/uclass.c)
                                                        |-->uc_drv->post_probe(drivers/core/uclass.c)
                                                            /*net/eth-uclass.c*/
                                                            UCLASS_DRIVER(ethernet) = {
                                                                .name       = "ethernet",
                                                                .id         = UCLASS_ETH,
                                                                .post_bind  = eth_post_bind,
                                                                .pre_unbind = eth_pre_unbind,
                                                                .post_probe = eth_post_probe,
                                                                .pre_remove = eth_pre_remove,
                                                                .priv_auto  = sizeof(struct eth_uclass_priv),
                                                                .per_device_auto    = sizeof(struct eth_device_priv),
                                                                .flags      = DM_UC_FLAG_SEQ_ALIAS,
                                                            };
                                                            |-->eth_post_probe(net/eth-uclass.c)
                                                                |-->eth_write_hwaddr(drivers/core/uclass.c)
                                    |-->...
                                    |-->run_main_loop(common/board_r.c)                 /* 主循环,处理命令 */
                                        |-->main_loop(common/main.c)
                                            |-->bootdelay_process(common/autoboot.c)    /* 读取环境变量bootdelay和bootcmd的内容 */
                                            |-->autoboot_command(common/autoboot.c)     /* 倒计时按下执行,没有操作执行bootcmd的参数 */
                                                |-->abortboot(common/autoboot.c)
                                                    |-->printf("Hit any key to stop autoboot: %2d ", bootdelay);
                                                    /* 到这里就是我们看到uboot延时3s启动内核的地方 */
                                            |-->cli_loop(common/cli.c)                  /* 倒计时按下space键,执行用户输入命令 */