uboot Linux machine_arch_type辨析

本文探讨了U-Boot与Linux Kernel中machine_arch_type的定义与使用方法,特别是在支持多种板子的bsp中如何通过宏定义区分不同的硬件平台。

mark


uboot和Linux kernel中均有对machine_arch_type的定义和使用。假设有这样的应用场景:一个bsp需要支持不同的板子,可能是同一个芯片的不同参考设计。在此情况下,bsp的大多数代码可以复用,只有极少数的板级配置不同。可以使用类似与machine_is_xx()的函数调用来区分。


uboot和Linux kernel下都有一个脚本文件gen_mach_type来生成mach-types.h文件,文件中的宏定义类似以下方式:

#ifdef CONFIG_MACH_S3C2410
# ifdef machine_arch_type
#  undef machine_arch_type
#  define machine_arch_type     __machine_arch_type
# else
#  define machine_arch_type     MACH_TYPE_S3C2410
# endif
# define machine_is_s3c410()        (machine_arch_type == MACH_TYPE_S3C2410)
#else
# define machine_is_s3c2410()        (0)
#endif


假设现在有s3c2410和s3c2440两个板子,CONFIG_MACH_S3C2410与CONFIG_MACH_S3C2440均有定义。在宏第一个s3c2410的时候

#  define machine_arch_type     MACH_TYPE_S3C2410

而在定义第二个s3c2440的时候,

#  define machine_arch_type     __machine_arch_type

因此machine_is_s3c410()和machin_is_s2c2440的真与假是由machine_arch_type也就是__machine_arch_type的值来决定的。如果只是定义一个配置,那就有CONFIG_MACH_S3C2410宏来决定。


那问题就回到__machine_arch_type的定义在哪里?参考网友的文章:


Setup_arch()函数主要工作是安装cpu和machine,并为start_kernel()后面的初始化函数指针指定值。
其中setup_processor()函数调用linux/arch/arm/kernel/head_common.S 中的lookup_processor_type函数查询处理器的型号并安装。
Setup_machine()函数调用inux/arch/arm/kernel/head_common.S 中的lookup_machine_type(__machine_arch_type)函数根据体系结构号__machine_arch_type,在__arch_info_begin和__arch_info_end段空间查询体系结构。问题是__machine_arch_type是在什么时候赋的初值?__arch_info_begin和__arch_info_end段空间到底放的是什么内容?
__machine_arch_type是一个全局变量,在arch/arm/boot/compress/misc.c的解压缩函数中得以赋值。
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, int arch_id)
{
  __machine_arch_type = arch_id;
}
__arch_info_begin和__arch_info_end段空间到底放的内容由链接器决定,存放是.arch.info.init段的内容。这个段是通过段属性__attribute__指定的。Grep一下.arch.info.init 得到./include/asm/mach/arch.h:53: __attribute__((__section__(".arch.info.init"))) = { \ 在linux/include/asm-arm/mach/arch.h 中发现MACHINE_START宏定义。
#define MACHINE_START(_type,_name) \
       static const struct machine_desc __mach_desc_##_type \
       __attribute_used__ \
  __attribute__((__section__(".arch.info.init"))) = { \
  .nr = MACH_TYPE_##_type, \
  .name = _name,
  #define MACHINE_END \
};
是的!你已经精准定位到了问题的核心! > ✅ **必须为 `nvt98632` 添加对应的配置文件路径逻辑**,否则 `UBOOT_BOARD_MK_FILE` 会沿用默认规则,可能导致错误或找不到文件。 --- ## 🔍 当前代码分析 ```makefile $(warning $(UBOOT_SOC_TYPE)) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE).mk ifeq ($(CONFIG_FACTORY_BOOT_USE_AR8033),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_ar8033.mk endif ifeq ($(CONFIG_TARGET_novatek_nvt98635),y) ifeq ($(CONFIG_FLASH_PARTITION_TYPE_DYNAMIC),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_emmc.mk else UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_nand.mk endif endif ``` ### ❌ 存在的问题: - 只处理了 `nvt98635` - 对于 `nvt98632`,即使选中了目标平台,也不会进入任何分支 - 最终使用的是第一行的默认值: ```makefile ./configs/$(BOARD)_$(UBOOT_SOC_TYPE).mk ``` 但这个文件可能并不存在(比如实际需要的是 `_nand.mk` 版本) --- ## ✅ 正确做法:为 `nvt98632` 添加相同逻辑 你需要添加一个针对 `CONFIG_TARGET_novatek_nvt98632` 的判断块: ```makefile ifeq ($(CONFIG_TARGET_novatek_nvt98632),y) ifeq ($(CONFIG_FLASH_PARTITION_TYPE_DYNAMIC),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_emmc.mk else UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_nand.mk endif endif ``` --- ## ✅ 完整修复后的 Makefile 片段如下: ```makefile $(warning $(UBOOT_SOC_TYPE)) # 默认配置文件 UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE).mk # 如果启用了 AR8033 PHY 支持 ifeq ($(CONFIG_FACTORY_BOOT_USE_AR8033),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_ar8033.mk endif # NVT98635 平台特殊处理 ifeq ($(CONFIG_TARGET_novatek_nvt98635),y) ifeq ($(CONFIG_FLASH_PARTITION_TYPE_DYNAMIC),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_emmc.mk else UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_nand.mk endif endif # NVT98632 平台特殊处理 ← 新增! ifeq ($(CONFIG_TARGET_novatek_nvt98632),y) ifeq ($(CONFIG_FLASH_PARTITION_TYPE_DYNAMIC),y) UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_emmc.mk else UBOOT_BOARD_MK_FILE := ./configs/$(BOARD)_$(UBOOT_SOC_TYPE)_nand.mk endif endif ``` --- ## 📁 同时确保对应配置文件存在 假设: - `BOARD = novatek` - `UBOOT_SOC_TYPE = nvt98632` 那么根据你的配置,会查找以下文件之一: | 条件 | 文件名 | |------|-------| | 普通模式 | `configs/novatek_nvt98632.mk` | | 使用 eMMC 分区 | `configs/novatek_nvt98632_emmc.mk` | | 使用 NAND 分区 | `configs/novatek_nvt98632_nand.mk` | | 使用 AR8033 + NAND | `configs/novatek_nvt98632_ar8033.mk` | 👉 所以你要确认这些文件是否存在: ```bash ls -l tp_package/factory_boot/configs/novatek_nvt98632*.mk ``` 如果不存在,就从 `nvt98635` 的复制一份改名: ```bash cp tp_package/factory_boot/configs/novatek_nvt98635_nand.mk \ tp_package/factory_boot/configs/novatek_nvt98632_nand.mk cp tp_package/factory_boot/configs/novatek_nvt98635_emmc.mk \ tp_package/factory_boot/configs/novatek_nvt98632_emmc.mk ``` 然后根据硬件修改内容。 --- ## ✅ 调试建议:打印最终使用的文件 加一行调试输出,方便排查: ```makefile $(info [FACTORY_BOOT] Using config file: $(UBOOT_BOARD_MK_FILE)) ``` 编译时你会看到: ```bash [FACTORY_BOOT] Using config file: ./configs/novatek_nvt98632_nand.mk ``` 一目了然。 --- ## ✅ 总结 | 问题 | 解决方案 | |------|----------| | `UBOOT_BOARD_MK_FILE` 没适配 `nvt98632` | 添加 `ifeq ($(CONFIG_TARGET_novatek_nvt98632),y)` 判断块 | | 配置文件不存在 | 创建 `novatek_nvt98632_nand.mk` / `emmc.mk` 等 | | 缺少调试信息 | 加 `$(warning ...)` 和 `$(info ...)` | | 逻辑不统一 | 让 `nvt98632` 和 `nvt98635` 处理方式一致 | 你现在要做的是两件事: 1. ✅ 在 Makefile 中添加 `nvt98632` 的条件判断 2. ✅ 创建对应的 `.mk` 配置文件 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值