通用板级编译配置与构建指导
示例参考
参考板级代码:test.tar.bz2 (2.9MB)
1. 适用范围
本文用于指导在 Manhattan Linux SDK 中创建新的板级产品配置,并完成 U-Boot、Linux 内核、设备树、Buildroot 文件系统和板级应用模块的接入。
本文只描述通用方法,不绑定具体客户或项目。为了便于阅读,全文使用一个虚拟示例进行说明:板级名称为 test,芯片平台为 x2600,内核版本为 5.10,存储介质为 nand。因此,示例中的板级目录是 device/test/,实际项目只需要将 test 替换为自己的板级名称即可。
文中仍使用 、、 等占位符表示通用写法时,对应的示例分别是:test、x2600、5.10。
不同 SDK 版本的目录名和变量可能存在差异。开始修改前,应优先参考当前 SDK 中已有的同系列板级目录、
build/core构建规则和内核源码中的参考 defconfig。
2. 板级目录与构建链路
通用结构如下:
| device/ |
| ├── vendorsetup.sh 注册 lunch 选项 |
| ├── device.mk 平台、存储介质和文件系统配置 |
| ├── Build.mk 引入 U-Boot、内核及其他模块 |
| ├── uboot.mk U-Boot 编译参数 |
| ├── kernel.mk 内核编译参数 |
| ├── |
| ├── kernel_cfg/ 板级内核 defconfig |
| ├── kernel_overlay/ 内核源码覆盖文件 |
| ├── kernel- |
| ├── uboot_overlay/ U-Boot 源码覆盖文件 |
| ├── rootfs-overlay/ 根文件系统覆盖文件 |
| └── ota-overlay/ 可选,OTA、分区和升级脚本 |
以本文示例展开后,目录可以写成:
| device/test/ |
| ├── vendorsetup.sh |
| ├── device.mk |
| ├── Build.mk |
| ├── uboot.mk |
| ├── kernel.mk |
| ├── test_base.mk |
| ├── kernel_cfg/5.10/ |
| ├── kernel_overlay/ |
| ├── kernel-5.10/ |
| ├── uboot_overlay/ |
| ├── rootfs-overlay/ |
| └── ota-overlay/ |
图 1:test 板级目录结构示例

整体流程为:vendorsetup.sh 注册产品 → lunch 解析产品参数 → device.mk 设置产品属性 → kernel.mk/uboot.mk 注册编译模块 → overlay 覆盖源码 → 外置 Kconfig/Makefile 接入板级代码 → 生成镜像。
推荐从以下模板或同系列板级目录复制:
| build/core/templates/device/template/ |
复制后必须逐项核对变量和目录结构,不要直接沿用旧 SDK 的配置。
复制已有板级目录时,建议先完整复制,再只替换板级名称相关的文件名和文本引用。以本文的 test 示例为例:
| cp -a device/ |
| find device/test -depth -name '* |
| rg -n -i ' |
检查无误后,再根据实际芯片和内核版本确认 device.mk、kernel.mk、uboot.mk、defconfig、boards.cfg 和设备树文件。
图 2:复制板级目录并检查代码改动

