一、board_init_f(common/board_f.c)

该函数位于common/board_f.c文件:

void board_init_f(ulong boot_flags)
{
#ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
    /*
     * For some archtectures, global data is initialized and used before
     * calling this function. The data should be preserved. For others,
     * CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack
     * here to host global data until relocation.
     */
    gd_t data;

    gd = &data;

    /*
     * Clear global data before it is accessed at debug print
     * in initcall_run_list. Otherwise the debug print probably
     * get the wrong vaule of gd->have_console.
     */
    zero_global_data();
#endif

    gd->flags = boot_flags;  #0x00
    gd->have_console = 0;    #0x00  

    if (initcall_run_list(init_sequence_f))
        hang();

#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
        !defined(CONFIG_EFI_APP)
    /* NOTREACHED - jump_to_copy() does not return */
    hang();
#endif
}

填充了flags和have_console字段后就执行一个初始化列表循环,这个循环里面有很多的函数,只要其中一个出错,u-boot启动就会停止。

initcall_run_list位于lib/initcall.c文件中:

int initcall_run_list(const init_fnc_t init_sequence[])
{
    const init_fnc_t *init_fnc_ptr;

    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        unsigned long reloc_ofs = 0;
        int ret;

        if (gd->flags & GD_FLG_RELOC)
            reloc_ofs = gd->reloc_off;
#ifdef CONFIG_EFI_APP
        reloc_ofs = (unsigned long)image_base;
#endif
        debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
        if (gd->flags & GD_FLG_RELOC)
            debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
        else
            debug("\n");
        ret = (*init_fnc_ptr)();
        if (ret) {
            printf("initcall sequence %p failed at call %p (err=%d)\n",
                   init_sequence,
                   (char *)*init_fnc_ptr - reloc_ofs, ret);
            return -1;
        }
    }
    return 0;
}

这里我们记录gd_t这个数据结构:

typedef struct global_data {
    bd_t *bd;
    unsigned long flags;
    unsigned int baudrate;
    unsigned long cpu_clk;    /* CPU clock in Hz!        */
    unsigned long bus_clk;
    /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
    unsigned long pci_clk;
    unsigned long mem_clk;
#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
    unsigned long fb_base;    /* Base address of framebuffer mem */
#endif
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
    unsigned long post_log_word;  /* Record POST activities */
    unsigned long post_log_res; /* success of POST test */
    unsigned long post_init_f_time;  /* When post_init_f started */
#endif
#ifdef CONFIG_BOARD_TYPES
    unsigned long board_type;
#endif
    unsigned long have_console;    /* serial_init() was called */
#ifdef CONFIG_PRE_CONSOLE_BUFFER
    unsigned long precon_buf_idx;    /* Pre-Console buffer index */
#endif
    unsigned long env_addr;    /* Address  of Environment struct */
    unsigned long env_valid;    /* Checksum of Environment valid? */

    unsigned long ram_top;    /* Top address of RAM used by U-Boot */

    unsigned long relocaddr;    /* Start address of U-Boot in RAM */
    phys_size_t ram_size;    /* RAM size */
#ifdef CONFIG_SYS_MEM_RESERVE_SECURE
#define MEM_RESERVE_SECURE_SECURED    0x1
#define MEM_RESERVE_SECURE_MAINTAINED    0x2
#define MEM_RESERVE_SECURE_ADDR_MASK    (~0x3)
    /*
     * Secure memory addr
     * This variable needs maintenance if the RAM base is not zero,
     * or if RAM splits into non-consecutive banks. It also has a
     * flag indicating the secure memory is marked as secure by MMU.
     * Flags used: 0x1 secured
     *             0x2 maintained
     */
    phys_addr_t secure_ram;
#endif
    unsigned long mon_len;    /* monitor len */
    unsigned long irq_sp;        /* irq stack pointer */
    unsigned long start_addr_sp;    /* start_addr_stackpointer */
    unsigned long reloc_off;
    struct global_data *new_gd;    /* relocated global data */

#ifdef CONFIG_DM
    struct udevice    *dm_root;    /* Root instance for Driver Model */
    struct udevice    *dm_root_f;    /* Pre-relocation root instance */
    struct list_head uclass_root;    /* Head of core tree */
#endif
#ifdef CONFIG_TIMER
    struct udevice    *timer;    /* Timer instance for Driver Model */
#endif

    const void *fdt_blob;    /* Our device tree, NULL if none */
    void *new_fdt;        /* Relocated FDT */
    unsigned long fdt_size;    /* Space reserved for relocated FDT */
    struct jt_funcs *jt;        /* jump table */
    char env_buf[32];    /* buffer for getenv() before reloc. */
#ifdef CONFIG_TRACE
    void        *trace_buff;    /* The trace buffer */
#endif
#if defined(CONFIG_SYS_I2C)
    int        cur_i2c_bus;    /* current used i2c bus */
#endif
#ifdef CONFIG_SYS_I2C_MXC
    void *srdata[10];
#endif
    unsigned long timebase_h;
    unsigned long timebase_l;
#ifdef CONFIG_SYS_MALLOC_F_LEN
    unsigned long malloc_base;    /* base address of early malloc() */
    unsigned long malloc_limit;    /* limit address */
    unsigned long malloc_ptr;    /* current address */
#endif
#ifdef CONFIG_PCI
    struct pci_controller *hose;    /* PCI hose for early use */
    phys_addr_t pci_ram_top;    /* top of region accessible to PCI */
#endif
#ifdef CONFIG_PCI_BOOTDELAY
    int pcidelay_done;
#endif
    struct udevice *cur_serial_dev;    /* current serial device */
    struct arch_global_data arch;    /* architecture-specific data */
#ifdef CONFIG_CONSOLE_RECORD
    struct membuff console_out;    /* console output */
    struct membuff console_in;    /* console input */
#endif
#ifdef CONFIG_DM_VIDEO
    ulong video_top;        /* Top of video frame buffer area */
    ulong video_bottom;        /* Bottom of video frame buffer area */
#endif
} gd_t;
#endif

