移植U-BOOT-2016.11到JZ2440详细教程(1)

前言

学习韦东山老师的移植U-BOOT 2012.04.01已经有一段时间了,一直想着自己来移植最新的U-BOOT,看看是否真正的掌握了移植方法。并通过这个过程,学着写一些自己的博客。

至于为什么要选择2016.11版本,而不是最新的2018.09,是因为从U-BOOT 2016.11以后的版本就不再支持S3C2410单板,以目前的能力,我们要移植U-BOOT到开发板上一定是选择当前支持的单板或者至少是相近的。 U-BOOT代码可以从这里下载,链接:[ftp://ftp.denx.de/pub/u-boot/]

因为现在我还没有从头到尾的把2016.11版本的U-BOOT移植成功,并且还在上班,所以接下来以一个模块为一个章节不定时更新。每一个章节结束,我都会附上相应的补丁文件,大家可以直接从补丁文件看到这一章修改了哪些地方。

U-BOOT 2016.11 启动流程分析

一般u-boot要做以下这些事:
a. 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
b. 如果bootloader比较大,要把它重定位到SDRAM
c. 把内核从NAND FLASH读到SDRAM
d. 设置"要传给内核的参数"
e. 跳转执行内核

下面主要列举了部分U-BOOT从上电到调用系统内核过程中的一些函数调用关系,其中加粗和斜体是移植U-BOOT中可能会修改到的函数。对部分函数进行了简单的注释,完整的启动流程分析以及函数注释可以看源代码,或者链接: [http://www.wowotech.net/u-boot/boot_flow_2.html].

  • .globl reset (arch\arm\cpu\arm920t\start.S) 1
    • bl cpu_init_crit 2
      • bl lowlevel_init(\board\samsung\smdk2440\lowlevel_init.S) 3
    • bl _main(\arch\arm\lib\crt0_64.S)
      • bl board_init_f_alloc_reserve (\common\init\board_init.c)4
      • bl board_init_f_init_reserve (\common\init\board_init.c)5
      • bl board_init_f (\common\board_f.c)
        • initcall_run_list(init_sequence_f)
          • setup_mon_len,6
          • initf_malloc,
          • initf_console_record,
          • arch_cpu_init,
          • mach_cpu_init,
          • initf_dm,
          • arch_cpu_init_dm,
          • board_early_init_f, (\board\samsung\smdk2440\smdk2410.c)7
          • init_timebase,
          • env_init,(\common\env_mmc.c)8
          • init_baud_rate,9
          • serial_init,(\drivers\serial\serial.c) 10
          • console_init_f,
          • display_options,
          • display_text_info,
          • print_cpuinfo,11
          • announce_dram_init,
          • dram_init,
          • reserve_uboot,12
          • setup_dram_config,
            • dram_init_banksize() ; (\common\board_f.c) 13
          • show_dram_config,14
          • display_new_sp,
          • setup_reloc,
      • b relocate_code15
      • b.lo clear_loop16
      • b board_init_r
        • initcall_run_list(init_sequence_r)
          • board_init,17
          • run_main_loop,
            • main_loop(); (\common\main.c)
              • bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, “main_loop”);18
              • cli_init();19
              • run_preboot_environment_command();20
              • s = bootdelay_process();21
              • autoboot_command(s);22
              • cli_loop();[^23]

根据以上函数调用关系,我们可以总结出U-BOOT从上电到调用系统内核中间经过的大致步骤如下:

  1. 初始化底层配置。
  2. 设置系统时钟。
  3. 初始化内存控制器。
  4. 初始化RAM。
  5. 分配代码各个部分所需空间。
  6. 拷贝代码到RAM并跳转到RAM相应地址继续执行。
  7. 清除BSS段。
  8. 初始化之前分配的各个空间。
  9. 跳转到run_main_loop,然后判断是直接调用系统内核,还是等待传入命令并执行相应的操作。
    我们在移植的时候主要还是主要系统时钟和内存控制器以及RAM的代码,如果这块代码没有问题,那么就离移植U-BOOT成功不远了。

  1. 让CPU运行在SVC32模式即超级用户模式,可以进一步管理计算机;关闭看门狗;关中断;设置系统分频系数。 ↩︎

  2. 关闭数据和指令缓存;关闭MMU和caches。 ↩︎

  3. 初始化内存控制器。 ↩︎

  4. 分配空间给全局变量global_data,并计算剩余地址。 ↩︎

  5. 初始化全局变量global_data。 ↩︎

  6. 计算整个U-BOOT长度。 ↩︎

  7. 设置UPLL和MPLL,S3C2440有两个PLL(phase locked loop)一个是MPLL,一个是UPLL。MPLL用于CPU及其他外围器件。UPLL用于USB,用于产生FCLK, HCLK, PCLK三种频率。设置IO管脚。 ↩︎

  8. 初始化系统环境变量。 ↩︎

  9. 初始化波特率。 ↩︎

  10. 初始化串口。 ↩︎

  11. 以上三个函数都是帮助打印调试信息。 ↩︎

  12. 分配U-BOOT代码的存储空间。 ↩︎

  13. 初始化dram Bank信息。 ↩︎

  14. 打印drarm信息。 ↩︎

  15. 重定位代码。 ↩︎

  16. 清零BSS段。 ↩︎

  17. 单板相关初始化。 ↩︎

  18. 说明U-BOOT当前阶段。 ↩︎

  19. 配置u-boot使用hush shell来作为执行器。初始化相关函数。 ↩︎

  20. 从环境变量中获取"preboot"的定义,该变量包含了一些预启动命令,并执行这些命令。 ↩︎

  21. 从环境变量中取出"bootdelay",并转化为整型,以及"bootcmd"。 ↩︎

  22. 循环处理U-BOOT cmd指令。 ↩︎

猜你喜欢

转载自blog.csdn.net/yunlong654/article/details/83501540