问问自己:
- 怎么编译目标dtb?
- 编译dtb时Makefile执行过程是什么?
如果你是能轻松回答上面的问题老鸟,可以关闭页面阅读其他文章。对于新手,我或许不能深入浅出地解答2个问题,但我的思路或许能借鉴。
这篇文章是平凡的一天工作记录,犯了很低级的dts文件命名错误,瞎鼓捣,浪费20min记录如下内容。
怎么生成设备树(dtb)
言简意赅列出手动创建dtb和在内核工程下创建dtb指令
出错
近期某项目结束,想备份工程设备树,龙芯官方的Linux-3.10内核生成设备树不支持 “make dtbs”,直接make就能生成dtb,以前没出问题也就没管过它。
- 复制2k1000_board.dtb为 LS2K-myproject-v6.dts
- 修改Makefile和Kconfig添加编译选项
编译出错
红色区域提示:在处理 LS2K-myproject-v6.dts.S 文件时遇到指令错误。
刚刚仅复制dts文件,搜遍整个工程都没有搜索到这个2k1000_board.S,考虑着S文件有可能是动态生成的。再次检查make错误输出内容,确认了我的猜想。
绿色区域提示:rm LS2K-board-myproject-v6.S
接下来是找到S文件是怎么生成的。
2k1000_board.dtb.S生成过程
光靠读取Makefile运行输出提示找不到S文件具体内容,唯一能看到紫色区域提示操作S文件。S文件在哪生成的呢?
跟踪Makefile。
打开Makefile调试选项: “make -n” 。下图Start和End之间框选的是动态生成脚本。
接下来找具体哪个Makefile文件、哪一行执行下面的内容。
2k1000_board.dtb.S在哪生成
一般工程里的makefile有三种命名规则:Makefile、Makefile.*、*.mk。 根据上文
“set -e; echo ’ DTC arch/mips/loongson2/dts/2k1000_board.dtb’;”
以 “DTC” 为关键词工程搜索:
- find Makefile scripts/ -name "Makefile.*" | xargs grep DTC
以搜索结果为依据锁定到两个文件
- scripts/Makefile.lib
- scripts/dtc/Makefile.dtc
宋宝华老师的指导方法,先嗅一下工程Makefile.dtc有没有什么Bed Smell, 简单阅读文件内容涉及的关键词,确认Makefile.dtc这个文件不用去看,从工程字面上去理解它的功能,猜测:应该是创建dtc工具和解析dts文件的,里面相关代码与平台无关。
# Makefile.dtc
#
# This is not a complete Makefile of itself. Instead, it is designed to
# be easily embeddable into other systems of Makefiles.
#
DTC_SRCS = \
checks.c \
data.c \
dtc.c \
flattree.c \
fstree.c \
livetree.c \
srcpos.c \
treesource.c \
util.c
DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
其中Makefile.lib文件的若干echo格式就是 “make -n” 解析看到的内容
echo ' DTB arch/mips/loongson2/dts/2k1000_board.dtb.S';
( echo '#include <asm-generic/vmlinux.lds.h>';
# scripts/Makefile.lib
# DTC
# ---------------------------------------------------------------------------
# Generate an assembly file to wrap the output of the device tree compiler
quiet_cmd_dt_S_dtb= DTB $@
cmd_dt_S_dtb= \
( \
echo '\#include <asm-generic/vmlinux.lds.h>'; \
echo '.section .dtb.init.rodata,"a"'; \
echo '.balign STRUCT_ALIGNMENT'; \
echo '.global __dtb_$(*F)_begin'; \
echo '__dtb_$(*F)_begin:'; \
echo '.incbin "lt;" '; \
echo '__dtb_$(*F)_end:'; \
echo '.global __dtb_$(*F)_end'; \
echo '.balign STRUCT_ALIGNMENT'; \
) > $@
$(obj)/%.dtb.S: $(obj)/%.dtb
$(call cmd,dt_S_dtb)
cmd_dt_S_dtb执行依赖目标文件名,原始目标 2k1000_board.dtb.S,自动则创建 两个标识
__dtb_2k1000_board_begin和__dtb_2k1000_board_end,
设备树2k1000_board.dts以 include的方式夹在这两个符号中间 .incbin “lt;”, STRUCT_ALIGNMENT 表示符号对齐方式,本工程里设定STRUCT_ALIGNMENT=32。
生成/tmp/b.txt
因为这个*.dtb.S文件生成立即使用,用完就删掉,本文第一张图片红色区域提示说:“第5行存在指令错误”。 懒得去分析若干 echo 生成的是什么鬼。 为了探寻它究竟是什么内容,临时修改Makefile.lib,把末尾的管道重定向到 /tmp/b.txt
cmd_dt_S_dtb= \
( \
echo '\#include <asm-generic/vmlinux.lds.h>'; \
------------略-------------
) > /tmp/b.txt
查看a.txt第四行瞬间明白错误原因,好想拍断大腿——“命名规则错误”。看到没,代码变量符号命名怎么可以用减号“-”,应该用下划线“_”。
/work/ls2k/linux-3.10-ls2k-git# cat /tmp/a.txt -n
1 #include <asm-generic/vmlinux.lds.h>
2 .section .dtb.init.rodata,"a"
3 .balign
4 .global __dtb_LS2K-myproject-v6_begin
5 __dtb_LS2K-myproject-v6_begin:
6 .incbin "arch/mips/loongson2/dts/LS2K-myproject-v6.dtb"
7 __dtb_LS2K-myproject-v6_end:
8 .global __dtb_LS2K-myproject-v6_end
9 .balign STRUCT_ALIGNMENTroot@debian-hub:/work/ls2k/linux-3.10-ls2k-git#
创建段
根据最初编译的提示,对比/tmp/b.txt可知第四行没有
"__dtb_LS2K-myproject-v6_begin"
这个段
arch/mips/loongson2/dts/LS2K-myproject-v6.dtb.S:4: Error: : no such section
重命名就dts文件就OK了,横杠改成下划线。
LS2K-myproject-v6.dtb.o,
LS2K_myproject_v6.dtb.o。
# arch/mips/loongson2/dts/Makefile
# obj-$(CONFIG_CPU_LOONGSON2K) := 2k1000_board.dtb.o
# obj-$(CONFIG_CPU_LOONGSON2K_MYPRJ_v6) := LS2K-myproject-v6.dtb.o
obj-$(CONFIG_CPU_LOONGSON2K_MYPRJ_v6) := LS2K_myproject_v6.dtb.o
资料
获取资料方式:
1、关注我
2、私信【linux进阶】