1. 编译完内核如何找出 dts
在编译完 ARM64 内核后,设备树二进制文件(DTB)通常会被放置在 arch/arm64/boot
目录下。在该目录下,你可以找到与目标硬件平台对应的 DTB 文件。命令如下:
$ find arch/arm64/boot/dts/ -name *.dtb.cmd
arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.cmd
里面不仅能展示原始dts文件是哪个,dtb编译过程,还能展示它的依赖文件有哪些,方便把这些依赖文件加到source insight进行分析:
$ cat arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.cmd
cmd_arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb := mkdir -p arch/arm64/boot/dts/rockchip/ ; ./scripts/gcc-wrapper.py ./../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -E -Wp,-MD,arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.d.pre.tmp -nostdinc -I./scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp -o arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.dts.tmp arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dts ; ./scripts/dtc/dtc -O dtb -o arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb -b 0 -iarch/arm64/boot/dts/rockchip/ -i./scripts/dtc/include-prefixes -@ -Wno-unit_address_vs_reg -Wno-unit_address_format -Wno-avoid_unnecessary_addr_size -Wno-alias_paths -Wno-graph_child_address -Wno-graph_port -Wno-simple_bus_reg -Wno-unique_unit_address -Wno-pci_device_reg -d arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.d.dtc.tmp arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.dts.tmp ; cat arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.d.pre.tmp arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.d.dtc.tmp > arch/arm64/boot/dts/rockchip/.rk3568-firefly-aioj.dtb.d
source_arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb := arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dts
deps_arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb := \
arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtsi \
arch/arm64/boot/dts/rockchip/rk3568-firefly-port.dtsi \
scripts/dtc/include-prefixes/dt-bindings/gpio/gpio.h \
scripts/dtc/include-prefixes/dt-bindings/pinctrl/rockchip.h \
arch/arm64/boot/dts/rockchip/rk3568-firefly-core.dtsi \
scripts/dtc/include-prefixes/dt-bindings/pwm/pwm.h \
scripts/dtc/include-prefixes/dt-bindings/input/rk-input.h \
scripts/dtc/include-prefixes/dt-bindings/display/drm_mipi_dsi.h \
scripts/dtc/include-prefixes/dt-bindings/sensor-dev.h \
arch/arm64/boot/dts/rockchip/rk3568.dtsi \
scripts/dtc/include-prefixes/dt-bindings/clock/rk3568-cru.h \
scripts/dtc/include-prefixes/dt-bindings/interrupt-controller/arm-gic.h \
scripts/dtc/include-prefixes/dt-bindings/interrupt-controller/irq.h \
scripts/dtc/include-prefixes/dt-bindings/soc/rockchip,boot-mode.h \
scripts/dtc/include-prefixes/dt-bindings/phy/phy.h \
scripts/dtc/include-prefixes/dt-bindings/power/rk3568-power.h \
scripts/dtc/include-prefixes/dt-bindings/soc/rockchip-system-status.h \
scripts/dtc/include-prefixes/dt-bindings/suspend/rockchip-rk3568.h \
scripts/dtc/include-prefixes/dt-bindings/thermal/thermal.h \
arch/arm64/boot/dts/rockchip/rk3568-dram-default-timing.dtsi \
scripts/dtc/include-prefixes/dt-bindings/clock/rockchip-ddr.h \
scripts/dtc/include-prefixes/dt-bindings/memory/rk3568-dram.h \
scripts/dtc/include-prefixes/dt-bindings/memory/rockchip-dram.h \
arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi \
arch/arm64/boot/dts/rockchip/rockchip-pinconf.dtsi \
arch/arm64/boot/dts/rockchip/rk3568-linux.dtsi \
arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj-cam-8ms1m.dtsi \
arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb: $(deps_arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb)
$(deps_arch/arm64/boot/dts/rockchip/rk3568-firefly-aioj.dtb):
2. Linux 运行起来之后如何找出 dts
当 Linux 系统启动后,设备树信息会被加载到 /proc/device-tree
中。虽然 /proc/device-tree
直接提供的是设备树的二进制形式,但我们可以通过以下步骤生成 DTS 文件,使用 dtc
(设备树编译器)工具:
dtc -I fs -O dts -o output.dts /proc/device-tree
-I fs
: 指定输入格式为文件系统格式。-O dts
: 指定输出格式为 DTS。-o output.dts
: 指定输出文件名。
3. QEMU直接导出dts
使用QEMU模拟arm64时,如果使用了-machine virt,那么是不需要指定dts的,因为QEMU内置了一个dts文件,参考:qemu/v9.1.0/source/hw/arm/virt.c
qemu-system-aarch64 \
-cpu cortex-a72 \
-machine virt,gic-version=3,virtualization=on \
-m 2048 \
-nographic \
-drive file=your_image.img,format=raw \
-kernel your_kernel.img \
-initrd your_initrd.img \
-append "console=ttyAMA0 root=/dev/vda rw"
在使用 QEMU 模拟器时,可以直接在启动虚拟机的过程中导出设备树二进制文件(DTB)。要在 QEMU 启动时导出 DTB,你可以使用 -machine
选项中的 dumpdtb
参数。以下是一个示例命令:
qemu-system-aarch64 -cpu cortex-a72 -machine virt,gic-version=3,virtualization=on,dumpdtb=cortex-a72-virt.dtb
qemu-system-aarch64
: 启动 QEMU 的 AArch64(ARM64)模拟器。-cpu cortex-a72
: 指定使用 Cortex-A72 CPU。-machine virt
: 指定虚拟机的机器类型为 virt。gic-version=3
: 设置通用中断控制器(GIC)的版本为 3。virtualization=on
: 开启虚拟化支持。dumpdtb=cortex-a72-virt.dtb
: 在启动时生成并导出名为cortex-a72-virt.dtb
的 DTB 文件。
成功启动后,QEMU 会自动将设备树保存为指定的 cortex-a72-virt.dtb
文件。你可以在本地文件系统中找到这个文件,并使用 dtc
工具将其转换为 DTS 文件:
dtc -I dtb -O dts -o cortex-a72-virt.dts cortex-a72-virt.dtb
4 修改dts后重新生成dtb
使用 dtc
命令将修改后的 DTS 文件转换为 DTB 文件。假设你的 DTS 文件名为 modified.dts
,可以执行以下命令:
dtc -I dts -O dtb -o output.dtb modified.dts
-I dts
: 指定输入格式为 DTS。-O dtb
: 指定输出格式为 DTB。-o output.dtb
: 指定输出的 DTB 文件名。
附上一些有用的资料
devicetree « Documentation - kernel/git/torvalds/linux.git - Linux kernel source tree
Specifications (devicetree.org)
Device Tree Reference - eLinux.org
Device Tree Usage - eLinux.org
ePAPR 1.1 (elinux.org)
记录点滴,欢迎点赞关注收藏,共同进步 !