【U-Boot】解决U-Boot的“Unknown command ‘help‘ - try ‘help‘”问题

【U-Boot】解决U-Boot的"Unknown command 'help' - try 'help'"问题

零、起因

最近在玩U-Boot,自己编译U-Boot之后输入help命令发现提示Unknown command 'help' - try 'help',就此记录解决过程。

壹、解决过程

0x00

搜索源码,使用grep命令查找弹出这个提示的位置:

显示在common/command.c中。

0x01

修改common/command.c打印一些调试信息,帮助我更进一步确定问题所在位置:


再次运行,发现table_len为0:

0x02

发现问题:

尝试再次修改代码,追溯table_len变量,发现这个ll_entry_count是一个叫链接器的东西:

相关代码:

1

##是表示连接两个字符串,例如:有定义#defined a(x,y) x##y,则a(i,j)最终生成为ij

这里会连接生成_u_boot_list_cmd__start_u_boot_list_cmd__end,然后大小就是这两个的差值,那么这两个变量又是在哪的呢?

2

这段中的_u_boot_list_cmd__start_u_boot_list_cmd__end是自定义的符号,而.在链接器脚本里代表当前地址,可以用extern关键字声明这两个符号,获得与当前段相关的地址。

*(SORT(.u_boot_list.cmd.*))中,*()是链接器脚本里的通配符语法,例如:*(pattern)会将所有目标文件中名为pattern的段内容合并到当前段中。

这里的pattern.u_boot_list.cmd.*,表示会匹配所有以.u_boot_list.cmd.开头的段。

SORT()是链接器脚本提供的排序函数,它能对匹配的段进行排序(排序的依据通常是段名)。

所以,28行的代码意思是将所有目标文件中符合.u_boot_list.cmd.*模式的段内容收集起来,排序后合并到当前正在定义的段中。

3

其中U_BOOT_CMD是所有命令用来注册的宏。

其中section属性允许开发者把变量或函数放置到自定义的段中。

写好命令相关的代码后用U_BOOT_CMD宏来注册,这样会被统计到对应段中。

调试:

这样我们声明一下这两个符号,尝试看看这个段的地址是怎样的:

运行结果:

开始地址和结束地址一样,难道是没匹配上?还是没编译进去?

0x03

查看help命令的代码:

有的。

再看镜像中是否被编译进去了:

有的。

那就是没匹配上咯?或者说是链接器有兼容性问题?

使用arm-none-linux-gnueabi-objdump检查段信息:

就是说,编译了......

再看u-boot.map

诶?被_u_boot_list_先匹配去了,后面的_u_boot_list_cmd__u_boot_list_env_clbk_都没分到内容!

咋办?

0x04

通过搜索命令,我们最终可以大致确认原始脚本位置:

替换一下位置:

生成后发现没用,经检查发现是u-boot.lst被重新生成了。

0x05

好,上面的u-boot.lst也是生成的,由make_u_boot_list生成:

函数在helper.mk中,我们让这个函数失效:

再次修改u-boot.lst后重新编译,刷写到 SD 卡。

0x05

成功了!

晚安,搞到了凌晨四点,明天还有早八 QwQ ~

贰、总结

对于此类问题,grep是一个不错的命令,能快速找到位置,再由那个位置一层一层往上找就能找到问题所在。

第一次接触U-Boot源码,本次找错的过程让我对U-Boot命令相关的部分有了一定了解,自己花点时间写个命令的"Hello world"应该是没问题了。

另外,也是第一次研究.map文件、.lst文件和.lds文件,对链接和文件布局相关的东西都有了一定的了解,下次遇到这个问题不会找好久了,hahahah。

加深了对arm-none-linux-gnueabi-objdump命令的理解,它在本次排错中提供了比较重要的信息。

对U-Boot的编译、镜像制作和刷写更加熟练了。

晚安~ ( 早安!感谢豆包~ )

叁、参考

  1. https://www.doubao.com/thread/w4ea6b9d8ece3d7e9
  2. https://www.doubao.com/thread/w16f419b17f0e9afe
  3. https://www.doubao.com/thread/w2cd5264f38dd2ff8
  4. https://www.doubao.com/thread/w2cd5264f38dd2ff8
  5. https://www.doubao.com/thread/w2cd5264f38dd2ff8
  6. https://www.doubao.com/thread/wef34dbca2d2d6605
  7. https://www.doubao.com/thread/w7eec8793d6766c13
相关推荐
用户9718356334662 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪4 小时前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠20 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush420 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行52020 小时前
Linux 11 动态监控指令top
linux
不会C语言的男孩1 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈1 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
凡人叶枫1 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
2601_961875241 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant
java_cj1 天前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes