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 15:52]
rpjday [arch/arm/cpu/armv7/lowlevel_init.S]
u-boot_boot_sequence [2019/12/28 08:33] (current)
rpjday [1.]
Line 17: Line 17:
  
  
-===== arch/​arm/​lib/​crt0.S [ENTRY(_main)] =====+===== arch/​arm/​lib/​crt0_64.S [ENTRY(_main)] =====
  
-==== Set up to call board_init_f() ​====+==== 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>​ 
 + 
 +==== 1. ====
  
 <​code>​ <​code>​
Line 37: Line 45:
  * Set up initial C runtime environment and call board_init_f(0).  * Set up initial C runtime environment and call board_init_f(0).
  */  */
- +#if defined(CONFIG_TPL_BUILD) && defined(CONFIG_TPL_NEEDS_SEPARATE_STACK) 
-#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) +        ldr     x0, =(CONFIG_TPL_STACK) 
-        ldr     r0, =(CONFIG_SPL_STACK)+#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 
 +        ldr     x0, =(CONFIG_SPL_STACK) 
 +#elif defined(CONFIG_INIT_SP_RELATIVE) 
 +        adr     x0, __bss_start 
 +        add     x0, x0, #​CONFIG_SYS_INIT_SP_BSS_OFFSET
 #else #else
-        ldr     r0, =(CONFIG_SYS_INIT_SP_ADDR)+        ldr     x0, =(CONFIG_SYS_INIT_SP_ADDR)
 #endif #endif
-        bic     r0r0, #7      ​/* 8-byte alignment for ABI compliance */ +        bic     spx0, #0xf    ​/* 16-byte alignment for ABI compliance */ 
-        mov     spr0+        mov     x0sp
         bl      board_init_f_alloc_reserve         bl      board_init_f_alloc_reserve
-        mov     ​sp, ​r0+        mov     ​sp, ​x0
         /* set up gd here, outside any C code */         /* set up gd here, outside any C code */
-        mov     r9r0+        mov     x18x0
         bl      board_init_f_init_reserve         bl      board_init_f_init_reserve
- 
-        mov     r0, #0 
 </​code>​ </​code>​
  
-==== Call board_init_f() ​====+==== 2. ====
  
 <​code>​ <​code>​
Line 66: Line 76:
  
 <​code>​ <​code>​
 +        mov     x0, #0
         bl      board_init_f         bl      board_init_f
 </​code>​ </​code>​
  
-==== Set up to call relocate_code() ​====+==== 3. ====
  
 <​code>​ <​code>​
