OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3864|回复: 1

uboot 的 relocate_code 问题

[复制链接]

8

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
389
金钱
389
注册时间
2019-4-25
在线时间
99 小时
发表于 2021-10-27 10:32:13 | 显示全部楼层 |阅读模式
5金钱
在分析imx6ull的uboot启动流程时,有几个问题麻烦大家帮忙看一下,谢谢。

1. uboot在执行完 relocate_code 后,此时DDR里面是不是有两份uboot镜像了?
2. uboot在执行完 relocate_code 后,又重新设置了向量表,然后清除了bss段,接着跳转到了 board_init_r 进行外设的初始化。在这里执行的 board_init_r  从哪里可以看出来运行的是DDR中 relocate_code 后的uboot,而不是iROM加载的那份uboot呢?
下面是 arch\arm\lib\crt0.S 的源码
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. *  crt0 - C-runtime startup Code for ARM U-Boot
  4. *
  5. *  Copyright (c) 2012  Albert ARIBAUD <albert.u.boot@aribaud.net>
  6. */

  7. #include <config.h>
  8. #include <asm-offsets.h>
  9. #include <linux/linkage.h>
  10. #ifdef CONFIG_CPU_V7M
  11. #include <asm/armv7m.h>
  12. #endif

  13. /*
  14. * This file handles the target-independent stages of the U-Boot
  15. * start-up where a C runtime environment is needed. Its entry point
  16. * is _main and is branched into from the target's start.S file.
  17. *
  18. * _main execution sequence is:
  19. *
  20. * 1. Set up initial environment for calling board_init_f().
  21. *    This environment only provides a stack and a place to store
  22. *    the GD ('global data') structure, both located in some readily
  23. *    available RAM (SRAM, locked cache...). In this context, VARIABLE
  24. *    global data, initialized or not (BSS), are UNAVAILABLE; only
  25. *    CONSTANT initialized data are available. GD should be zeroed
  26. *    before board_init_f() is called.
  27. *
  28. * 2. Call board_init_f(). This function prepares the hardware for
  29. *    execution from system RAM (DRAM, DDR...) As system RAM may not
  30. *    be available yet, , board_init_f() must use the current GD to
  31. *    store any data which must be passed on to later stages. These
  32. *    data include the relocation destination, the future stack, and
  33. *    the future GD location.
  34. *
  35. * 3. Set up intermediate environment where the stack and GD are the
  36. *    ones allocated by board_init_f() in system RAM, but BSS and
  37. *    initialized non-const data are still not available.
  38. *
  39. * 4a.For U-Boot proper (not SPL), call relocate_code(). This function
  40. *    relocates U-Boot from its current location into the relocation
  41. *    destination computed by board_init_f().
  42. *
  43. * 4b.For SPL, board_init_f() just returns (to crt0). There is no
  44. *    code relocation in SPL.
  45. *
  46. * 5. Set up final environment for calling board_init_r(). This
  47. *    environment has BSS (initialized to 0), initialized non-const
  48. *    data (initialized to their intended value), and stack in system
  49. *    RAM (for SPL moving the stack and GD into RAM is optional - see
  50. *    CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
  51. *
  52. * 6. For U-Boot proper (not SPL), some CPUs have some work left to do
  53. *    at this point regarding memory, so call c_runtime_cpu_setup.
  54. *
  55. * 7. Branch to board_init_r().
  56. *
  57. * For more information see 'Board Initialisation Flow in README.
  58. */

  59. /*
  60. * entry point of crt0 sequence
  61. */

  62. ENTRY(_main)

  63. /*
  64. * Set up initial C runtime environment and call board_init_f(0).
  65. */

  66. #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
  67.         ldr        r0, =(CONFIG_SPL_STACK)
  68. #else
  69.         ldr        r0, =(CONFIG_SYS_INIT_SP_ADDR)
  70. #endif
  71.         bic        r0, r0, #7        /* 8-byte alignment for ABI compliance */
  72.         mov        sp, r0
  73.         bl        board_init_f_alloc_reserve        // 为malloc和gd_data留出空间
  74.         mov        sp, r0
  75.         /* set up gd here, outside any C code */
  76.         mov        r9, r0       
  77.         bl        board_init_f_init_reserve        // 初始化gd结构体

  78.         mov        r0, #0
  79.         bl        board_init_f

  80. #if ! defined(CONFIG_SPL_BUILD)

  81. /*
  82. * Set up intermediate environment (new sp and gd) and call
  83. * relocate_code(addr_moni). Trick here is that we'll return
  84. * 'here' but relocated.
  85. */

  86.         ldr        r0, [r9, #GD_START_ADDR_SP]        /* sp = gd->start_addr_sp */
  87.         bic        r0, r0, #7        /* 8-byte alignment for ABI compliance */
  88.         mov        sp, r0
  89.         ldr        r9, [r9, #GD_BD]                /* r9 = gd->bd */
  90.         sub        r9, r9, #GD_SIZE                /* new GD is below bd */

  91.         adr        lr, here
  92.         ldr        r0, [r9, #GD_RELOC_OFF]                /* r0 = gd->reloc_off */
  93.         add        lr, lr, r0
  94. #if defined(CONFIG_CPU_V7M)
  95.         orr        lr, #1                                /* As required by Thumb-only */
  96. #endif
  97.         ldr        r0, [r9, #GD_RELOCADDR]                /* r0 = gd->relocaddr */
  98.         b        relocate_code
  99. here:
  100. /*
  101. * now relocate vectors
  102. */

  103.         bl        relocate_vectors

  104. /* Set up final (full) environment */

  105.         bl        c_runtime_cpu_setup        /* we still call old routine here */
  106. #endif
  107. #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
  108. # ifdef CONFIG_SPL_BUILD
  109.         /* Use a DRAM stack for the rest of SPL, if requested */
  110.         bl        spl_relocate_stack_gd
  111.         cmp        r0, #0
  112.         movne        sp, r0
  113.         movne        r9, r0
  114. # endif
  115.         ldr        r0, =__bss_start        /* this is auto-relocated! */

  116. #ifdef CONFIG_USE_ARCH_MEMSET
  117.         ldr        r3, =__bss_end                /* this is auto-relocated! */
  118.         mov        r1, #0x00000000                /* prepare zero to clear BSS */

  119.         subs        r2, r3, r0                /* r2 = memset len */
  120.         bl        memset
  121. #else
  122.         ldr        r1, =__bss_end                /* this is auto-relocated! */
  123.         mov        r2, #0x00000000                /* prepare zero to clear BSS */

  124. clbss_l:cmp        r0, r1                        /* while not at end of BSS */
  125. #if defined(CONFIG_CPU_V7M)
  126.         itt        lo
  127. #endif
  128.         strlo        r2, [r0]                /* clear 32-bit BSS word */
  129.         addlo        r0, r0, #4                /* move to next */
  130.         blo        clbss_l
  131. #endif

  132. #if ! defined(CONFIG_SPL_BUILD)
  133.         bl coloured_LED_init
  134.         bl red_led_on
  135. #endif
  136.         /* call board_init_r(gd_t *id, ulong dest_addr) */
  137.         mov     r0, r9                  /* gd_t */
  138.         ldr        r1, [r9, #GD_RELOCADDR]        /* dest_addr */
  139.         /* call board_init_r */
  140. #if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
  141.         ldr        lr, =board_init_r        /* this is auto-relocated! */
  142.         bx        lr
  143. #else
  144.         ldr        pc, =board_init_r        /* this is auto-relocated! */
  145. #endif
  146.         /* we should not return here. */
  147. #endif

  148. ENDPROC(_main)
复制代码


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

51

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
389
金钱
389
注册时间
2019-4-25
在线时间
99 小时
 楼主| 发表于 2021-10-27 15:27:18 | 显示全部楼层
解析参考文章https://blog.csdn.net/skyflying2012/article/details/37660265
从测试中可以看出,ARM对全局变量和函数均是采用相对寻址的方式进行寻址,uboot中rel.dyn段存储了全局变量和函数的地址,通过下面这段代码,将rel.dyn段进行重定位
  1.         /*
  2.          * fix .rel.dyn relocations
  3.          */
  4.         ldr        r2, =__rel_dyn_start        /* r2 <- SRC &__rel_dyn_start */
  5.         ldr        r3, =__rel_dyn_end        /* r3 <- SRC &__rel_dyn_end */
  6. fixloop:
  7.         ldmia        r2!, {r0-r1}                /* (r0,r1) <- (SRC location,fixup) */
  8.         and        r1, r1, #0xff
  9.         cmp        r1, #R_ARM_RELATIVE
  10.         bne        fixnext

  11.         /* relative fix: increase location by offset */
  12.         add        r0, r0, r4
  13.         ldr        r1, [r0]
  14.         add        r1, r1, r4
  15.         str        r1, [r0]
  16. fixnext:
  17.         cmp        r2, r3
  18.         blo        fixloop
复制代码


重定位后,当调用下面这行代码时,将board_init_r函数的地址放入PC指针中,就跳转到了board_init_r函数处去执行。在完成rel.dyn段的重定位后,board_init_r函数的地址已经被定位到了新的位置,所以会执行重定位后的代码
  1. ldr        pc, =board_init_r        /* this is auto-relocated! */
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 14:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表