当前位置: 代码迷 >> 综合 >> 移植 u-boot-2020.07 到 iTOP-4412(二)地址相关码 boot
  详细解决方案

移植 u-boot-2020.07 到 iTOP-4412(二)地址相关码 boot

热度:14   发布时间:2024-02-01 20:30:54.0

文章目录

  • 前言
  • 一、重新编写脚本
    • 1. init_env.sh
    • 2. build.sh
    • 3. sdflush.sh
  • 二、spl 启动流程
    • 1. start.S
    • 2. board_init_f()
      • 2.1 setup_global_data()
      • 2.2 do_lowlevel_init()
      • 2.3 power_exit_wakeup()
      • 2.4 copy_uboot_to_ram()
      • 2.5 jump to uboot
  • 三、点灯
    • 1. 问题:spl.bin 不正确
    • 2. 问题:灯亮一瞬间后熄灭
    • 3. 亮一段时间后发生 reset

前言

???在 移植 u-boot-2020.07 到 iTOP-4412(一)地址无关码点灯 文中,因为三星比较恶心的 boot 方式(对学习而言),使用了 MOV 等地址无关指令点灯成功,因为不知道 bl2.bin 最终将 u-boot-spl 重定位在哪里,始终无法使用 ldr 等指令点灯。

???对讯为提供的资料经行一番搜索查找发现,讯为有帮助把 bl1 中的安全校验等恶心人的地方去掉,这方便了学习,并且可以看出 spl 的链接地址。所以才能有这一篇文章。

???本文主要讲 spl 的方面。

一、重新编写脚本

1. init_env.sh

???这绝对是一个大坑,最开始我是在 build.sh 中 export 环境变量,第一次编译没有问题,然后发现需要 make menuconfig 或是想手动 make 时发生了错误,肯定是编译器不对,胡乱编译后 make distclean 也不起效果。

???只好用 Beyond Compare 手动和原 u-boot 文件对比一个一个修改后才能正常编译,所以很有必要使用同一的脚本初始化环境变量。

  • . init_env.sh

2. build.sh

为了方便,build.sh 主要实现这几个功能:

  • make xhr4412_defconfig
  • make
  • 检查编译是否成功
  • 反汇编
  • 连接 bl1 spl uboot

反汇编非常重要,调试的时候需要分析。

3. sdflush.sh

用于制作 tf 启动卡:

  • 检查 bin 文件存在
  • 使用 dd 命令将 bin 刷写到 tf card

二、spl 启动流程

[u-boot 2020.07] README

1. start.S

文件流程:

  1. arch/arm/lib/vectors.S
  2. arch/arm/cpu/armv7/start.S
  3. arch/arm/lib/crt0.S

vectors 中的其他 arm 向量不去关心。

???跳转到 reset 后,又跳转了几次看起来是无用功,应该是设计来增加函数的,还没研究怎么添加。最后由 save_boot_params_ret 跳转到 _main

???_main 中会根据 CONFIG_SPL_STACK 的值设置 SP,最后跳转到 board_init_f

2. board_init_f()

函数定义在:

  • arch/arm/mach-exynos/spl_boot.c

该初始化函数主要作用:

  1. 初始化全局变量
  2. lowlevel init
  3. 重定位 u-boot
  4. 跳转到 u-boot,不再返回

2.1 setup_global_data()

定义在 arch/arm/mach-exynos/spl_boot.c

初始化结构体 __aligned(8) gd_t local_gd; ,该结构体存放在堆栈中,具体什么用处还没搞懂。

2.2 do_lowlevel_init()

定义在 arch/arm/mach-exynos/lowlevel_init.c

???首先调用 get_reset_status() 获取 reset 状态,根据 reset 状态来判断需要完成哪些初始化操作。如果是正常启动,要做如下操作:

  • DO_POWER
    set_ps_hold_ctrl()
  • DO_CLOCKS
    system_clock_init()
  • DO_MEM_RESET
    mem_ctrl_init(actions & DO_MEM_RESET)

???如果配置了 UART ,将会初始化 UART,需要注意初始化哪一个 UART。最后初始化 TrustZone,这里修改代码,添加宏,不编译它。

#ifndef CONFIG_XHR4412tzpc_init();
#endif

2.3 power_exit_wakeup()

定义在:arch/arm/mach-exynos/power.c

该函数在 do_lowlevel_init() 返回非零时执行。

2.4 copy_uboot_to_ram()

调用 get_boot_mode() 函数判断从哪里 boot,然后将代码重定位。

2.5 jump to uboot

最后直接跳转到重定位的 u-boot 上执行。

三、点灯

???嵌入式大神鲁迅曾经说过:没有什么是点灯不能解决的,如果有,那就点两个流水灯。

???没想到这么简单的点灯程序仍然不简单。

void led_test(void)
{volatile unsigned long * GPL2CON;volatile unsigned long * GPL2DAT;GPL2CON = (volatile unsigned long *)0x11000100;GPL2DAT = (volatile unsigned long *)0x11000104;*GPL2CON = 1;*GPL2DAT = 1;while (1) ;
}

1. 问题:spl.bin 不正确

???在 out/spl/ 目录中会自动生成 xhr4412-spl.bin,一开始没弄懂这个文件怎么来的,不过就是普通的 u-boot-spl.bin,加了 header 和 padding。

???因为这个 header,导致 spl 被 bl1 重定位后无法执行到 reset,一直没能点灯成功。

???对整个 u-boot 文件夹搜索 grep -nr xhr4412,发现了之前添加的 board 文件夹中有 mkxhr4412spl.c 源文件,应该就是该文件编译后制作的 xhr4412-spl.bin,所以对它进行修改,注释掉 header 部分。

???并且仿造讯为提供的 u-boot 添加 checksum,可能 bl1 还是会对 xhr4412-spl.bin 进行简单校验。

???注意:需要 make distclean 后才能使上述修改生效。

2. 问题:灯亮一瞬间后熄灭

???最开始以为是 watchdog 的原因导致 cpu reset,但是关闭 watchdog 后也是这样的现象。

???后来发现 4412 比简单的 2440 复杂很多,需要电源管理芯片供电,看来应该是设置不对,供电断开了。

???设置 PS_HOLD_CONTROL 寄存器,并且我发现不能在设置该寄存器前 disable watchdog,不然灯完全不会亮,具体原因还没分析出来。

3. 亮一段时间后发生 reset

???设置了 PS_HOLD 后仍然是有问题的,现在可以亮一阵子,但是 6 7 秒后会熄灭重新亮,具体是 watchdog 还是电源管理芯片引起的还未分析出来,下一篇文章再研究这个问题,这里就先闪一闪灯吧。

void led_test(void)
{volatile unsigned long i; // volatile 不会被优化volatile unsigned long * GPL2CON;volatile unsigned long * GPL2DAT;volatile unsigned long * PS_HOLD;GPL2CON = (volatile unsigned long *)0x11000100;GPL2DAT = (volatile unsigned long *)0x11000104;PS_HOLD = (volatile unsigned long *)0x1002330C;*GPL2CON  = 1;*GPL2DAT  = 0;*PS_HOLD |= 0x300;while (1){*GPL2DAT ^= 1;for (i = 0; i < 500000; i++) ;}
}
  相关解决方案