3. 注册 lunch 产品
vendorsetup.sh 由 build/envsetup.sh 执行,使用 add_lunch_combo 注册产品。推荐产品名结构如下:
本文示例使用 test、x2600、nand 和 5.10:
| #!/bin/sh |
| add_lunch_combo test.x2600e_nand_5.10-eng |
| add_lunch_combo test.x2600e_nand_5.10_ota-eng |
实际项目可将 test 替换为板级目录名,x2600 替换为对应平台标识;存储介质和内核版本必须与实际构建配置一致。
创建后执行:
| source build/envsetup.sh |
| lunch |
确认以下变量被正确解析:TARGET_DEVICE、TARGET_STORAGE_MEDIUM、TARGET_EXT_SUPPORT、TARGET_EXT2_SUPPORT 和 TARGET_PRODUCT。
4. 配置板级入口文件
4.1 device.mk
device.mk 负责平台信息、Buildroot 配置、根文件系统 overlay 和存储介质参数。
| PRODUCT := product |
| TARGET_PRODUCT_BOARD := $(TARGET_DEVICE) |
| TARGET_BOARD_PLATFORM := "x2600" |
| TARGET_BOARD_ARCH := "mips" |
| TARGET_ARCH_VARIANT := mips32r2_fp64 |
| LOCAL_PATH := $(shell dirname $(lastword $(MAKEFILE_LIST))) |
| DEVICE_PATH := $(TOP_DIR)/$(LOCAL_PATH) |
| MAKE_JLEVEL := 4 |
注意:
TARGET_ARCH_VARIANT必须与芯片所属架构匹配。
xburst 芯片使用
mips32r2,例如x1600。xburst2 芯片使用
mips32r2_fp64,例如x2000、x2600。
device.mk中的配置示例:
# xburst2 芯片,例如 x2000、x2600 TARGET_ARCH_VARIANT := mips32r2_fp64 # xburst 芯片,例如 x1600 # TARGET_ARCH_VARIANT := mips32r2 两种配置不能同时启用。新增板级目录时,应先确认芯片平台,再选择对应的
TARGET_ARCH_VARIANT,否则可能出现工具链、编译选项或最终程序运行不匹配的问题。
存储介质相关配置应放在条件分支中:
| ifeq ($(strip $(TARGET_STORAGE_MEDIUM)),nand) |
| ROOTFS_OVERLAY_DIR := $(DEVICE_PATH)/rootfs-overlay |
| BUILDROOT_CONFIG := x2600e_test_linux_defconfig |
| BUILDROOT_CONFIG_PATH := $(DEVICE_PATH) |
| FILE_SYSTEM_TYPE := ubifs |
| endif |
OTA 配置、分区配置和升级脚本也应只在对应产品条件下加入,避免不同存储介质相互污染。
4.2 Build.mk 和
Build.mk 负责引入板级编译规则:
| include $(DEVICE_PATH)/uboot.mk |
| include $(DEVICE_PATH)/kernel.mk |
| ifeq ($(strip $(TARGET_EXT2_SUPPORT)),ota) |
| include $(DEVICE_PATH)/kernel-recovery.mk |
| endif |
通过 PRODUCT_MODULES 选择产品模块。本文示例对应的文件名为 test_base.mk:
| PRODUCT_MODULES := uboot \ |
| kernel |
| PRODUCT_MODULES += |
例如,若应用模块的 LOCAL_MODULE := test-app,则可以写成:
| PRODUCT_MODULES += test-app |
追加的名称应取自模块 Build.mk 中的 LOCAL_MODULE,而不是目录名。使用以下命令确认模块是否被选中:
| make show-modules |
4.3 uboot.mk
| UBOOT_BUILD_CONFIG := x2600e_test_uImage_sfc_nand |
| UBOOT_TARGET_FILE := u-boot-with-spl.bin |
| UBOOT_PATH := $(TOP_DIR)/u-boot |
| UBOOT_BOARD_PATH := $(LOCAL_PATH)/uboot_overlay |
| LOCAL_MODULE := uboot |
| include $(BUILD_UBOOT) |
需要确认:
UBOOT_BUILD_CONFIG在boards.cfg中存在对应条目。uboot_overlay/与 U-Boot 源码保持相同目录结构。例如
include/configs/test.h、board/ingenic/test/下的板级 C 文件和 Makefile 路径一致。启动介质、串口、bootargs、分区和镜像加载地址符合硬件方案。
单独验证:
| make uboot |
4.4 kernel.mk
| KERNEL_VER := 5.10 |
| KERNEL_PATH := $(TOP_DIR)/kernel/kernel-5.10 |
| KERNEL_BOARD_PATH := $(LOCAL_PATH)/kernel-5.10 |
| KERNEL_CONFIG_PATH := $(DEVICE_PATH)/kernel_cfg/5.10 |
| KERNEL_BUILD_CONFIG := x2600e_test_v10_linux_defconfig |
| KERNEL_BOARD_OVERLAY_PATH := $(LOCAL_PATH)/kernel_overlay |
| KERNEL_TARGET_IMAGE := uImage |
| KERNEL_IMAGE_PATH := arch/mips/boot/ |
| LOCAL_MODULE := kernel |
| include $(BUILD_KERNEL) |
OTA 或压缩内核场景可能改为:
| KERNEL_TARGET_IMAGE := xImage |
| KERNEL_IMAGE_PATH := arch/mips/boot/compressed/ |
当前 build/core/build_kernel.mk 的关键行为是:复制 KERNEL_BOARD_OVERLAY_PATH、复制 KERNEL_CONFIG_PATH 中的 defconfig、通过 OUTSIDE_BUILD 传入 KERNEL_BOARD_PATH,最后构建内核镜像、模块和设备树。
5. 设备树配置方式
设备树不是只放置一个 .dts 文件即可。推荐使用 defconfig + 外置 Kconfig + 外置 Makefile + DTS/DTSI 的完整链路。
5.1 推荐目录结构
| device/ |
| ├── Kconfig |
| ├── Makefile |
| └── board- |
| ├── Kconfig |
| ├── Makefile |
| └── device-dts/ |
| ├── Makefile |
| ├── |
| └── |
本文示例对应为:
| device/test/kernel-5.10/ |
| ├── Kconfig |
| ├── Makefile |
| └── board-x2600/ |
| ├── Kconfig |
| ├── Makefile |
| └── device-dts/ |
| ├── Makefile |
| ├── x2600e_test.dts |
| └── test_display.dtsi |
5.2 外置 Kconfig
顶层 Kconfig 引入板级 Kconfig:
| menu "external driver" |
| source "$(OUTSIDE_BUILD)/board-x2600/Kconfig" |
| endmenu |
板级 Kconfig 提供板级选择:
| choice |
| prompt "External Board Name" |
| depends on DT_XBURST2_EXTERNAL_BOARD |
| default DT_X2600E_TEST |
| config DT_X2600E_TEST |
| bool "test x2600 board" |
| endchoice |
DT_XBURST2_EXTERNAL_BOARD 必须由 SoC Kconfig 提供并在 defconfig 中打开;DT_ 必须与设备树 Makefile 中的配置符号完全一致。
图 3:外置 Kconfig、Makefile、defconfig 与 DTB 的配置链路