/*
 * Global Data Flags - the top 16 bits are reserved for arch-specific flags
 */
#define GD_FLG_RELOC        0x00001    /* Code was relocated to RAM       */
#define GD_FLG_DEVINIT        0x00002    /* Devices have been initialized   */
#define GD_FLG_SILENT        0x00004    /* Silent mode               */
#define GD_FLG_POSTFAIL        0x00008    /* Critical POST test failed       */
#define GD_FLG_POSTSTOP        0x00010    /* POST seqeunce aborted       */
#define GD_FLG_LOGINIT        0x00020    /* Log Buffer has been initialized */
#define GD_FLG_DISABLE_CONSOLE    0x00040    /* Disable console (in & out)       */
#define GD_FLG_ENV_READY    0x00080    /* Env. imported into hash table   */
#define GD_FLG_SERIAL_READY    0x00100    /* Pre-reloc serial console ready  */
#define GD_FLG_FULL_MALLOC_INIT    0x00200    /* Full malloc() is ready       */
#define GD_FLG_SPL_INIT        0x00400    /* spl_init() has been called       */
#define GD_FLG_SKIP_RELOC    0x00800    /* Don't relocate */
#define GD_FLG_RECORD        0x01000    /* Record console */

#endif /* __ASM_GENERIC_GBL_DATA_H */

二、 init_sequence_f

init_sequence_f是一个函数指针数组,里面存放着各种初始化的函数指针,其中大部分函数只有定义了指定了宏才会生效,后面会针对其中比较重要的函数进行一一介绍。

static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_SANDBOX
    setup_ram_buf,
#endif
    setup_mon_len,
#ifdef CONFIG_OF_CONTROL
    fdtdec_setup,
#endif
#ifdef CONFIG_TRACE
    trace_early_init,
#endif
    initf_malloc,
    initf_console_record,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
    /* TODO: can this go into arch_cpu_init()? */
    probecpu,
#endif
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
    x86_fsp_init,
#endif
    arch_cpu_init,        /* basic arch cpu dependent setup */
    initf_dm,
    arch_cpu_init_dm,
    mark_bootstage,        /* need timer, go after init dm */
#if defined(CONFIG_BOARD_EARLY_INIT_F)
    board_early_init_f,
#endif
    /* TODO: can any of this go into arch_cpu_init()? */
#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
    get_clocks,        /* get CPU and bus clocks (etc.) */
#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
        && !defined(CONFIG_TQM885D)
    adjust_sdram_tbs_8xx,
#endif
    /* TODO: can we rename this to timer_init()? */
    init_timebase,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || \
        defined(CONFIG_BLACKFIN) || defined(CONFIG_NDS32) || \
        defined(CONFIG_SPARC)
    timer_init,        /* initialize timer */
#endif
#ifdef CONFIG_SYS_ALLOC_DPRAM
#if !defined(CONFIG_CPM2)
    dpram_init,
#endif
#endif
#if defined(CONFIG_BOARD_POSTCLK_INIT)
    board_postclk_init,
#endif
#if defined(CONFIG_SYS_FSL_CLK) || defined(CONFIG_M68K)
    get_clocks,
