u-boot nand spl代码整体流程

/* SPL阶段函数调用过程 */

u-boot-spl.lds(arch/arm/cpu/arm/u-boot-spl.lds)

      |--> vectors.S(arch/arm/lib/vectors.S)

      |--> start.S(arch/arm/cpu/arm926ejs/start.S)

           |--> /*set SVC mode .. disable FIQ and IRQ*/

           |--> cpu_init_crit(arch/arm/cpu/armv7/start.S)

                 |--> /* flush D cache before disabling it*/

                 |--> /* disable MMU and D cache it, enable I cache if SYS_ICACHE_OFF is not defined*/

                 |--> lowlevel_init(arch/arm/cpu/arm926ejs/nuc970/lowlevel_init.S)  /* 板级初始化,设置栈空间 */

           |--> _main(arch/arm/lib/crt0.S )

                 |--> /* Set up initial C runtime environment and call board_init_f(0).*/

                 |--> board_init_f_alloc_reserve(common/init/board_init.c)

                 |--> board_init_f_init_reserve(common/init/board_init.c)

                 |--> board_init_f(common/spl/spl.c)

                      |--> spl_early_init(common/spl/spl.c)

                            |--> spl_common_init(true) (common/spl/spl.c)

                                  |--> gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);

                                 |--> gd->malloc_ptr = 0;

                                  |--> bootstage_init(u_boot_first_phase())(include/bootstage.c)

                                  |--> bootstage_unstash(#ifdef CONFIG_BOOTSTAGE_STASH) (include/bootstage.c)

                                  |--> bootstage_mark_name(include/bootstage.c)

|--> log_init(common/log.c)

                                  |--> fdtdec_setup()(lib/fdtdec.c)

                                       |--> gd->fdt_blob = board_fdt_blob_setup()(lib/fdtdec.c)

                                       |--> fdtdec_prepare_fdt() (lib/fdtdec.c)

|--> bootstage_start(include/bootstage.c)

|--> dm_init_and_scan(drivers/core/root.c)

|--> dm_init (drivers/core/root.c)

      //#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root) 创建头结点gd->uclass_root

|--> INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST) (drivers/core/root.c)

|--> device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST) (drivers/core/device.c)

      //lists_driver_lookup_name("root_driver")

|--> drv = lists_driver_lookup_name(info->name) (drivers/core/device.c)

      //通过上篇分析,此处得到的是uboot_list_2_driver_1的地址

      |--> struct driver *drv =ll_entry_start(struct driver, driver);

      //uboot_list_2_driver_3-uboot_list_2_driver_1即得到长度

      |--> const int n_ents = ll_entry_count(struct driver, driver)

      //遍历,通过name字段匹配,匹配成功得到driver结构体地址

      |--> for (entry = drv; entry != drv + n_ents; entry++)

|--> device_bind_common(drv, "root_driver", gd->dm_root) (drivers/core/device.c)

      //通过上面得到的drv中的id字段(UCLASS_ROOT)进行匹配,匹配成功得到对应的uclass_driver结构体地址

|--> uclass_get(drv->id, &uc)

|-->uc = uclass_find(id);

|-->return uclass_add(id, ucp);

      |--> uc->uc_drv = uc_drv; //uclass root的uclass_driver指向uclass_driver root

      |--> INIT_LIST_HEAD(&uc->sibling_node);

      |--> INIT_LIST_HEAD(&uc->dev_head);

      |--> list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);

|--> dev = calloc(1, sizeof(struct udevice))

/* put dev into parent's successor list */

|--> list_add_tail(&dev->sibling_node, &parent->child_head);

|--> ret = uclass_bind_device(dev);

/* if we fail to bind we remove device from successors and free it */

|--> DM_ROOT_NON_CONST->node =

|--> np_to_ofnode, offset_to_ofnode()

|--> device_probe (drivers/core/device.c)

|--> if (dev->flags & DM_FLAG_ACTIVATED)

|-->  device_ofdata_to_platdata (drivers/core/device.c)

