Uboot 2017.01 Start-up process analysis

Source: Internet
Author: User
Tags spl
Preface
2017.01 Uboot contains two stages of start-up, one is SPL-initiated, and the other is a normal start-up we call the second stage of Uboot. Of course, we can also choose to use SPL and not to use it. In the
process of compiling, the second stage Uboot is compiled first, and then the SPL is compiled. These two phases are compiled at the time of separation.
have different configurations, so macros in many places are not the same as SPL. And the linked files are inconsistent.
so next, we will be divided into two parts for analysis.
SPL Start
In the am437x platform, the actual SPL start-up is the MLO start-up phase. Its operating space is on-chip dram, so there is a tighter limit to its size.
Typically, after the basic device is initialized with SPL, the second-stage uboot load is performed in SDRAM.
First Stage: schema-related initialization
Its source code is located in Arch/arm/cpu/armv7/start.s.
The key invocation relationships are as follows:
call: Cpu_init_crit
        b   lowlevel_init
            ==>arch/arm/cpu/armv7/lowlevel_init. S
                b s_init 
Phase II: Initialization associated with the SOC underlying

After the first phase of initialization is completed, the s_init function is called, and the source code for its implementation is ARCH/ARM/MACH-OMAP2/AN33XX/BORAD.C.
The function calls a function, rtc_only (), and then returns to the Lowlevel_init function.
At this point, Lowlevel_init has completed his task and returned to the Cpu_init_crit.
However, the work of the Cpu_init_crit function was all done and then returned to start. s, and then the
b _main

And this _main function is located at:
Arch/arm/lib/crt0. S medium
In the _main function, a cross-era function is called.
Board_init_f (ARCH/ARM/MACH-OMAP2/AM33XX/BORAD.C) Phase III: board level initialization

Above, we can know that the _main function calls Board_init_f. In fact, this function is a function associated with the board level.
However, in SPL startup, he points to the following function:

void Board_init_f (ULONG dummy)
{
    early_system_init ();
    Board_early_init_f ();
    Sdram_init ();
    /* Dram_init must store complete ramsize in Gd->ram_size */
    gd->ram_size = get_ram_size (
            (void *) Config_sys _sdram_base,
            config_max_ram_bank_size);
}

The Sdram_ini () is the key code that initializes the SDRAM, so if we have our own board, we can also implement the Sdram_init function to initialize the SDRAM of our board.

The invocation relationship is as follows:
Board_init_f
==>early_system_init ()
==>set_uart_mux_conf (); Set the appropriate PIN for the serial port
==>board_early_init_f (); Different boards can implement this function.
==>
==>sdram_init (); Initialize SDRAM

After executing Borad_init_f, go back to _main
This time, will go to execute SPL_RELOCATE_STACK_GD
Reposition the Global_data in the stack.

If Config_spl_stack_r is defined, the Global_data object previously in-chip memory is relocated to the SDRAM, and the stack pointer points to an address in the SDRAM
Finally, the Borad_init_r function is called:

Borad_init_r (COMMON/SPL/SPL.C)
    ==>spl_board_init ();    Initialize the serial port
    ==> if (boot_from_devices (&spl_image, Spl_boot_list,
                  array_size (spl_boot_list))) {
                puts ("spl:failed to boot from all boot devices\n");
                Hang ();
            }
            = = Traverse loader to see which loader matches the device.
            ==> spl_load_image
                ==>spl_mmc_load_image
                    ==>spl_mmc_do_fs_boot
                        ==>spl_load_image _fat (UBOOT.IMG)    //load Uboot.img into memory and parse

When the image is loaded into memory, SPL determines whether the loaded image is uboot or kernel and then jumps to the mirror's portal for execution. At this point, SPL's mission was completed.
==>jump_to_image_no_args (&spl_image); Phase II Uboot

This phase of the uboot is in memory, the memory has been initialized, and many of the pin multiplexing has been reused in the previous phase.

In the process of compiling, the second stage Uboot is compiled first, and then the SPL is compiled. These two phases are compiled at the time of separation. have different configurations, so macros in many places are not the same as SPL. And
the linked files are inconsistent.