5.3 各级 Makefile
| # kernel- |
| obj-y += board-x2600/ |
| # board- |
| obj-y += device-dts/ |
| # device-dts/Makefile |
| dtb-$(CONFIG_DT_X2600E_TEST) += x2600e_test.dtb |
| obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) |
| always := $(dtb-y) |
| clean-files := *.dtb *.dtb.S |
只增加 .dts 而不增加 Makefile,或只增加 Kconfig 选项而没有 dtb-$(CONFIG_...) 规则,都可能导致能配置但不生成 DTB。
5.4 DTS 编写和核对重点
| /dts-v1/; |
| #include |
| #include |
| / { |
| compatible = "vendor,test", "vendor,x2600"; |
| }; |
| &uart0 { |
| status = "okay"; |
| pinctrl-names = "default"; |
| pinctrl-0 = |
| }; |
修改 DTS 时依次确认:
公共 SoC DTSI、GPIO、时钟、引脚复用和外设节点来自当前内核版本。
根节点
compatible与实际 SoC、板级产品一致。未使用外设为
disabled,使用外设为okay。UART、I2C、SPI、MMC、LCD 等设备的 pinctrl 与原理图一致。
GPIO、regulator、reset-gpios 的有效电平正确。
MMC/SFC 的总线宽度、频率、电压和非易失存储属性正确。
reserved-memory 不与 DDR、协处理器和 DMA 缓冲区重叠。
DTS 中使用的
CONFIG_...选项确实存在于本次.config。
图 4:x2600e_test.dts 设备树文件修改示例