#endif
    env_init,        /* initialize environment */
#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
    /* get CPU and bus clocks according to the environment variable */
    get_clocks_866,
    /* adjust sdram refresh rate according to the new clock */
    sdram_adjust_866,
    init_timebase,
#endif
    init_baud_rate,        /* initialze baudrate settings */
    serial_init,        /* serial communications setup */
    console_init_f,        /* stage 1 init of console */
#ifdef CONFIG_SANDBOX
    sandbox_early_getopt_check,
#endif
#ifdef CONFIG_OF_CONTROL
    fdtdec_prepare_fdt,
#endif
    display_options,    /* say that we are here */
    display_text_info,    /* show debugging info if required */
#if defined(CONFIG_MPC8260)
    prt_8260_rsr,
    prt_8260_clks,
#endif /* CONFIG_MPC8260 */
#if defined(CONFIG_MPC83xx)
    prt_83xx_rsr,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
    checkcpu,
#endif
    print_cpuinfo,        /* display cpu info (and speed) */
#if defined(CONFIG_MPC5xxx)
    prt_mpc5xxx_clks,
#endif /* CONFIG_MPC5xxx */
#if defined(CONFIG_DISPLAY_BOARDINFO)
    show_board_info,
#endif
    INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
    misc_init_f,
#endif
    INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
    init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)
    init_func_spi,
#endif
    announce_dram_init,
    /* TODO: unify all these dram functions? */
#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_NDS32) || \
        defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32)
    dram_init,        /* configure available RAM banks */
#endif
#if defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_M68K)
    init_func_ram,
#endif
#ifdef CONFIG_POST
    post_init_f,
#endif
    INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_SYS_DRAM_TEST)
    testdram,
#endif /* CONFIG_SYS_DRAM_TEST */
    INIT_FUNC_WATCHDOG_RESET

#ifdef CONFIG_POST
    init_post,
#endif
    INIT_FUNC_WATCHDOG_RESET
    /*
     * Now that we have DRAM mapped and working, we can
     * relocate the code and continue running from DRAM.
     *
     * Reserve memory at end of RAM for (top down in that order):
     *  - area that won't get touched by U-Boot and Linux (optional)
     *  - kernel log buffer
     *  - protected RAM
     *  - LCD framebuffer
     *  - monitor code
     *  - board info struct
     */
    setup_dest_addr,
#if defined(CONFIG_BLACKFIN)
    /* Blackfin u-boot monitor should be on top of the ram */
    reserve_uboot,
#endif
#if defined(CONFIG_SPARC)
    reserve_prom,
#endif
#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
    reserve_logbuffer,
#endif
#ifdef CONFIG_PRAM
    reserve_pram,
#endif
    reserve_round_4k,
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
        defined(CONFIG_ARM)
    reserve_mmu,
#endif
#ifdef CONFIG_DM_VIDEO
    reserve_video,
#else
# ifdef CONFIG_LCD
    reserve_lcd,
# endif
    /* TODO: Why the dependency on CONFIG_8xx? */
# if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
        !defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
        !defined(CONFIG_BLACKFIN) && !defined(CONFIG_M68K)
    reserve_legacy_video,
# endif
#endif /* CONFIG_DM_VIDEO */
    reserve_trace,
#if !defined(CONFIG_BLACKFIN)
    reserve_uboot,
#endif
#ifndef CONFIG_SPL_BUILD
    reserve_malloc,
    reserve_board,
#endif
    setup_machine,
    reserve_global_data,
    reserve_fdt,
    reserve_arch,
    reserve_stacks,
    setup_dram_config,
    show_dram_config,
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
    setup_board_part1,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
    INIT_FUNC_WATCHDOG_RESET
    setup_board_part2,
#endif
    display_new_sp,
#ifdef CONFIG_SYS_EXTBDINFO
    setup_board_extra,
#endif
    INIT_FUNC_WATCHDOG_RESET
    reloc_fdt,
    setup_reloc,
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
    copy_uboot_to_ram,
    clear_bss,
    do_elf_reloc_fixups,
#endif
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
    jump_to_copy,
#endif
    NULL,
};
View Code

相关文章:

  • 2021-12-12
  • 2021-05-20
  • 2022-01-13
  • 2022-01-22
  • 2022-12-23
  • 2021-05-21
  • 2022-01-05
  • 2021-05-29
猜你喜欢
  • 2021-07-27
  • 2021-08-08
  • 2022-02-04
  • 2021-07-08
  • 2021-12-10
  • 2021-09-10
  • 2021-05-17
相关资源
相似解决方案