资讯动态

Hi3531 uboot移植实战:DDR3参数配置与板级移植详解

发布时间:2026/9/19 10:38:58 来源:尧图企业网站定制
简介面向嵌入式系统开发者的海思Hi3531平台UBoot移植PDF完整覆盖UBoot在Hi3531上的从零移植流程拷贝并解压SDK中的uboot源码设置make ARCHarm CROSS_COMPILEarm-hisiv200-linux- godnet_config编译环境复制godnet板级BSP到hi3531_cj2102目录同步修改config.h、config.mk及hisfc300new_spi_ids.c中的适配项并调整默认IP、PHY地址和服务器地址以适应实际网络。文档重点解决外接DDR3芯片MT41K256M16HA-125IT与SDK默认参数不一致的问题根据芯片手册修改DDRC_RNKCFG0x2C和DDRC_TIMING10x54两个关键寄存器其中0x54的bit7~bit0按trfc208、tzqcs64设为0xD0再通过uboot_tools生成reg_info.bin、执行mkboot.sh合成u-boot-hi3531.bin。最后给出FastBoot串口烧录和UBoot ping PC的验证步骤。除烧录演示外文档还解释了编译脚本的创建方式以及DDR时序参数从芯片手册到寄存器值的换算思路方便读者迁移到其他DDR型号。全资源共1个PDF文件压缩包1.38MB已有2518人学习下载。适合需要在海思3531上完成启动引导、内存配置与网络功能调通的嵌入式工程师也可作为UBoot移植排错和寄存器参数调整的实用参考。1. 为什么Hi3531的uboot移植卡在DDR3参数上海思Hi3531的uboot移植最常见的现象不是编译失败而是镜像烧进去后串口完全无输出或者DDR training直接报错。原因往往只有一个SDK里自带的参考板godnet用的是海思官方DDR颗粒而实际项目的DDR3选型几乎不会和它一致。比如CJ2102板卡外接的是镁光MT41K256M16HA-125IT一共4片每个DDR控制器挂2片这种组合必须在DDR参数表里改掉rank配置和时序寄存器否则uboot连起来的机会都没有。这篇记录从板级文件拷贝讲起把编译脚本、SPI Flash ID处理、DDR3的0x2C与0x54寄存器修改、reg_info.bin生成、FastBoot烧录和网络测试串在一起适合手里有Hi3531 SDK、正在做替换板卡或改DDR方案的嵌入式工程师参考。2. 板级移植从godnet拷贝到生成u-boot.bin2.1 SDK源码的拷贝与解压拿到Hi3531_SDK_V2.0.A.0之后首先从/opt/pkg/Hi3531/Hi3531_SDK_V2.0.A.0/osdrv/下把uboot目录整体拷贝到自己的工作目录。不要直接在原SDK里改因为后续要反复修改和编译一旦改坏还能从原始目录恢复。mkdir -p ~/hi3531_cj2102 cp -r /opt/pkg/Hi3531/Hi3531_SDK_V2.0.A.0/osdrv/uboot ~/hi3531_cj2102/ cd ~/hi3531_cj2102/uboot # 解压uboot压缩包具体文件名以SDK实际为准 tar xf u-boot-*.tar.*这里的关键是保持目录结构完整因为后续的board、include/configs、drivers/mtd/spi等路径都是相对uboot根目录的。解压后先不急着改文件建议先确认一下交叉编译器是否在环境变量里。海思默认用的是arm-hisiv200-linux-如果直接执行make提示找不到编译器就是环境变量没配好。我一般会先执行一次arm-hisiv200-linux-gcc -v确认工具链可用再继续。2.2 编译官方godnet配置拿到基础config这一步很多人会跳过但实际不能省。官方godnet配置第一次编译的目的是生成include/config.h等自动配置文件后续修改config.h和config.mk、新增板级目录时Makefile需要依赖这些自动生成的文件才能正常认到新板型。make ARCHarm CROSS_COMPILEarm-hisiv200-linux- godnet_config make ARCHarm CROSS_COMPILEarm-hisiv200-linux-ARCHarm指定目标架构为ARMCROSS_COMPILE指定交叉编译前缀最终实际的编译命令会被拼成arm-hisiv200-linux-gcc。第一次编译完成之后uboot根目录下会出现u-boot.bin但这只是官方参考板的镜像还不能直接用。我们真正要的是它生成的那些config中间文件。2.3 建立hi3531_cj2102板级目录并修改config.h与config.mk进入board目录把godnet目录下的内容完整拷贝一份命名为hi3531_cj2102。同理把include/configs/godnet.h拷贝成include/configs/hi3531_cj2102.h。这两个文件名必须和板型一致因为后续Makefile会按照BOARD名字去寻找对应的板级文件。cd ~/hi3531_cj2102/uboot cp -r board/godnet board/hi3531_cj2102 cp include/configs/godnet.h include/configs/hi3531_cj2102.h拷贝完成后修改include/config.h把原来指向godnet.h的include路径改成hi3531_cj2102.h。同时修改include/config.mk里的BOARD变量。需要注意config.mk里有些厂商信息也可能写死比如SOC和VENDOR一般保持hisilicon不变只改BOARD。文件修改项原始值修改后include/config.hinclude路径configs/godnet.hconfigs/hi3531_cj2102.hinclude/config.mkBOARDgodnethi3531_cj2102修改完成后可以顺手检查一下board/hi3531_cj2102目录里的Makefile确认它是否引用了godnet.c这类文件名。如果有需要同步改成hi3531_cj2102.c或者保持原文件名不动也可以只要make能找到目标文件。常见做法是直接把godnet.c重命名成hi3531_cj2102.c再改掉目录内Makefile里的目标名这样看起来更整洁。2.4 编写编译脚本并处理SPI Flash ID表海思这套uboot的Makefile逻辑比较绕直接改Makefile来适配新板型容易改错。更干净的做法是写一个独立的编译脚本每次编译都执行脚本不碰Makefile。#!/bin/sh set -e make ARCHarm CROSS_COMPILEarm-hisiv200-linux- clean make ARCHarm CROSS_COMPILEarm-hisiv200-linux- hi3531_cj2102_config make ARCHarm CROSS_COMPILEarm-hisiv200-linux- -j4set -e保证任何一步失败就停止避免在错误基础上继续编译。hi3531_cj2102_config这个目标是在修改完config.h和config.mk之后才会生成的如果前面跳过第一步官方编译这里就会报错。脚本中的-j4根据本机CPU核数调整编译机核多可以用-j8。SPI Flash ID表的处理在drivers/mtd/spi/hisfc300new/hisfc300new_spi_ids.c。原文档要求把第715行、736行、781~785行、791行、1331~1335行、1341~1344行注释掉。这些行对应的是海思Flash ID匹配表里的一部分条目不注释的话uboot在识别SPI NOR Flash时可能匹配到错误的型号导致启动阶段卡在Flash初始化。可以用下面的脚本一次性处理for ln in 715 736 781 782 783 784 785 791 1331 1332 1333 1334 1335 1341 1342 1343 1344; do sed -i ${ln}s/^/\/\/ / drivers/mtd/spi/hisfc300new/hisfc300new_spi_ids.c done注意这段代码只能在干净的源码上执行一次。如果重复执行已经注释的行会再被加一遍//如果原本是整行注释再在前面加//会导致语法混乱。判断是否生效可以打开文件查看对应行确认首字符已经变成//。2.5 修改IP、服务器地址和PHY地址网络参数都在include/configs/hi3531_cj2102.h里典型需要改的宏如下宏名默认值示例说明CONFIG_IPADDR0xC0A80011uboot本机IP即192.168.0.17CONFIG_SERVERIP0xC0A8000Atftp服务器IP即192.168.0.10CONFIG_NETMASK0xFFFFFF00子网掩码255.255.255.0CONFIG_PHY_ADDR0x088E1512的MDIO地址IP地址在头文件里通常写成16进制的大端格式改的时候不要直接写成点分十进制。PHY地址要根据原理图确认CJ2102板上88E1512工作在地址0x0有些板卡会用0x1。如果PHY地址写错uboot启动时EMAC0初始化会找不到PHYping命令也会一直报link is down。做完这些修改后执行编译脚本得到u-boot.bin。这个bin还不能直接烧录它只包含uboot代码不包含DDR控制器初始化参数。DDR参数需要单独合成这就是下一章的重点。3. DDR3参数配置0x2C与0x54寄存器决定uboot能否起来3.1 为什么官方DDR参数不能直接用Hi3531的DDR控制器参数由两个文件配合生成一个是支持DDR0和DDR1双控制器的Excel表格另一个是uboot_tools目录下的mkboot.sh脚本。Excel表格里包含了DDR控制器所有寄存器的值海思提供一个名为uboot-Hi3531-bvt_No1_930_310_620_ddr0_ddr1_slow_ddr_lp.xls的参考工程。这个参考工程使用的是海思调试板上的DDR颗粒型号而CJ2102用的是镁光MT41K256M16HA-125IT如果直接采用默认xls生成reg_info.bin上电后DDR training大概率失败。MT41K256M16HA-125IT是16bit位宽、256M x 16的DDR3L颗粒4片组合方式为DDR0控制器挂2片、DDR1控制器挂2片。也就是说每个控制器看到的都是32bit总线、1个rank。官方参考配置可能是2个rank或者不同位宽组合所以必须修改寄存器。3.2 修改DDRC_RNKCFG0x2C寄存器rank数量与位宽匹配打开xls表格后找到DDR0和DDR1的寄存器配置页。0x2C寄存器对应的名称是DDRC_RNKCFG它决定当前控制器下挂几个rank、每rank的数据位宽。海思手册里rank配置字段含义如下表bit位字段含义[1:0]RANK_COUNT0b00表示1个rank0b01表示2个rank[3:2]DATA_WIDTH0b00表示32bit总线0b01表示16bit总线[7:4]RSVD保留位按默认值对照CJ2102的方案DDR0和DDR1各自都是2片16bit颗粒并联成32bit并且只有1个rank所以0x2C应该配成1个rank、32bit总线按位组合为0x1。原本官方xls里如果是2个rank则大概率是0x3或类似值需要改掉。修改流程非常简单在Excel里找到地址为0x2C的那一行把DDR0页和DDR1页数值都改为0x1。保存后点击Generate reg bin file按钮就会生成reg_info.bin。这里要注意xls文件里不能只改DDR0不改DDR1Hi3531是双DDR控制器方案两个控制器都必须正确配置否则对应通道的内存读写会异常表现形式就是uboot起来后md命令读到一半死机。3.3 修改DDRC_TIMING10x54寄存器tRFC与tZQCS计算0x54寄存器是DDRC_TIMING1主要控制DDR的时序参数。其中bit7~bit0对应tRFC。MT41K256M16HA-125IT的数据手册里标称tRFC208tZQCS64。海思手册对这一段的定义是直接把周期数写在bit7~bit0里所以需要把208转成16进制208 0xD0也就是在xls中0x54寄存器的bit7~bit0填写0xD0其他bit位保持官方默认值。这里容易出错的地方是有人认为208是纳秒需要先除以时钟周期再换算但在海思这套工具链里xls里填的就是手册给出的tRFC标称值。换成别的DDR3颗粒时一定要重新查手册中tRFC的值不能直接套用208。比如常规DDR3-1600颗粒的tRFC往往是260或313对应到bit7~bit0分别是0x104或0x139那就超出了8位宽度说明还需要修改0x54寄存器更高bit位的字段。修改后的xls保存生成reg_info.bin。此时reg_info.bin里就包含了正确的rank配置和时序参数。3.4 用mkboot.sh合成最终烧录镜像把生成的reg_info.bin拷贝到上一步拷贝出来的uboot_tools目录同时把编译出的u-boot.bin也拷贝过去。uboot_tools目录位于SDK的osdrv/tools/pc_tools/uboot_tools拷贝之后执行chmod x mkboot.sh ./mkboot.sh reg_info.bin u-boot-hi3531.binmkboot.sh的作用是把u-boot.bin和reg_info.bin合并生成一个带DDR初始化参数的镜像u-boot-hi3531.bin。这个文件才是最终需要烧录的uboot镜像。很多人直接把编译出来的u-boot.bin烧进Flash结果上电后DDR控制器根本没有初始化代码串口自然不会有任何输出。文件用途是否直接烧录u-boot.bin编译生成的纯uboot代码否缺DDR参数reg_info.binDDR控制器寄存器配置否只是一个参数段u-boot-hi3531.binmkboot.sh合成的完整镜像是4. 烧录与网络验证FastBoot工具和EMAC0的坑4.1 FastBoot工具烧录流程海思Hi3531的uboot烧录需要用到官方提供的FastBoot工具它不是Android的那个fastboot而是Windows下针对海思芯片的镜像烧录工具。连接方式使用USB转串口线板卡端接RS232调试串口PC端识别出COM口号之后打开FastBoot工具。# FastBoot工具是Windows GUI程序没有命令行模式 # 操作顺序选择COM口 - 选择u-boot-hi3531.bin - 点击Burn - 手动按板卡复位键点击Burn按钮后板卡如果没有反应不要急着点第二次而是手动按一下板卡上的复位按钮让uboot重新启动并进入烧录模式。FastBoot工具会在串口输出烧录进度等待显示烧录成功后重新给板卡上电即可进入uboot命令行。这一步最常见的失败场景是选了错误的镜像。u-boot.bin不带DDR参数烧进去之后启动时DDR完全没初始化FastBoot工具虽然能烧录但后续无法通过串口交互。确认烧录成功后可以重新上电观察串口输出正常会有DDR training相关的打印信息。4.2 烧录后首次ping失败的判断板卡启动到uboot命令行后连接网线把PC的IP设置为192.168.0.18然后在uboot命令行执行ping 192.168.0.18注意这个操作只能用来测试uboot到PC的连通性不要反过来在PC上ping uboot的IP因为uboot默认不处理ICMP请求PC端会一直显示无响应这是正常现象。另外上电后第一次执行ping大概率会失败一次提示link is down或者超时此时按CtrlC退出再执行一次ping就会成功。第一次失败的原因基本可以锁定在PHY上电复位时序。Hi3531的外围PHY芯片是88E1512uboot的EMAC0驱动在PHY上电完成后才能读到链接状态。如果uboot启动速度很快PHY芯片的复位还没结束驱动就完成了初始化那么第一次ping必然失败。第二次ping时PHY已经稳定所以能通。网络驱动本身不需要做修改88E1512和Hi3531的MAC是直连方案。现象原因对策第一次ping失败第二次成功PHY上电复位未完成手动再ping一次或加PHY软复位PC ping uboot不通uboot不处理ICMP请求正常现象无需处理ping一直失败PHY地址或网络参数错误检查CONFIG_PHY_ADDR和IP配置4.3 EMAC0与EMAC1的差异Hi3531有EMAC0和EMAC1两个网络接口但uboot阶段默认只提供EMAC0的网络功能。如果板卡实际用的是EMAC1那么不能通过修改配置文件来切换必须修改uboot源码里的网络初始化部分。EMAC1的PHY地址、MDIO总线、引脚复用都需要重新配置工程量大不少。CJ2102项目直接用EMAC0所以这个坑没有踩到。如果你的板卡只能用EMAC1建议还是优先改硬件跳线或者接受uboot阶段没有网络的现实等kernel起来后再用完整驱动。5. 进阶技巧DDR参数核验与PHY复位时序优化5.1 用md命令验证DDR配置是否生效uboot起来之后不要急着烧kernel先用内存读写命令验证DDR参数是否真正稳定。在uboot命令行执行mw.l 0x80000000 0x5A5A5A5A 0x1000 md.l 0x80000000 0x10mw.l表示按32bit写入0x80000000是DDR0的起始地址0x1000是写入的字数。写入后再读回来如果读出的值全部是5a5a5a5a说明DDR0读写正常。再用同样方式检查DDR1对应的地址段比如0x10000000或0x20000000具体地址要以Hi3531的地址映射表为准。如果读到一半出现总线错误或者值不对多半是0x2C的rank配置和实际颗粒组合不匹配。更严格的测试可以写一个递增序列再读回比对但uboot命令行下的循环不便我一般用mw.l配合md.l抽查几个地址段再加上cp.b命令做一次大块内存拷贝校验cp.b 0x80000000 0x10000000 0x100000 md.b 0x10000000 0x10把DDR0前1MB拷到DDR1地址段再读DDR1的内容能正常读出数据就说明两个控制器都可以工作。这一步比直接启动kernel更能暴露DDR参数问题。5.2 避免二次ping问题的PHY软复位如果不想每次都手动CtrlC再ping可以在板级初始化代码里给88E1512加一次软件复位。常见位置是board/hi3531_cj2102/hi3531_cj2102.c中的board_eth_init或board_early_init里通过MDIO总线对PHY的0x00寄存器写入复位位#define PHY_BMCR 0x00 #define PHY_RESET 0x8000 #define PHY_88E1512_ADDR 0x0 /* 在板级网络初始化函数中 */ int i; for (i 0; i 10; i) { mii_write(PHY_88E1512_ADDR, PHY_BMCR, PHY_RESET); udelay(1000); if (!(mii_read(PHY_88E1512_ADDR, PHY_BMCR) PHY_RESET)) break; }写PHY_BMCR为0x8000会触发PHY内部复位复位完成后该寄存器会自动清掉bit15所以循环等待它清零即可。udelay(1000)是1ms延时总共最多等10ms。加上这段后uboot启动阶段PHY就已经复位完成后面的ping第一次就能通。需要注意的是mii_read/mii_write在部分海思uboot版本里封装名可能不同有的用miiphy_read编译报错时搜一下board_eth_init里的现有PHY访问函数再替换。这个思路不仅适用于88E1512只要PHY芯片手册里有BMCR复位位的都可以这么处理。如果你的板卡PHY型号不同先查手册确认0x00寄存器的bit15是否为软复位位再决定是否套用。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价