|-->  /* Ensure all parents are probed */

|-->  seq = uclass_resolve_seq(dev) (drivers/core/uclass.c)

|-->  uclass_find_device_by_seq

|-->  dev->flags |= DM_FLAG_ACTIVATED

|-->  pinctrl_select_state

|-->  dev_power_domain_on

|-->  uclass_pre_probe_device

|-->  uclass_pre_probe_device

|-->  /* Only handle devices that have a valid ofnode */

|-->  clk_set_defaults

|-->  drv->probe

|-->  uclass_post_probe_device

|-->  pinctrl_select_state

|--> ret = dm_scan_platdata(pre_reloc_only); (drivers/core/root.c) //搜索使用宏U_BOOT_DEVICE定义的设备进行驱动匹配,也就是bind子节点

|--> ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only); (drivers/core/root.c) //在其他地方(设备树)搜索设备并进行驱动匹配,然后bind

      |--> dm_scan_fdt//在设备树种搜索设备并进行驱动匹配,然后bind

|--> ret = dm_scan_other(pre_reloc_only); (drivers/core/root.c)

|--> bootstage_accum(include/bootstage.c)

                            |--> gd->flags |= GD_FLG_SPL_EARLY_INIT (common/spl/spl.c)   

                      |--> preloader_console_init (common/spl/spl.c)

                            |--> gd->baudrate = CONFIG_BAUDRATE(common/spl/spl.c)

                            |--> serial_init (drivers/serail/serial-uclass.c)

                                  |--> serial_find_console_or_panic(drivers/serail/serial-uclass.c)

                                       |--> /* Live tree has support for stdout */

|--> ogd->cur_serial_dev <- uclass_get_device_by_ofnode

|--> ogd->cur_serial_dev <- serial_check_stdout

                                  |--> gd->flags |= GD_FLG_SERIAL_READY

                            |--> gd->have_console = 1

          

                 |--> board_init_r(common/spl/spl.c)

                      |--> spl_set_bd();gd->bd = &bdata /* gd是保存在r9寄存器的,即r9保存的是指向gdata的指针 */

                      |--> timer_init(arch/arm/cpu/armv7/sunxi/timer.c)  /* 初始化时钟 */

                      ret = bloblist_init();

                      ret = setup_spl_handoff();

                      |--> spl_board_init()

                      |--> initr_watchdog();

                      |--> dram_init_banksize();

                      |--> bootcount_inc();

                      |--> memset(&spl_image, '\0', sizeof(spl_image));

                      |--> board_boot_order(spl_boot_list);

                      |--> boot_from_devices(common/spl/spl.c)

                            |--> spl_ll_find_loader(common/spl/spl.c)

                                  |--> ll_entry_start(include/linker_lists.h)

                                       |--> SPL_LOAD_IMAGE_METHOD("NAND", 1, BOOT_DEVICE_NAND, spl_nand_load_image); (common/spl/spl_nand.c)

                                             |--> loader->load_image(spl_image, &bootdev); spl_nand_load_image (common/spl/spl_nand.c)

                                                  |--> nand_init(); (common/spl/spl_mmc.c)

                                                  |--> spl_get_load_buffer(0, sizeof(*header)); (common/spl/spl_mmc.c)

                                                  |--> spl_nand_load_element

                                                  |--> /* Load u-boot */spl_nand_load_element(spl_image, spl_nand_get_uboot_raw_page(), header);

                                                  |--> nand_deselect(); (common/spl/spl.c) /* 解析 header */

                      |--> spl_perform_fixups(&spl_image);

|--> ret = write_spl_handoff();

                      |--> ret = bloblist_finish(); /* 结束SPL过程,跳转到u-boot */

                      |--> bootstage_mark_name

                      |--> bootstage_stash

                      |--> spl_board_prepare_for_boot();

                      |--> jump_to_image_no_args(&spl_image);

posted @ 2020-08-01 07:31  liujunhuasd  阅读(683)  评论(0编辑  收藏  举报