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
u-boot_boot_sequence [2019/12/27 17:39]
rpjday
u-boot_boot_sequence [2019/12/28 08:33] (current)
rpjday [1.]
Line 19: Line 19:
 ===== arch/​arm/​lib/​crt0_64.S [ENTRY(_main)] ===== ===== arch/​arm/​lib/​crt0_64.S [ENTRY(_main)] =====
  
 +==== Prologue ====
  
 +<​code>​
 + * This file handles the target-independent stages of the U-Boot
 + * start-up where a C runtime environment is needed. Its entry point
 + * is _main and is branched into from the target'​s start.S file.
 +</​code>​
  
-===== common/​board_f.c =====+==== 1. ====
  
-===== common/​board_r.(only most common===== +<​code>​ 
- + * 1Set up initial environment for calling board_init_f(). 
-==== initr_dm() [C] ==== + *    This environment only provides a stack and a place to store 
-==== board_init() [A,B] ==== + *    the GD ('​global data'structure, both located in some readily 
- + *    available RAM (SRAM, locked cache...). In this contextVARIABLE 
-==== board_early_init_r() (not for Zynq) ==== + *    global data, initialized or not (BSS), are UNAVAILABLE;​ only 
- + ​* ​   ​CONSTANT initialized data are availableGD should be zeroed 
-==== arch_early_init_r() [A] ==== + ​* ​   ​before board_init_f() is called. 
- +</​code>​
-  ​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>​ <​code>​
-#ifdef CONFIG_BOARD_LATE_INIT +void board_init_f(ulong boot_flags) 
-        ​board_late_init,​ +{ 
-#endif+        ​gd->​flags = boot_flags;​ 
 +        gd->​have_console = 0; 
 + 
 +        if (initcall_run_list(init_sequence_f)) 
 +                hang(); 
 +                ...
 </​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.1577468390.txt.gz · Last modified: 2019/12/27 17:39 by rpjday