-#if ! defined(CONFIG_SPL_BUILD)+ * 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>​
 +#if !defined(CONFIG_SPL_BUILD)
 /* /*
  * Set up intermediate environment (new sp and gd) and call  * Set up intermediate environment (new sp and gd) and call
Line 79: Line 95:
  * '​here'​ but relocated.  * '​here'​ but relocated.
  */  */
 +        ldr     x0, [x18, #​GD_START_ADDR_SP] ​   /* x0 <- gd->​start_addr_sp */
 +        bic     sp, x0, #0xf    /* 16-byte alignment for ABI compliance */
 +        ldr     x18, [x18, #​GD_NEW_GD] ​         /* x18 <- gd->​new_gd */
  
-        ​ldr     ​r0, [r9, #GD_START_ADDR_SP] ​    /* sp = gd->​start_addr_sp ​*/ +        ​adr     ​lrrelocation_return 
-        ​bic     ​r0r0, #7      ​/* 8-byte alignment for ABI compliance ​*/ +#if CONFIG_POSITION_INDEPENDENT 
-        mov     sp, r0 +        ​/* Add in link-vs-runtime offset ​*/ 
-        ldr     r9[r9, #​GD_BD] ​               ​/* r9 = gd->​bd ​*/ +        ​adr     ​x0_start ​             ​/* x0 <Runtime value of _start ​*/ 
-        sub     r9r9#​GD_SIZE ​               ​/* new GD is below bd */ +        ldr     x9_TEXT_BASE ​         ​/* x9 <Linked value of _start ​*/ 
- +        sub     x9x9x0              ​/* x9 <- Run-vs-link offset ​*/ 
-        adr     lr, here +        add     lr, lr, x9
-        ldr     r0, [r9, #​GD_RELOC_OFF] ​        /* r0 = gd->​reloc_off ​*/ +
-        add     lr, lr, r0 +
-#if defined(CONFIG_CPU_V7M) +
-        orr     lr, #1                          /* As required by Thumb-only */ +
-#endif +
-        ldr     r0, [r9, #​GD_RELOCADDR] ​        /* r0 = gd->​relocaddr */ +
-        b       ​relocate_code +
-here: +
-/* +
- * now relocate vectors +
- */ +
- +
-        bl      relocate_vectors +
- +
-/* Set up final (full) environment */ +
- +
-        bl      c_runtime_cpu_setup ​    /* we still call old routine here */+
 #endif #endif
 +        /* Add in link-vs-relocation offset */
 +        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>​
  
-==== Set up to call board_init_r() ​====+==== 4a. ====
  
 <​code>​ <​code>​
-        /call board_init_r(gd_t *id, ulong dest_addr*/ + 4a.For U-Boot proper ​(not SPL), call relocate_code(). This function 
-        mov     r0r9                  /* gd_t */ + ​* ​   ​relocates U-Boot from its current location into the relocation 
-        ldr     r1, [r9, #​GD_RELOCADDR] /* dest_addr */ + ​* ​   ​destination computed by board_init_f().
-        /* call board_init_r */ +
-#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD+
-        ​ldr ​    lr, =board_init_r ​      /this is auto-relocated! */ +
-        ​bx ​     lr +
-#else +
-        ldr     pc, =board_init_r ​      /this is auto-relocated! */ +
-#endif +
-        /* we should not return here*/ +
-#endif+
 </​code>​ </​code>​
  
-===== common/​board_f.c =====+<​code>​ 
 +        b       ​relocate_code
  
-===== common/board_r.c (only most common) =====+relocation_return:​ 
 +</code>
  
-==== initr_dm() [C] ==== +==== 4b. ====
-==== 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) + * 4b.For SPL, board_init_f() just returns ​(to crt0). There is no 
-int arch_early_init_r(void+    code relocation in SPL.
-+
-#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; +
- +
-        fpga.size = zynq_fpga_descs[cpu_id].fpga_size;​ +
-        fpga.name = zynq_fpga_descs[cpu_id].devicename;​ +
-        fpga_init();​ +
-        fpga_add(fpga_xilinx,​ &​fpga);​ +
-#endif +
-        return 0; +
-+
-#endif+
 </​code>​ </​code>​
  
-==== initr_mmc() [C] ====+==== 5. ====
  
 <​code>​ <​code>​
-#ifdef CONFIG_MMC + * 5. Set up final environment for calling board_init_r(). This 
-static int initr_mmc(void+ *    environment has BSS (initialized to 0), initialized non-const 
-+ *    data (initialized to their intended value), and stack in system 
-        puts("​MMC: ​  "​); + *    RAM (for SPL moving the stack and GD into RAM is optional ​see 
-        ​mmc_initialize(gd->bd); + *    CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
-        ​return 0; +
-+
-#endif+
 </​code>​ </​code>​
  
-==== initr_env() [C] ====+==== 6. ====
  
 <​code>​ <​code>​
-static int initr_env(void) + 6. For U-Boot proper ​(not SPL), some CPUs have some work left to do 
-+ ​* ​   at this point regarding memoryso call c_runtime_cpu_setup.
-        /initialize environment */ +
-        if (should_load_env()+
-                env_relocate();​ +
-        else +
-                set_default_env(NULL0); +
-#ifdef CONFIG_OF_CONTROL +
-        env_set_hex("​fdtcontroladdr",​ +
-                    (unsigned long)map_to_sysmem(gd->​fdt_blob));​ +
-#endif +
- +
-        /Initialize from environment */ +
-        load_addr = env_get_ulong("​loadaddr"​16, load_addr);​ +
- +
-        return 0; +
-}+
 </​code>​ </​code>​
- 
-==== show_board_info() [C] ==== 
- 
-From ''​common/​board_info.c'':​ 
  
 <​code>​ <​code>​
-int __weak checkboard(void+/* 
-{ + * Set up final (fullenvironment 
-        return 0; + */ 
-}+        ​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, #
 +        ​csel ​   x18, x0, x18, ne 
 +        /* 
 +         * Perform 'sp = (x0 != NULL) ? x0 : sp' while working 
 +         * around the constraint that conditional moves can not 
 +         * have '​sp'​ as an operand 
 +         */ 
 +        mov     x1, sp 
 +        cmp     x0, #0 
 +        csel    x0, x0, x1, ne 
 +        mov     sp, x0 
 +#endif
  
 /* /*
- ​* ​If the root node of the DTB has a "​model"​ property, show it. + ​* ​Clear BSS section
- * Then call checkboard().+
  */  */
-int __weak show_board_info(void) +        ldr     x0, =__bss_start ​               /* this is auto-relocated! */ 
-{ +        ​ldr ​    x1, =__bss_end ​                 /* this is auto-relocated! */ 
-#ifdef CONFIG_OF_CONTROL +clear_loop:​ 
-        ​DECLARE_GLOBAL_DATA_PTR;​ +        str     xzr, [x0], #8 
-        ​const char *model;+        ​cmp     x0, x1 
 +        ​b.lo    clear_loop
  
-        ​model = fdt_getprop(gd->​fdt_blob0, "​model",​ NULL); +        ​/* call board_init_r(gd_t *idulong dest_addr*/ 
- +        ​mov ​    x0, x18                         /* gd_t */ 
-        ​if (model) +        ​ldr     x1, [x18, #GD_RELOCADDR] ​       /* dest_addr */
-                printf("​Model:​ %s\n"model); +
-#endif +
- +
-        return checkboard();​ +
-}+
 </​code>​ </​code>​
  
- +==== 7====
-For ''​zynqmp.c'':​+
  
 <​code>​ <​code>​
-int checkboard(void) + * 7. Branch to board_init_r().
-+
-        puts("​Board:​ Xilinx ZynqMP\n"​);​ +
-        return 0; +
-}+
 </​code>​ </​code>​
- 
-==== arch_misc_init() ==== 
- 
-Some arches and boards, not Zynq. 
  
 <​code>​ <​code>​
-#ifdef CONFIG_ARCH_MISC_INIT +        b       ​board_init_r ​                   /* PC relative jump */
-        arch_misc_init,​ +
-#endif +
-</code>+
  
-==== misc_init_r() ==== +        /* NOTREACHED - board_init_r() does not return */
- +
-<​code>​ +
-#ifdef CONFIG_MISC_INIT_R +
-        misc_init_r,​ +
-#endif+
 </​code>​ </​code>​
  
-==== initr_enable_interrupts() ​====+===== common/​board_f.c =====
  
 <​code>​ <​code>​
-#ifdef CONFIG_ARM +void board_init_f(ulong boot_flags)
-static int initr_enable_interrupts(void)+
 { {
-        ​enable_interrupts()+        ​gd->​flags = boot_flags
-        ​return ​0; +        ​gd->​have_console = 0; 
-} + 
-#endif+        if (initcall_run_list(init_sequence_f)) 
 +                hang(); 
 +                ...
 </​code>​ </​code>​
  
-From ''​arch/arm/​lib/​interrupts.c'':​+===== common/board_r.c =====
  
 <​code>​ <​code>​
-int interrupt_init (void)+void board_init_r(gd_t *new_gd, ulong dest_addr)
 { {
         /*         /*
-         ​* ​setup up stacks if necessary+         ​* ​Set up the new global data pointer. So far only x86 does this 
 +         * here. 
 +         * TODO(sjg@chromium.org):​ Consider doing this for all archs, or 
 +         * dropping the new_gd parameter.
          */          */
-        IRQ_STACK_START_IN = gd->​irq_sp + 8;+#if CONFIG_IS_ENABLED(X86_64) 
 +        arch_setup_gd(new_gd); 
 +#endif
  
-        return 0; +#ifdef CONFIG_NEEDS_MANUAL_RELOC 
-+        int i;
- +
-void enable_interrupts (void) +
-{ +
-        ​return; +
-+
-int disable_interrupts (void) +
-+
-        return 0; +
-+
-</​code>​ +
- +
-==== initr_ethaddr() [C] ==== +
- +
-<​code>​ +
-#ifdef CONFIG_CMD_NET +
-        initr_ethaddr,​+
 #endif #endif
-</​code>​ 
  
-<​code>​ +#if !defined(CONFIG_X86&& !defined(CONFIG_ARM) && !defined(CONFIG_ARM64
-#ifdef CONFIG_CMD_NET +        ​gd = new_gd;
-static int initr_ethaddr(void) +
-+
-        bd_t *bd = gd->​bd;​ +
- +
-        /* kept around for legacy kernels only ... ignore the next section */ +
-        eth_env_get_enetaddr("​ethaddr",​ bd->​bi_enetaddr)+
-#ifdef CONFIG_HAS_ETH1 +
-        ​eth_env_get_enetaddr("​eth1addr",​ bd->​bi_enet1addr);+
 #endif #endif
-#ifdef CONFIG_HAS_ETH2 +        gd->flags &= ~GD_FLG_LOG_READY;
-        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>​+
  
-==== board_late_init() [B] ==== +#ifdef CONFIG_NEEDS_MANUAL_RELOC 
- +        for (i 0; i < ARRAY_SIZE(init_sequence_r); i++) 
-(Defined in board/​xilinx/​zynq/​board.c.) +                init_sequence_r[i+gd->reloc_off;
- +
-<code> +
-#ifdef CONFIG_BOARD_LATE_INIT +
-        board_late_init,​+
 #endif #endif
-</​code>​ 
  
-==== initr_net() ====+        if (initcall_run_list(init_sequence_r)) 
 +                hang();
  
-<​code>​ +        /* NOTREACHED - run_main_loop() does not return */ 
-#ifdef CONFIG_CMD_NET +        ​hang();
-static int initr_net(void) +
-{ +
-        ​puts("​Net: ​  "​); +
-        eth_initialize();​ +
-#if defined(CONFIG_RESET_PHY_R) +
-        debug("​Reset Ethernet PHY\n"​);​ +
-        reset_phy();​ +
-#endif +
-        return 0; +
-+
-#endif+
 </​code>​ </​code>​
- 
u-boot_boot_sequence.1577461977.txt.gz · Last modified: 2019/12/27 15:52 by rpjday