User Tools

Site Tools


u-boot_boot_sequence

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
u-boot_boot_sequence [2019/12/27 17:40]
rpjday [arch/arm/lib/crt0_64.S [ENTRY(_main)]]
u-boot_boot_sequence [2019/12/27 17:55]
rpjday [common/board_f.c]
Line 21: Line 21:
 ==== 1. ==== ==== 1. ====
  
-==== 2. ==== +<​code>​ 
- + * This file handles the target-independent stages of the U-Boot 
-==== 3==== + * start-up where a C runtime environment is neededIts entry point 
- + * is _main and is branched into from the target'​s start.S file
-==== 4a==== + * 
- + * _main execution sequence is: 
-==== 4b==== + * 
- + * 1Set up initial environment for calling board_init_f()
-==== 5. ==== + *    This environment ​only provides a stack and a place to store 
- + *    the GD ('​global data'structure, both located in some readily 
-==== 6==== + *    available RAM (SRAM, locked cache...). In this contextVARIABLE 
- + *    global data, initialized or not (BSS), are UNAVAILABLE;​ only 
-==== 7==== + *    CONSTANT initialized data are available. GD should be zeroed 
- + *    before board_init_f() is called
-===== common/​board_f.c ===== +</code>
- +
-===== common/​board_r.c (only most common) ===== +
- +
-==== initr_dm() [C] ==== +
-==== board_init() [A,B] ==== +
- +
-==== board_early_init_r() (not for Zynq) ==== +
- +
-==== arch_early_init_r() [A] ==== +
- +
-  * arch/​arm/​mach-zynq/​cpu.c +
-  * arch/arm/​mach-zynq/​spl.c+
  
 <​code>​ <​code>​
-#if defined(CONFIG_ARCH_EARLY_INIT_R) +ENTRY(_main)
-int arch_early_init_r(void) +
-+
-#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \ +
-    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD)) +
-        int cpu_id = cpu_desc_id();​+
  
-        if (cpu_id < 0) +/* 
-                ​return 0; + * Set up initial C runtime environment and call board_init_f(0). 
- + */ 
-        ​fpga.size ​zynq_fpga_descs[cpu_id].fpga_size;​ +#if defined(CONFIG_TPL_BUILD) && defined(CONFIG_TPL_NEEDS_SEPARATE_STACK) 
-        ​fpga.name ​zynq_fpga_descs[cpu_id].devicename;​ +        ​ldr     ​x0, ​=(CONFIG_TPL_STACK) 
-        ​fpga_init(); +#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 
-        ​fpga_add(fpga_xilinx&fpga); +        ​ldr     ​x0, ​=(CONFIG_SPL_STACK) 
-#endif +#elif defined(CONFIG_INIT_SP_RELATIVE
-        ​return 0; +        ​adr     x0__bss_start 
-}+        ​add ​    x0, x0, #CONFIG_SYS_INIT_SP_BSS_OFFSET 
 +#else 
 +        ​ldr ​    x0, =(CONFIG_SYS_INIT_SP_ADDR)
 #endif #endif
 +        bic     sp, x0, #0xf    /* 16-byte alignment for ABI compliance */
 +        mov     x0, sp
 +        bl      board_init_f_alloc_reserve
 +        mov     sp, x0
 +        /* set up gd here, outside any C code */
 +        mov     x18, x0
 +        bl      board_init_f_init_reserve
 </​code>​ </​code>​
  
-==== initr_mmc() [C] ====+==== 2. ====
  
 <​code>​ <​code>​
-#ifdef CONFIG_MMC + * 2. Call board_init_f(). This function prepares the hardware for 
-static int initr_mmc(void+ *    execution from system RAM (DRAM, DDR...As system RAM may not 
-+ *    be available yet, , board_init_f() must use the current GD to 
-        puts("​MMC: ​  "​); + *    store any data which must be passed on to later stages. These 
-        ​mmc_initialize(gd->bd); + *    data include the relocation destination,​ the future stack, and 
-        ​return 0; + *    the future GD location.
-} +
-#endif+
 </​code>​ </​code>​
- 
-==== initr_env() [C] ==== 
  
 <​code>​ <​code>​
-static int initr_env(void) +        mov     x0#
-+        ​bl      board_init_f 
-        /* initialize environment */ +</code>
-        if (should_load_env()) +
-                env_relocate();​ +
-        else +
-                set_default_env(NULL, 0); +
-#ifdef CONFIG_OF_CONTROL +
-        ​env_set_hex("​fdtcontroladdr",​ +
-                    ​(unsigned long)map_to_sysmem(gd->fdt_blob));​ +
-#endif+
  
-        /* Initialize from environment */ +==== 3. ====
-        load_addr ​env_get_ulong("​loadaddr",​ 16, load_addr);+
  
-        return 0; +<​code>​ 
-}+ * 3. Set up intermediate environment where the stack and GD are the 
 + ​* ​   ones allocated by board_init_f() in system RAM, but BSS and 
 + ​* ​   initialized non-const data are still not available.
 </​code>​ </​code>​