5.5 defconfig 到 DTB 的选择链路
| SoC Kconfig |
| → CONFIG_DT_XBURST2_EXTERNAL_BOARD=y |
| → 外置 board-x2600/Kconfig |
| → CONFIG_DT_X2600E_TEST=y |
| → device-dts/Makefile 中的 dtb-$(CONFIG_DT_X2600E_TEST) |
| → 生成 x2600e_test.dtb |
建议在板级 defconfig 中检查:
| CONFIG_OF=y |
| CONFIG_DT_XBURST2_EXTERNAL_BOARD=y |
| CONFIG_DT_X2600E_TEST=y |
| CONFIG_OUTSIDE_BUILD=".../device/test/kernel-5.10" |
CONFIG_OUTSIDE_BUILD 的最终值由构建系统传入,不建议写死绝对路径。以构建生成的 .config 为准:
| grep -E 'CONFIG_OF=|CONFIG_DT_|CONFIG_OUTSIDE_BUILD' \ |
| out/product/ |
6. 设备树和内核验证
| make kernel |
| find out -name 'x2600e_test.dtb' -o -name 'x2600e_test.dtb.S' |
需要确认:
编译日志没有 DTS 语法错误、未定义标签或找不到 include 文件。
生成的 DTB 名称与
device-dts/Makefile一致。目标 DTB 没有被误编译成其他板级 DTB。
启动后可通过
/sys/firmware/devicetree/base/compatible检查兼容性字符串。关键外设的设备节点、内核日志和运行状态符合预期。
7. 文件系统、OTA 与整体构建
rootfs-overlay 的目录结构应与目标根文件系统一致,适合放置启动脚本、默认配置、校准数据和随系统发布的工具。
OTA 场景重点确认:
分区配置与 U-Boot 分区表、内核 MTD 分区一致。
normal/recovery 镜像名称和启动参数一致。
升级脚本使用的设备节点与实际存储介质一致。
OTA overlay 只在 OTA lunch 选项下加入。
推荐按从局部到整体的顺序验证:
| source build/envsetup.sh |
| lunch |
| make show-modules |
| make uboot |
| make kernel |
| make buildroot |
| make -j$(nproc) |
如果当前 SDK 没有 make buildroot 目标,以 make help 或当前板级文档为准。
8. 建立完成确认清单
☐
vendorsetup.sh的 lunch 选项可以显示并正确解析。☐
device.mk的平台、架构、Buildroot 配置和文件系统类型匹配。☐
Build.mk引入了实际需要的构建规则。☐
UBOOT_BUILD_CONFIG在boards.cfg中有对应条目。☐ U-Boot overlay 与源码树路径一致,
make uboot通过。☐
KERNEL_PATH、KERNEL_CONFIG_PATH和KERNEL_BUILD_CONFIG相互匹配。☐
KERNEL_BOARD_OVERLAY_PATH和KERNEL_BOARD_PATH指向正确位置。☐ defconfig 打开设备树和外置板级配置选项。
☐ 外置 Kconfig、各级 Makefile 和 DTS 文件逐级连通。
☐
CONFIG_DT_与dtb-$(CONFIG_DT_名称一致。☐ DTS 的 GPIO、pinctrl、电源、复位、时钟、总线参数和保留内存已按原理图确认。
☐ 构建输出中实际生成目标 DTB,且镜像流程使用该 DTB。
☐ OTA 配置、分区表和启动参数一致。
☐
make show-modules和整体make的结果符合产品预期。
9. 常见问题定位
| 现象 | 优先检查项 |
|---|---|
lunch 看不到新产品 | vendorsetup.sh 是否被扫描、脚本是否可执行、产品名格式是否正确 |
| 找不到 defconfig | KERNEL_CONFIG_PATH、KERNEL_BUILD_CONFIG 和内核版本目录 |
| 看不到外置板级 Kconfig | KERNEL_BOARD_PATH、OUTSIDE_BUILD 和顶层 Kconfig 的 source 路径 |
| 能配置但没有生成 DTB | CONFIG_DT_、device-dts/Makefile、always 和 dtb-$(CONFIG_...) |
| DTS 找不到 include | overlay 是否复制到内核源码、DTSI 相对路径和 include 搜索路径 |
| 设备树通过但外设不工作 | status、pinctrl、GPIO 有效电平、电源、时钟、复位和总线参数 |
| U-Boot 能编译但不能启动 | 启动介质、分区、bootargs、串口和内核/DTB 加载地址 |
| 整体构建未编译板级应用 | 应用 LOCAL_MODULE 是否加入 的 PRODUCT_MODULES |
10. 维护建议
升级 SDK、内核或 U-Boot 后,重新核对模板变量和公共 DTSI。
硬件变更时,优先同步 DTS、U-Boot 配置头文件、分区配置和 rootfs 启动脚本,再执行单模块验证。
设备树修改应同时保存 defconfig、Kconfig、Makefile 和 DTS,避免只提交部分文件。
将实际构建命令、镜像输出位置和烧录配置记录在项目 README 中;本文只作为通用方法。