by validation, in the case of the Board_init_r function, the Board_init_r function in SPL is linked to spl.c, whereas in Uboot, it is the BOARD_R.C function in the link to borad_init_r.

So, let's start with the Borad_init_r function and see how the second phase of Uboot starts. In the

process of analysis,
we directly in the Board_init_r function into a dead loop, but found that there is still information to output, indicating that the Board_init_r has also been initialized work.

    u-boot 2017.01-g03781bc-dirty (Jul 2017-13:55:58 +0800)

    CPU  : AM437X-GP Rev 1.2
    model:ti am437x GP EVM
    i²c:   ready
    DRAM:  1 GiB

We found that in fact in Board_ Init_f are already linked in other files, he is located in the Board_f.c file
    void Board_init_f (ULong boot_flags) {#ifdef config_sys_generic_global_data/* * For some architectures, the global data is initialized and used before * calling this function. The data should be preserved. For others, * Config_sys_generic_global_data should is 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 value of gd->have_console.
        */Zero_global_data ();
            #endif gd->flags = boot_flags;

            Gd->have_console = 0;

        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}
The key function of the 
 is Initcall_run_list (init_sequence_f); let's see what Init_sequence_f is. 
Static init_fnc_t init_sequence_f[] = {#ifdef Config_sandbox setup_ram_buf, #endi
            F Setup_mon_len, #ifdef Config_of_control fdtdec_setup,//Initialize FDT #endif #ifdef config_trace trace_early_init, #endif initf_malloc , Initf_console_record, #if defined (config_mpc85xx) | | Defined (CONFIG_MPC86XX)/* Todo:can this go to 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 */ Mach_cpu_init,/* soc/machine dependent CPU 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 T His go to Arch_cpu_init ()? */#if defined (CONFIG_PPC) &&!defined (Config_8xx_cpuclk_default) get_clocks,/* g
                    Et CPU and bus clocks (etc) */#if defined (CONFIG_TQM8XXL) &&!defined (config_tqm866m) \ &&!defined (CONFIG_TQM885D) adjust_sdram_tbs_8xx, #endif/* to Do: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_sh) | | 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 ENVIRONM ENT */#if defined (config_8xx_cpuclk_default)/* Get CPU and bus clocks according to the EnviR  Onment 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_c Heck, #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 define D (config_mpc83xx) PRT_83XX_RSR, #endif #if defined (CONFIG_PPC) | | Defined (config_m68k) | | Defined (config_sh) checkcpu, #endif print_cpuinfo,/* Display CPU info (a nd speed) */#if defined (config_mpc5xxx) prt_mpc5xxx_clks, #endif/* config_mpc5xx X */#if defined (config_dtb_reselect) embedded_dtb_select, #endif #if Defined (config_display_boardinfo) show_board_info, #endif init_func_watchdog_i NIT #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 Dr AM functions? */#if defined (config_arm) | | Defined (config_x86) | | Defined (CONFIG_NDS32) | | \ defined (config_microblaze) | | Defined (CONFIG_AVR32) | | \ defined (CONFIG_SH) dram_init,/* Configure available RAM banks *//set some GD related parameters Number #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 the 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 this 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) | | Defined (CONFIG_XTENSA)/* Blackfin U-boot Monitor should be on top of the RAM */Reserve_u
   Boot, #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_4 K, #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:w Hy the dependency on config_8xx?
                    * * * 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) &&
                !defined (Config_xtensa) reserve_uboot, #endif #ifndef config_spl_build Reserve_malloc, Reserve_board, #endif setup_machine, Res
                Erve_global_data, RESERVE_FDT, Reserve_arch, Reserve_stacks, Setup_dram_config, Show_dram_config, #if defined (config_m68k) | | Defined (config_mips) | | Defined (CONFIG_PPC) | | \ defined (config_sh) 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 define D (config_x86) | |
            Defined (CONFIG_ARC) Copy_uboot_to_ram, CLEAR_BSS, Do_elf_reloc_fixups, #endif #if defined (config_xtensa) CLEAR_BSS, #endif #if!defi 
        Ned (Config_arm) &&!defined (Config_sandbox) jump_to_copy, #endif NULL, };
 we found this to be an array-like thing.
By the name of the function, we can probably know that the function in this array is called sequentially. 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.