- 
-==== show_board_info() [C] ==== 
- 
-From ''​common/​board_info.c'':​ 
  
 <​code>​ <​code>​
-int __weak checkboard(void) +#if !defined(CONFIG_SPL_BUILD)
-+
-        return 0; +
-+
 /* /*
- ​* ​If the root node of the DTB has a "​model"​ property, show it. + ​* ​Set up intermediate environment (new sp and gd) and call 
- ​* ​Then call checkboard().+ ​* ​relocate_code(addr_moni). Trick here is that we'll return 
 + * '​here'​ but relocated.
  */  */
-int __weak show_board_info(void) +        ldr     x0, [x18, #GD_START_ADDR_SP] ​   /* x0 <- gd->​start_addr_sp */ 
-+        ​bic     sp, x0, #0xf    /* 16-byte alignment for ABI compliance */ 
-#ifdef CONFIG_OF_CONTROL +        ​ldr     x18, [x18, #​GD_NEW_GD] ​         /* x18 <- gd->​new_gd ​*/
-        ​DECLARE_GLOBAL_DATA_PTR;​ +
-        ​const char *model;+
  
-        ​model = fdt_getprop(gd->​fdt_blob0"​model",​ NULL); +        ​adr     lr, relocation_return 
- +#if CONFIG_POSITION_INDEPENDENT 
-        ​if (model) +        /* Add in link-vs-runtime offset */ 
-                ​printf("​Model:​ %s\n"model);+        adr     x0_start ​             /* x0 <- Runtime value of _start */ 
 +        ldr     x9_TEXT_BASE ​         /* x9 <- Linked value of _start */ 
 +        ​sub     x9, x9, x0              /* x9 <- Run-vs-link offset */ 
 +        ​add ​    lr, lrx9
 #endif #endif
- +        /* Add in link-vs-relocation offset */ 
-        return ​checkboard();​ +        ​ldr     x9, [x18, #​GD_RELOC_OFF] ​       /* x9 <- gd->​reloc_off */ 
-}+        add     lr, lr, x9      /* new return ​address after relocation */ 
 +        ​ldr ​    x0, [x18, #​GD_RELOCADDR] ​       /* x0 <- gd->​relocaddr */
 </​code>​ </​code>​
  
 +==== 4a. ====
  
-For ''​zynqmp.c'':​+<​code>​ 
 + * 4a.For U-Boot proper (not SPL), call relocate_code(). This function 
 + ​* ​   relocates U-Boot from its current location into the relocation 
 + ​* ​   destination computed by board_init_f(). 
 +</​code>​
  
 <​code>​ <​code>​
-int checkboard(void) +        b       ​relocate_code 
-{ + 
-        ​puts("​BoardXilinx ZynqMP\n"​);​ +relocation_return:
-        return 0; +
-}+
 </​code>​ </​code>​
  
-==== arch_misc_init() ​==== +==== 4b. ====
- +
-Some arches and boards, not Zynq.+
  
 <​code>​ <​code>​
-#ifdef CONFIG_ARCH_MISC_INIT + * 4b.For SPLboard_init_f() just returns (to crt0). There is no 
-        arch_misc_init+ *    code relocation in SPL.
-#endif+
 </​code>​ </​code>​
  
-==== misc_init_r() ​====+==== 5. ====
  
 <​code>​ <​code>​
-#ifdef CONFIG_MISC_INIT_R + * 5. Set up final environment for calling board_init_r(). This 
-        ​misc_init_r+ *    environment has BSS (initialized to 0)initialized non-const 
-#endif+ *    data (initialized to their intended value), and stack in system 
 + ​* ​   RAM (for SPL moving the stack and GD into RAM is optional - see 
 + ​* ​   CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
 </​code>​ </​code>​
  
-==== initr_enable_interrupts() ​====+==== 6. ====
  
 <​code>​ <​code>​
-#ifdef CONFIG_ARM + * 6. For U-Boot proper ​(not SPL), some CPUs have some work left to do 
-static int initr_enable_interrupts(void+ *    at this point regarding memory, so call c_runtime_cpu_setup.
-+
-        enable_interrupts();​ +
-        return 0; +
-+
-#endif+
 </​code>​ </​code>​
- 
-From ''​arch/​arm/​lib/​interrupts.c'':​ 
  
 <​code>​ <​code>​
-int interrupt_init ​(void+/* 
-{+ * Set up final (fullenvironment 
 + */ 
 +        bl      c_runtime_cpu_setup ​            /* still call old routine */ 
 +#endif /* !CONFIG_SPL_BUILD */ 
 +#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK) 
 +#if defined(CONFIG_SPL_BUILD) 
 +        bl      spl_relocate_stack_gd ​          /* may return NULL */ 
 +        /* set up gd here, outside any C code, if new stack is returned */ 
 +        cmp     x0, #0 
 +        ​csel ​   x18, x0, x18, ne
         /*         /*
-         ​* ​setup up stacks if necessary+         ​* ​Perform 'sp = (x0 != NULL) ? x0 : sp' while working 
 +         * around the constraint that conditional moves can not 
 +         * have '​sp'​ as an operand
          */          */
-        ​IRQ_STACK_START_IN = gd->​irq_sp + 8;+        ​mov     x1, sp 
 +        cmp     x0, #0 
 +        csel    x0, x0, x1, ne 
 +        mov     sp, x0 
 +#endif
  
-        return 0; +/* 
-}+ * Clear BSS section 
 + */ 
 +        ldr     x0, =__bss_start ​               /* this is auto-relocated! */ 
 +        ldr     x1, =__bss_end ​                 /* this is auto-relocated! */ 
 +clear_loop:​ 
 +        str     xzr, [x0], #8 
 +        cmp     x0, x1 
 +        b.lo    clear_loop
  
-void enable_interrupts ​(void) +        /* call board_init_r(gd_t *id, ulong dest_addr*/ 
-{ +        ​mov     x0, x18                         /* gd_t */ 
-        ​return; +        ​ldr     x1, [x18, #​GD_RELOCADDR] ​       /* dest_addr */
-+
-int disable_interrupts (void) +
-{ +
-        ​return 0; +
-}+
 </​code>​ </​code>​
  
-==== initr_ethaddr() [C] ====+==== 7. ====
  
 <​code>​ <​code>​
-#ifdef CONFIG_CMD_NET + * 7. Branch to board_init_r().
-        initr_ethaddr,​ +
-#endif+
 </​code>​ </​code>​
  
 <​code>​ <​code>​
-#ifdef CONFIG_CMD_NET +        b       ​board_init_r ​                   /PC relative jump */
-static int initr_ethaddr(void) +
-+
-        bd_t *bd = gd->bd;+
  
-        /* kept around for legacy kernels only ... ignore the next section */ +        /* NOTREACHED ​board_init_r() does not return */
-        eth_env_get_enetaddr("​ethaddr",​ bd->​bi_enetaddr);​ +
-#ifdef CONFIG_HAS_ETH1 +
-        eth_env_get_enetaddr("​eth1addr",​ bd->​bi_enet1addr);​ +
-#endif +
-#ifdef CONFIG_HAS_ETH2 +
-        eth_env_get_enetaddr("​eth2addr",​ bd->​bi_enet2addr);​ +
-#endif +
-#ifdef CONFIG_HAS_ETH3 +
-        eth_env_get_enetaddr("​eth3addr",​ bd->​bi_enet3addr);​ +
-#endif +
-#ifdef CONFIG_HAS_ETH4 +
-        eth_env_get_enetaddr("​eth4addr",​ bd->​bi_enet4addr);​ +
-#endif +
-#ifdef CONFIG_HAS_ETH5 +
-        eth_env_get_enetaddr("​eth5addr",​ bd->​bi_enet5addr)+
-#endif +
-        ​return ​0; +
-+
-#endif /* CONFIG_CMD_NET ​*/+
 </​code>​ </​code>​
  
-==== board_late_init() [B] ====+===== common/​board_f.c =====
  
-(Defined in board/​xilinx/​zynq/​board.c.)+<​code>​ 
 +void board_init_f(ulong boot_flags) 
 +
 +        gd->​flags = boot_flags;​ 
 +        gd->​have_console = 0;
  
-<​code>​ +        if (initcall_run_list(init_sequence_f)) 
-#ifdef CONFIG_BOARD_LATE_INIT +                ​hang();​ 
-        ​board_late_init,​ +                ...
-#endif+
 </​code>​ </​code>​
  
-==== initr_net() ​====+===== common/​board_r.c =====
  
 <​code>​ <​code>​
-#ifdef CONFIG_CMD_NET +void board_init_r(gd_t *new_gd, ulong dest_addr)
-static int initr_net(void)+
 { {
-        ​puts("​Net: ​  "​);​ +        ​/* 
-        ​eth_initialize(); +         * Set up the new global data pointer. So far only x86 does this 
-#if defined(CONFIG_RESET_PHY_R) +         * here. 
-        debug("Reset Ethernet PHY\n"); +         * TODO(sjg@chromium.org): Consider doing this for all archs, or 
-        ​reset_phy();+         * dropping the new_gd parameter. 
 +         */ 
 +#if CONFIG_IS_ENABLED(X86_64
 +        ​arch_setup_gd(new_gd);
 #endif #endif
-        return 0; + 
-}+#ifdef CONFIG_NEEDS_MANUAL_RELOC 
 +        int i;
 #endif #endif
-</​code>​ 
  
 +#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
 +        gd = new_gd;
 +#endif
 +        gd->​flags &= ~GD_FLG_LOG_READY;​
 +
 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
 +        for (i = 0; i < ARRAY_SIZE(init_sequence_r);​ i++)
 +                init_sequence_r[i] += gd->​reloc_off;​
 +#endif
 +
 +        if (initcall_run_list(init_sequence_r))
 +                hang();
 +
 +        /* NOTREACHED - run_main_loop() does not return */
 +        hang();
 +</​code>​
u-boot_boot_sequence.txt · Last modified: 2019/12/28 08:33 by rpjday