news 2026/8/25 17:03:02

U-Boot 移植(1)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
U-Boot 移植(1)

1. U-Boot 移植:技术概述

U-Boot(Universal Boot Loader)是嵌入式 Linux 系统中负责引导内核的启动加载程序。其核心任务包括:初始化关键硬件(如时钟、DDR、总线)、加载操作系统内核与设备树映像至内存、并建立引导参数传递机制。

1.1 为什么要进行移植?

U-Boot 虽然提供了通用的初始化框架,但不同开发板的硬件参数存在差异。当开发板的 DDR 时序、存储器类型(EMMC/NAND)、外设驱动接口(如网络 PHY、LCD 屏幕参数)与 U-Boot 官方提供的参考板(Reference Board)不一致时,必须进行移植。移植的本质是通过修改板级配置文件(Defconfig)、头文件(Header files)和驱动源码,使 U-Boot 正确初始化目标硬件环境。

1.2移植的主要内容

  1. 构建系统适配:在configs/board/目录下添加自定义板级配置,通过修改MakefileKconfig建立独立的编译入口。
  2. 硬件驱动适配
  • 外设驱动:根据硬件原理图修改网络 PHY 寄存器地址及复位 GPIO 时序;调整 LCD 时序参数以适配物理面板。
  • 设备树配置:在.dts文件中更新引脚复用(IOMUX)和外设节点属性。
  1. 参数传递机制配置
    通过环境变量(bootcmd,bootargs)设定内核加载路径与启动参数,确保 U-Boot 在倒计时结束后,能够将 Linux 内核与设备树搬运至 DDR 对应地址,并将设备树物理首地址写入 CPU 的r2寄存器,完成控制权移交。

2. 移植流程

2.1 了解 U-Boot 的三种来源

源码种类维护主体技术侧重定位
社区通用版 (Mainline)U-Boot 社区追求架构的标准化、通用性与前沿特性支持。嵌入式开发的基准线,用于技术预研与架构追踪。
原厂内核版 (Vendor SDK)SoC 厂商 (NXP, ST, TI等)针对特定 SoC 系列优化,包含完善的内存初始化(DDR)驱动、时钟拓扑及外设控制器驱动。硬件产品的开发基准,确保 CPU 核心特性的稳定性。
板级工程版 (Board Support)开发板/硬件方案商基于原厂代码,进行具体的引脚复用(IOMUX)、存储介质适配及外设时序微调。交付终端用户的实际可用代码,直接匹配物理电路板。
  1. 社区通用版(Mainline):技术演进的观测窗
    核心价值:它是 U-Boot 最新的设计理念来源。开发者研究 Mainline 可以获知最新的驱动模型(DM)、设备树绑定规范(DT Binding)以及安全引导(Secure Boot)技术演进。
    局限性:由于适配范围太广它往往不包含特定硬件平台的最新补丁或特定 SoC 的专有 IP 驱动,直接移植难度大。

  2. 原厂内核版(Vendor SDK):硬件适配的稳定锚点
    核心价值:半导体厂商在开发 SoC 的同时,会维护一份与其配套的 U-Boot 源码。它不仅包含核心的芯片驱动,还通常附带了原厂参考板(EVK/EVB)的完整配置。
    移植策略:在移植工作中,原厂版本是最稳妥的基准线。绝大多数的内存控制逻辑、SoC 总线驱动均从此版本继承。

  3. 开发板工程版(Board Support):最终产品的适配层
    核心价值:它是对原厂版本进行“裁剪”和“修正”的产物。在工程实践中,开发板厂商的主要工作是物理映射:
    引脚映射:确保板卡上的 GPIO 连线与寄存器映射一致。
    电气参数校准:调整特定 LCD 屏的时序参数、调整 PHY 芯片的复位时序。
    裁剪冗余:移除工程板不需要的调试功能,减小固件体积,缩短冷启动时间。

2.2 U-Boot 源码的选择

在实际工程开发中,这三种 U-Boot 源码的选择依据主要取决于硬件平台与参考设计(Reference Design)的匹配度

  1. 社区通用版 (Mainline):在商业项目与定制硬件开发中基本不作为首选。由于其缺乏特定 SoC 厂商的专有补丁与底层高频调校,对具体芯片的外设支持较弱。
  2. 原厂内核版 (Vendor SDK) 与 板级工程版 (Board Support)
    这是工业界最常用的两种源码来源。
  • 使用半导体厂商评估板(如 NXP 官方 EVK 板):直接使用半导体厂商维护的 U-Boot 源码。
  • 使用第三方标准开发板(如韦东山的 I.MX6ULL 开发板):首选使用开发板厂商提供的 U-Boot 源码。该源码已由厂商基于原厂 U-Boot 针对其特定电路板完成了引脚复用和外设驱动的闭环适配。
  1. 自主设计板卡(企业产品研发)
    通常以半导体厂商提供的 U-Boot 为基础基准线。若硬件电路参考了第三方开发板的设计(如延续了韦东山开发板的电源与网络拓扑),则会结合两者的源码进行裁剪。
    在第三方开发板上直接换用原厂 U-Boot,由于部分外设(如网络 PHY 芯片型号、LCD 屏时序、电源管理 PMIC)存在硬件电路差异,部分驱动将无法直接运行,必须进行代码级修改以完成适配——这一过程即标准的U-Boot 移植

3. 韦东山 IMX6ULL 开发板的 U-Boot 移植

本文采用 NXP 半导体场上的 U-Boot 进行移植,原因如下:

维度使用厂商(正点原子/韦东山)U-Boot使用 NXP 原厂 U-Boot 移植(你的选择)带来的核心学习好处
驱动开发深度核心驱动(如 LAN8720A 网络、时钟)已由厂商重写完毕,开发者只需修改 GPIO 引脚编号。必须亲手剔除原厂公版的复杂外设逻辑(如 74LV595 扩展芯片),并根据芯片手册手写物理电平的复位与延时时序。真正掌握物理层驱动编写与硬件总线时序控制。
构建系统认知直接在已有单板目录下修补代码,较少触及底层的配置与编译规则。必须完整执行大厂标准的“立门户”流程:新建单板目录、配置 Kconfig 菜单、编写 Makefile、定制 defconfig。彻底吃透嵌入式 Linux 系统的条件编译与自动打包机理。
调试(Debug)锻炼硬件适配度高,编译烧写后基本直接点亮,缺乏排错机会。原厂代码与目标板硬件存在天然冲突,必然高频遭遇网口不通、开机卡死、屏幕花屏等故障。逼迫自己学会对比原理图、分析时钟信号流向、读写底层寄存器,建立解决死机 Bug 的高级排错能力。

3.1 NXP 官方 U-Boot 编译

3.1.1 版本确定

由于开发板的资料是 Uboot-2017.03,所以我们去 GitHub 下载对应的版本:NXP官方 uboot 源码下载

3.1.2 编译链确定


从韦东山开发板的参考手册可以得知编译链为:
arm-buildroot-linux-gnueabihf-

3.1.3 默认配置文件选择


进入 configs/ 目录搜索 mx6ull*,列出相关的默认配置文件

  1. 第一步:核对芯片型号与封装(14x14 还是 9x9?)
    14x14 与 9x9 的含义:
    这代表 i.MX6ULL 芯片的物理封装尺寸(单位是毫米,即 14mm×14mm 或 9mm×9mm)。不同封装的芯片,其引脚(Pin)数量和球位引脚分布完全不同。
    如何选择:
    打开韦东山开发板的核心板原理图,查看 CPU 型号(或者直接拿放大镜看你板子中间那颗 NXP 芯片上的丝印)。韦东山的 i.MX6ULL 开发板采用的是最常用的 MAPBGA 289 针脚封装,其物理尺寸正是 14x14 毫米。
    结论:
    直接过滤掉所有带 9x9 的文件,锁定 mx6ull_14x14_…。
  1. 第二步:核对板型(evk 还是 arm2?)
    evk 的含义:
    Evaluation Kit(官方评估板)。NXP 官方公版开发板的名字就叫 i.MX6ULL EVK。
    arm2 的含义:
    NXP 内部用于特定验证或早期硅片测试的板卡(通常外设极少,不适合用来做应用开发)。
    结论:
    锁定 evk。
  1. 第三步:判定启动与存储介质(驱动适配的关键)
    这是最关键的一步,U-Boot 需要知道它自己将被烧写到哪里,以及从哪里加载 Linux 内核。
    mx6ull_14x14_evk_nand_defconfig:
    适用于板载存储器为 NAND Flash 颗粒的开发板。
    mx6ull_14x14_evk_emmc_defconfig:
    适用于板载存储器为 eMMC 芯片的开发板。
    目前市面上百问网(韦东山)主推的 i.MX6ULL 开发板,绝大多数都是 eMMC 版本(板载一颗 8GB 或 4GB 的 eMMC 芯片)。
    因此选择mx6ull_14x14_evk_emmc_defconfig

3.1.4 编译过程

#1.彻底清理工程(清除之前由于用错编译器留下的错误缓存,这步非常关键) make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf-distclean #2.配置基线:载入 NXP 官方 I.MX6ULL EMMC 评估板的默认配置文件 make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf-mx6ull_14x14_evk_emmc_defconfig #3.全速编译:调用虚拟机12个线程全速编译 U-Boot 源码 make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf--j12


核心镜像文件(用于烧写启动)
这是编译出来的终极目标,也是唯一需要传到板子上运行的文件:
u-boot-dtb.imx (核心中的核心)
作用:
直接用于烧写到 SD 卡或 eMMC 的最终镜像。
本质:
它是把 u-boot.bin(编译出的可执行文件)和 u-boot.dtb(编译出的设备树文件)合并后,在头部加上了 i.MX6ULL 芯片专属的启动头信息(IVT、DCD 等,用于初始化内存参数)。

3.1.5 烧录 imx 文件至 SD卡

维度通用 dd 命令imxdownload 工具
安全性高风险。不带设备检查,一旦把盘符 sdb 错打成系统盘 sda,会直接擦除 Ubuntu 系统致其瘫痪。高安全(防呆)。内部自带防误杀机制,会自动校验目标盘符属性,拒绝向系统盘写入数据。
烧写参数繁琐易错。每次必须手动输入 bs=1k seek=1 来指定跳过前 1KB 字节,漏掉或写错参数板子就无法启动。一键傻瓜化。将“跳过 1KB 绝对扇区”的硬件规则直接写死在源码中,开发者无需记忆复杂的偏移参数。
文件兼容性单一。只能原封不动地平铺数据,无法处理没有芯片启动头(DCD/IVT)的纯裸机 .bin 文件。智能双模。如果是纯 led.bin,会自动帮其补齐 3KB 的芯片启动头再烧写;如果是已带头的 u-boot.imx,则直接烧写。

先手写并编译一个 imxdownload
1.新建 C 文件

cd~/Desktop/uboot_plant/uboot-imx-nxp-imx_v2017.03_4.9.11_1.0.0_ga gedit imxdownload.c

2.粘贴通用源码
把下面这段标准的 imxdownload 开源核心 C 语言代码完整复制,粘贴到刚才弹出的 gedit 窗口中,保存并关闭:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<fcntl.h>#include<sys/stat.h>#include<sys/types.h>intmain(intargc,char*argv[]){FILE*fp_src;intfd_dst;unsignedcharbuf[512];intnread;if(argc!=3){printf("============================================================\n");printf("I.MX6U Embedded Processor Download Tool (Lite)\n");printf("Usage: ./imxdownload <source_bin> <sd_device>\n");printf("Example: ./imxdownload u-boot-dtb.imx /dev/sdb\n");printf("============================================================\n");return-1;}// 打开源镜像文件fp_src=fopen(argv[1],"rb");if(fp_src==NULL){printf("Error: Cannot open source file %s\n",argv[1]);return-1;}// 打开 SD 卡物理设备fd_dst=open(argv[2],O_WRONLY);if(fd_dst<0){printf("Error: Cannot open device %s. Please check sudo permission.\n",argv[2]);fclose(fp_src);return-1;}// 核心逻辑:绝对寻址,定位到物理 SD 卡 1KB 偏移处(第2个扇区)if(lseek(fd_dst,1024,SEEK_SET)<0){printf("Error: lseek failed\n");close(fd_dst);fclose(fp_src);return-1;}printf("Flashing Bootloader %s to %s ...\n",argv[1],argv[2]);// 开始物理扇区平铺写入while((nread=fread(buf,1,sizeof(buf),fp_src))>0){write(fd_dst,buf,nread);}fsync(fd_dst);close(fd_dst);fclose(fp_src);printf("Done! Flash successfully.\n");return0;}

3.现场编译成工具
在终端使用 Ubuntu 本地编译器编译它,并赋予执行权限:

gcc imxdownload.c-oimxdownloadchmod+x imxdownload

4.使用新生成的工具烧写
现在可以直接使用 imxdownload 进行烧写了:

sudo./imxdownload u-boot-dtb.imx /dev/***

*** 是 实际 SD 卡盘符


输入 lsblk 查看,我的 TF卡 是16G的,实际容量和sdb的14.6G相符,所以 *** 换成 sdb 进行烧写

3.1.6 启动开发板验证


切换到 SD/TF卡 启动并连接串口,启动开发板查看信息:

📺 LCD 屏幕问题汇总

  1. 现状体检
    U-Boot 识别参数:
    480 × 272 480 \times 272480×272分辨率(TFT43AB 4.3寸低清屏)。
    实际物理硬件:
    通常为1024 × 600 1024 \times 6001024×600(7寸屏)。
    物理现象:
    上电倒计时 3 秒内,屏幕黑屏、白屏或无任何有效画面。
  2. 底层根本原因
    LCD 驱动的本质是“对表”。U-Boot 驱动此时发出的像素时钟频率(Pixel Clock)以及行同步/场同步时序参数(HBP, HFP, VBP, VFP)完全是按照 4.3 寸低清屏设计的。屏幕控制 IC 收到这些错误的电信号后,无法锁定帧频,导致硬件直接拒绝显示。
  3. 后续移植修改靶心
    核心文件:
    board/freescale/mx6ullevk/mx6ullevk.c
    修改动作:
    在源码中找到 displays 数组下的 struct display_info_t 结构体,将原本 TFT43AB 的参数,依照你物理屏幕的数据手册(Datasheet),精确修改为适配你当前屏幕的分辨率与时序参数。

🌐 网络(Ethernet)问题汇总

  1. 现状
    U-Boot 报错提示:
    Net: No ethernet found.(未找到以太网设备)。
    物理现象:
    无法使用 ping 命令,无法通过 tftp 或 nfs 远程下载内核,网络功能完全瘫痪。

  2. 底层根本原因
    这是典型的外围控制电路不匹配导致网络物理层(PHY)无法工作。
    NXP 官方原厂设计:
    使用 KSZ8081 PHY 芯片,且网口的复位引脚由一颗外扩的 74LV595 串转并芯片来间接控制。
    百问网实际硬件设计:
    使用 LAN8720A PHY 芯片,且网口的复位引脚直接连接在 i.MX6ULL CPU 的物理 GPIO 上(无 74LV595 芯片)。
    冲突点:
    U-Boot 启动时试图通过 I2C/SPI 去驱动那个压根不存在的 74LV595 芯片来释放网口复位,导致 LAN8720A 芯片始终处于死机复位状态,MDIO 总线根本找不到网络物理层设备。

  3. 后续移植修改靶心
    核心文件:
    board/freescale/mx6ullevk/mx6ullevk.c(引脚复用与物理复位逻辑)
    include/configs/mx6ullevk.h(网络宏定义与 PHY 地址配置)
    修改动作:
    在 mx6ullevk.c 中彻底剔除 74LV595 的驱动代码。
    写入纯粹的 GPIO 操作代码,在上电时给 LAN8720A 的复位引脚拉低再拉高,完成硬件复位。
    在 mx6ullevk.h 中将 PHY 芯片的地址(CONFIG_FEC_MXC_PHYADDR)修改为你的单板实际物理地址(通常是 0x0 或 0x1)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 17:00:13

微信OpenClaw插件:官方能力本地化部署与腾讯云Lighthouse实战

1. 项目概述&#xff1a;从“龙虾插件”看微信生态的开放新范式最近&#xff0c;微信官方发布了一个代号为“OpenClaw”的插件&#xff0c;这个名字听起来有点意思&#xff0c;直译过来就是“开放的爪子”&#xff0c;或者更形象点&#xff0c;叫“龙虾钳”。这可不是一个简单的…

作者头像 李华
网站建设 2026/8/25 16:49:17

LinguaSafe: A Comprehensive Multilingual Safety Benchmark for Large Language Models

LinguaSafe相关总结与翻译 一、文章主要内容 (一)研究背景 随着大型语言模型(LLMs)在全球技术领域的广泛应用,其在不同语言和文化背景下的安全性愈发重要。然而,现有多语言安全评估存在明显不足,一方面过度依赖翻译数据,而这类数据的毒性远低于自然产生的原生多语言…

作者头像 李华
网站建设 2026/8/25 16:44:27

舵机本质是闭环位置伺服系统,不是普通电机

1. 舵机不是“舵”也不是“机”&#xff0c;而是一个精密的闭环位置伺服系统很多人第一次听到“舵机”这个词&#xff0c;下意识会联想到船上的舵、飞机的尾翼&#xff0c;或者干脆以为是某种小型发动机——这恰恰暴露了对它最根本的误解。舵机&#xff08;Servo Motor&#xf…

作者头像 李华
网站建设 2026/8/25 16:41:02

零基础学修板别瞎看书!抓牢 5 项核心技能,比啃半年教材管用

真的&#xff0c;干维修快二十年&#xff0c;见过太多新手一头扎进弯路里。上来先抱一堆厚书回家&#xff0c;什么模电数电、电子电路基础、单片机原理&#xff0c;书买了一大堆&#xff0c;摞起来比烙铁架都高&#xff0c;啃得头昏脑涨。啃了仨月半年&#xff0c;公式背了不老…

作者头像 李华
网站建设 2026/8/25 16:40:40

Docker容器化LNMP环境搭建:从原理到实战部署PHP项目

1. 项目概述与核心价值在服务器运维和Web开发领域&#xff0c;环境搭建一直是个既基础又磨人的活儿。我记得刚入行那会儿&#xff0c;为了在CentOS上配一个能跑的LNMP&#xff08;Linux, Nginx, MySQL, PHP&#xff09;&#xff0c;得照着教程一行行敲命令&#xff0c;处理各种…

作者头像 李华
网站建设 2026/8/25 16:35:21

Kotlin 语言【知识点整理2】

目录 一、基本概念 1.包的定义与导入 2.程序入口点 2.1 输入 3.变量 二、基本类型 1.数字 1.1 整数类型 1.2 浮点类型 1.3 数字字面常量 1.4 装箱与缓存 1.4.1 JVM是怎么存储数字的&#xff1f; 1.4.2 使用可空类型的时候会触发装箱操作&#xff1a; 1.4.3 JVM 对…

作者头像 李华