
摘要:本文深入剖析 Zephyr 中west build -b my_board到CONFIG_SOC_xxx=y的完整链路。核心结论是:-b选择的是 Board 而非 SoC,SoC 由 Board 的 Kconfig 体系(select/default y)进一步选择。全文从 Board 的board.yml、Kconfig.board、Kconfig.defconfig、my_board_defconfig等文件出发,逐层拆解 Board → SoC Family → SoC Variant → Kconfig symbol → CMake source selection 的完整流程,并厘清soc.yml(SoC 目录/metadata)与Kconfig.soc(Kconfig symbol)的区别、select与default y的差异、Kconfig 与 Devicetree 的分工,最后给出基于build/zephyr/.config的 SoC 选择诊断方法,帮助 BSP 开发者快速定位「SoC 代码未被编译」的问题。接入 Zephyr 中断控制器下面接着你的Zephyr BSP 系列。这一篇建议把重点放在一个非常关键的问题上:用户只写了 west build -b my_board,Zephyr 为什么最后会得到 CONFIG_SOC_xxx=y?真正的答案不是「Board 配置了 SoC」这么简单,而是一条完整的Board → SoC family → SoC variant → Kconfig symbol → CMake source selection链路。从 -b my_board 到 CONFIG_SOC_xxx:Zephyr 是怎么选中你的 SoC 的?前面我们已经建立了:soc.yml + Kconfig.soc:让 Zephyr **认识 SoC** soc/:提供 SoC 的代码 board/:描述具体开发板 DEVICE_DT_DEFINE():把硬件设备最终变成 struct device这一篇继续向前追:west build-bmy_board │ ▼ Board │ ▼ Board Kconfig │ ▼ SoC family / variant │ ▼CONFIG_SOC_xxx=y │ ▼ SoC Kconfig │ ▼ SoC CMakeLists.txt │ ▼ 编译对应 SoC 源码1. 先回答最核心的问题假设我们有自己的板子:boards/ └── my_vendor/ └── my_board/执行:west build-bmy_board samples/hello_world你可能会自然地认为:\-b my_board ↓ my_board ↓ my_soc但实际上不是一个简单的字符串映射。更准确地说:-bmy_board │ ▼ Board definition │ ├── board.yml ├── Kconfig.board ├── Kconfig.defconfig ├── my_board_defconfig └── my_board.dts │ ▼ Kconfig system │ ▼ CONFIG_SOC_... │ ▼ SoC selection也就是说:-b 选择的是 Board,而不是直接选择 SoC。SoC 是 Board 的配置体系进一步选择出来的。2. -b 到底是什么?执行:west build-bmy_board-b 的含义是:buildforboard=my_board也就是:Board=my_board它首先告诉 Zephyr:“我要针对这个 Board 建立一个 build configuration。”这一步本身并没有直接执行:CONFIG_SOC_MY_SOC=y3. Board 在哪里?一个典型 Zephyr Board:boards/ └── my_vendor/ └── my_board/ ├── board.yml ├── Kconfig.board ├── Kconfig.defconfig ├── my_board_defconfig ├── my_board.dts └── CMakeLists.txt其中最重要的几个文件:board.yml Kconfig.board Kconfig.defconfig my_board_defconfig my_board.dts它们分别解决不同的问题。4. board.yml:告诉 Zephyr「我是谁」例如:board: name: my_board full_name: My Board vendor: my_vendor它主要属于 Board metadata。它可以让 Zephyr 知道:my_board ↓ My Board ↓ my_vendor但是:不要把 board.yml 理解成「选择 SoC 的地方」。SoC 选择主要发生在 Kconfig。5. 真正关键的是 Board Kconfig例如:boards/my_vendor/my_board/Kconfig.board可能包含:config BOARD_MY_BOARDselectSOC_MY_SOC于是:BOARD_MY_BOARD │ │select▼ SOC_MY_SOC最终:CONFIG_BOARD_MY_BOARD=yCONFIG_SOC_MY_SOC=y这就是最核心的一层。6. 所以 -b 并不是直接变成 CONFIG_SOC_xxx真正的关系更像:-bmy_board │ ▼ BOARD_MY_BOARD │ │select▼ SOC_MY_SOC │ ▼CONFIG_SOC_MY_SOC=y因此可以记住:-b 选择 Board,Board 的 Kconfig 负责选择 SoC。7. 但实际 Zephyr 里还会多一层真实的 SoC 往往不是:SOC_MY_SOC这么简单。例如一个 MCU 家族:MyVendor MCU Family下面可能有:my_soc_a my_soc_b my_soc_c因此 Zephyr 通常会形成:Board │ ▼ SoC Family │ ▼ SoC Series │ ▼ SoC Variant例如:my_board │ ▼ my_vendor_m4 │ ▼ my_vendor_m4_series │ ▼ my_vendor_m4_123最终才落到具体:CONFIG_SOC_MY_VENDOR_M4_123=y8. 为什么需要这种层次?因为 SoC 通常存在大量共性。例如:MY_VENDOR_M4 │ ├── my_m4_101 ├── my_m4_102 ├── my_m4_201 └── my_m4_202它们可能共享:startup code clock driver interrupt controller GPIO UART timer power management所以 Zephyr 不希望每个 SoC 都复制一份:Kconfig CMakeLists.txt startup.c soc.c而是:SoC Family │ ├── common code │ ├── common Kconfig │ └── common CMake │ ▼ specific variant9. Kconfig.defconfig 又是什么?Board 通常还有:Kconfig.defconfig例如:ifBOARD_MY_BOARD config SOC_MY_SOC default y endif这里就出现了一个非常重要的区别:select和:default y不是同一回事。10. select 和 default y 的区别假设:config BOARD_MY_BOARDselectSOC_MY_SOC这是:Board → 强制选择 SoC而:config SOC_MY_SOC default y表示:如果当前配置环境允许, 那么默认打开 SOC_MY_SOC所以理解 Kconfig 时必须区分:select和:default11. Board defconfig 是另外一层Board 还有:my_board_defconfig里面可能有:CONFIG_SERIAL=yCONFIG_UART_CONSOLE=yCONFIG_CONSOLE=y它表达的是:“这个 Board 默认需要哪些功能。”例如:my_board │ ├──CONFIG_SERIAL=y