| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> XR872 移植 u-boot-v2021.07 -> 正文阅读 |
|
[系统运维]XR872 移植 u-boot-v2021.07 |
背景说明去年下半年时间较多,每天下班了总得找点事干,之后偶尔看到XR872这款芯片,感觉可玩性还比较高,蓝牙WIFI、PSRAM、CSI编解码应有尽有,本着玩一玩的心态,计划是要将最新的uboot和linux移植上去的(据说uClinux已经融入linux主线,支持NOMMU了,所以也想验证一下)。但是后来由于干其他的事去了,uboot的移植已经搁浅差不多半年了,所以现在把我移植的代码分享出来,给后边喜欢折腾的朋友提供一个参考。 目前移植的u-boot已经可以入命令行,启动后开发板指示灯亮起,可正常使用loadx和go命令跑裸板程序了。 这是之前发的几篇文章,为本篇做铺垫: XR872 打包自定义镜像与烧录https://blog.csdn.net/qq_28824733/article/details/124436295XR872 官方bootloader程序分析https://blog.csdn.net/qq_28824733/article/details/124436820XR872 自打包的镜像烧录出现Verify boot error解决办法https://blog.csdn.net/qq_28824733/article/details/124438272 环境说明编译系统:Ubuntu uboot蓝本:u-boot-v2021.07.tar.gz 交叉工具链:gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2 我的代码仓库:https://gitee.com/huxiangjs/u-boot-v2021.07 测试开发板: 编译步骤(1)克隆工程源码
(2)编译命令
(3)制作烧录镜像
关于这个工具的说明请看我之前发表的铺垫文章,目前我的image.cfg文件内容为:
如上步骤是正确的,最终会得到xr_system.img文件,烧录到开发板即可。 UBOOT实际测试(1)启动之后 (2)help命令 (3)loadx命令(传入了一个uart裸板测试程序) ?(4)go命令 程序已经正常跑起来了。 后面附上调试的一些记录,如有错误请指出,3Q UBOOT分析及调试记录首先分析UBOOT, 以stm32f429分析为例。 分析要点:
先用stm32的默认配置编译一下(生成.o文件): ???????? make stm32f429-discovery_defconfig ???????? make menuconfig ???????? make CROSS_COMPILE=../gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi- ARCH=arm 或者指定目录: ???????? make stm32f429-discovery_defconfig O=../build ???????? make menuconfig O=../build ???????? make CROSS_COMPILE=../../arm-gcc/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi- ARCH=arm O=../build -j8 uboot.lds中得到代码组织顺序: 搜索这个字段在哪儿: u-boot-v2021.07/arch/arm$ grep -rn vectors 找到结果(带m的,因为是Cortex-M系列,而且目录下有vectors_m.o表示编译过): 内容如下: 分析下一块,也就是start.o的源码start.S,文件再u-boot-v2021.07/arch/arm/cpu/armv7m/start.S,其中reset这个就是在上边中断向量表中指定的。 查找这个_main在哪里: u-boot-v2021.07/arch/arm$ grep -rn _main 找到: 分析crt0.S文件,crt为C runtime environment的缩写,也就是c运行环境。看看_main处的入口代码: 寻找board_init_f函数: u-boot-v2021.07/common$ grep -rn board_init_f 发现: 分析这个函数内容: 也就是把这个函数指针数组里的代码都调用一遍: 顺着代码,开始移植。首先建立配置文件: 接接下来就要编写这个文件了,要知道如何写,就要分析Makefile函数,首先看uboot根目录下的Makefile文件,看看我们传进去的ARCH=arm参数干嘛用了: 所以重点就在arch/arm/Makefile下,分析一下这个文件。 所以在目录下新建xr872: xr872_defconfig中增加: 重新defconfig,提示代码段地址无效: 那就设置一个,这个地址不一定对,后边根据需要调整: 至此,defconfig已经没有问题了,但是编译会有问题。 编译提示的错误: 代码如下: 检查.config,发现CONFIG_ARM64被默认打开了: 好吧,看来是有地方还需要增加。首先对Kconfig增加芯片选项吧,加入: 这里可以通过select CPU_V7M来选择指令集,所以可以把xr872_defconfig中的那一行去掉了。此时不出意外,menuconfig中就可以找到这个选项了: 此时再检查生成的.config文件中,CONFIG_ARM64已经没有了。 再次编译,报错: 查看这个文件(注意这个是在指定的编译目录下): 发现在这个目录有很多config文件: 依葫芦画瓢,建一个我们的config文件:touch xr872.h,编译一下,还是有问题,那说明不是这个问题,那就借鉴一下stm32的看看: 原来,板级文件夹还没有创建呢。但是这个路径CONFIG_BOARDDIR是如何确定的呢,看看构建的文件: 参考stm32,原来在这而定义的: 它被这个文件包含: 而这个文件又被这个文件包含: 所以最终还是被mach-*下的Kconfig文件控制着。那就继续画瓢,创建这些内容。 而mach-*下的Kconfig文件是在arm文件夹下的Kconfig中包含。 arm文件夹则就是我们make时候ARCH=arm所指定的,所以层层控制。 依葫芦画瓢完,再次编译,之前的问题已经没有了,这时候应该制作Makefile文件了: 提示板级Makefile错误: 直接上面的Makefile拷贝一个即可。 新问题: 依葫芦画瓢添加(这个地址后续调整,目前只要求编译通过): 如下问题,也这么解决,可以参考其它芯片的配置。 再次编译,还有错,是因为我们还没有创建源文件呢: 添加(文件内容置空就OK): 再次编译,编译阶段已经没有问题了,链接出错,因为有些函数还没有实现: 研究代码,发现如果要调用print_cpuinfo是需要打开CONFIG_DISPLAY_CPUINFO宏的,默认是打开,所以我们关闭它: 解决dram_init未实现,首先看出错的地方: 发现没有宏来控制,那就实现一下这个函数把: 文件头很漂亮,因为是VScode自动生成的。 board_init问题,看源码: 要使这些宏都为0才可以保证不调用这个函数,但是这个CONFIG_ARM肯定是需要被配置的,所以就实现这个函数吧: cread_line问题,看源码: 默认是打开的: 那就关掉它(后续需要时打开): 接下来就到了串口问题: 那就实现一下这个函数(内容以后再实现): 接下来就是滴答时钟的问题: 实现一下这个函数: 编译成功: 之后加入led函数: 加进init_sequence_f中: led此时已经可以点亮了,说明程序可以运行到这里面了。 把led_on移动到init_sequence_f尾部,发现不能点亮,那说明这中间有函数出问题了。 测试发现是在serial_init中卡死的,这个是因为之前那个default_serial_console函数中,直接返回了个NULL指针,估计这个函数是被serial_init调用了,所以出错,看代码,果然: 好吧,那就先把串口实现了! 实现完后,串口已经有输出了,但是肯定卡在哪个地方了: 通过led的指示,发现在这个函数卡死了: 看来是重定位代码出问题了,先把debug打开: 再次启动,有很多调试信息输出了: 分析上面的log,明显可以看出来有些地址是不对的: 新栈指针都设置错了,那肯定有问题: 好,那就分析一下看看代码是如何重定位relocation代码的: 预留的空间直接是从栈空间里减掉。 上面代码中,r9原先保存了gd所在的地址,之后做了一个操作,把r9切换到了new_gd所在位置。下边来分析一下relocate_code是如何实现的: 那么现在可以得出如下结论: ?????? (1)保证gd->new_gd ->reloc_off等于0,这样返回地址就是目前here的地方。 ?????? (2)保证gd->new_gd ->relocaddr等于__image_copy_start。 ?????? 确保这俩个条件无误,应该就可以跳过代码重定向了。 看看gd->new_gd是如何被设置的: 通过如上分析,可以知道,只要把ram_base设置为适当的位置,就可以跳过代码重定向,但是,为啥要gd->relocaddr = gd->ram_top呢?往后看就知道: 那么新分配的new_gd又是如何初始化的呢: 综合上述,可以知道只需要做gd->ram_base和gd->ram_size的初始化,uboot就可以正常跑起来,那就再dram_init中做吧: 果然跑起来的,进入可控制台,把DEBUG关掉后效果如下: 目前串口的输入还没实现,看一下这几个函数的功能: 顺着代码跳转,看看uboot的读取机制: 实现后效果: 发现控制台不好看,=>符合前少了些什么,同分析发现可通过如下来定义: 效果如下: 另外发现按上下键没有出现命令历史记录,这是由于前面在defconfig中把CONFIG_CMDLINE_EDITING关闭掉了,而这个宏控制了这个功能: 那就删除掉这一句: # CONFIG_CMDLINE_EDITING is not set 再次编译, 发现卡死了,那这个问题暂时不解决吧,毕竟RAM有限: 目前loadx命令还不能用,卡在第一个C位置: 分析代码,发现每次接受超时会有个延时操作: 而可以看到这个延时和滴答时钟有关系: 之后发现了我们之前实现的一个函数,这个函数直接返回了0,这是一个滴答时钟与微秒的比例系数: 而滴答时钟的初始化在这里: 用命令看一看,发现滴答时钟没有运行: 经过研究发现,uboot在进入loadx后会每隔一段时间发送一个C字符,电脑在收到这个C字符后开始传输数据,目前就是卡在第一个C字符,后面就不会有C字符输出,原因在这里: 看一看get_timer的代码: 看看这个timer_read_counter函数: 所以实现一下试试: 这个时候C可以一个一个出现,传输数据也没有问题了: 当然这只是个实验,还是要想办法把滴答时钟打开! 接下来要启用滴答时钟: 经过研究发现,armv7m/systick-timer.c受一个宏控制: 所以在xr872_defconfig中可以把这个宏设置为y,再次编译,发现还以没有编译systick-timer.c这个文件,之后通过menuconfig发现它还依赖ARM64或者ARMV7A,之后我在把ARMV7A也值为y,发现也没有编译这个问题。(连.config中都没出现CONFIG_SYS_ARCH_TIMER这个宏)。 所以直接粗暴简单: 还发现一个问题是,之前在xr872_defconfig中配置的CONFIG_TIMER=y,也没有在.config文件中找到,所以属于无效配置,在menuconfig中看看,发现确实有依赖: 依赖DM,所以暂时不处理,直接CONFIG_TIMER=y也注释掉。 再次编译,发现提示get_tbclk多重定义,这时候回到soc.c中,去掉我们之前加的那个get_tbclk函数,再次编译,成功。 启动uboot是没有问题的,但是使用loadx就直接挂了: 经过调试,发现问题,原因是因为0除以0出现问题。这个get_ticks()获取到的值为0,而gd->arch.timer_rate_hz也为0 这里应该要根据手册,把滴答时钟的时钟源打开,手册上已经找到了。滴答时钟源有俩种,低速和高速,当使用高速时钟,也就是cpu的时钟,这时候就不需要配置其它寄存器了,因为这个时钟直接从cpu引过来了,所以这里不再配置其它寄存器,直接使用cpu时钟了。 指定CPU频率: 之后loadx就已经可以使用了。 优化一下直接简单粗暴, 修改Kconfig: 恢复原状: 再次编译,OK ============== 实现历史命令选择: 设置CONFIG_CMDLINE_EDITING=y 发现启动后卡死,现在log.h中把DEBUG打开 发现只要调用mem_malloc_init就卡死,通过直接读取mem_malloc_init所在地址的数据发现,这个函数的代码竟然没被拷贝过去,难道是拷贝达到极限了?待后续确定 需要缩减u-boot.bin的尺寸,首先,分析每一个built-in.o文件大小, 发现网络占了比较大的空间,所以首先关掉网络: 重新编译后,xr_system.img大小从107KB减少到了85.3 KB 这时候再开启CONFIG_CMDLINE_EDITING=y 编译后的xr_system.img大小为:86.8 KB,再次启动,问题解决,功能正常! 历史命令也是可以切换了!这样验证了前面所说的“拷贝达到极限”的猜测。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 20:05:30- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |