U-Boot移植与调试指南

文档信息

  • 项目: 5G/WiFi高清执法记录仪
  • 平台: RV1126B (ARM Cortex-A53, 64位)
  • U-Boot源码路径: /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot

目录

  1. U-Boot的作用
  2. U-Boot移植步骤
  3. U-Boot调试方法
  4. 针对执法记录仪项目的定制
  5. 常见问题与解决方案

一、U-Boot的作用

1.1 什么是U-Boot

U-Boot(Universal Boot Loader)是嵌入式Linux系统的引导加载程序,它在系统启动流程中的位置:

上电 → MiniLoader(TPL/SPL) → U-Boot → Linux Kernel → 根文件系统
         ↑                      ↑
      初始化DDR            初始化硬件、加载内核

启动流程详解:

阶段 名称 运行位置 主要功能
1 TPL (Tiny Program Loader) SRAM 初始化DDR内存
2 SPL (Secondary Program Loader) DDR 加载U-Boot
3 U-Boot DDR 初始化硬件、加载内核
4 Linux Kernel DDR 操作系统内核
5 RootFS DDR 根文件系统

image-20260302155134603

image-20260302155159382

image-20260302155219309

1.2 U-Boot的核心职责

1. 硬件初始化

U-Boot负责初始化系统启动所需的所有硬件设备:

// U-Boot初始化的硬件模块
├── CPU和时钟系统
│   ├── CPU频率配置
│   ├── 系统时钟树配置
│   └── 电源管理单元(PMU)
│
├── 内存控制器
│   ├── DDR参数配置
│   ├── 内存时序调整
│   └── 内存测试
│
├── 串口(UART)
│   ├── 波特率配置
│   ├── 调试输出
│   └── 命令行交互
│
├── 存储设备
│   ├── eMMC控制器
│   ├── SPI Flash控制器
│   └── SD卡控制器
│
├── 网络接口
│   ├── 以太网MAC
│   ├── PHY芯片
│   └── TFTP启动支持
│
└── 其他外设
    ├── GPIO
    ├── I2C
    ├── SPI
    └── USB
2. 加载内核

U-Boot的主要任务是加载并启动Linux内核:

┌─────────────────────────────────────────────────────────┐
│              U-Boot加载内核流程                           │
└─────────────────────────────────────────────────────────┘

1. 读取boot分区
   ├─ 从eMMC/SPI Flash读取boot.img
   └─ boot.img是FIT格式镜像

2. 解析FIT镜像
   ├─ 提取内核镜像(Image)
   ├─ 提取设备树(DTB)
   └─ 提取资源镜像(resource.img)

3. 加载到内存
   ├─ 内核加载到0x40000000
   ├─ DTB加载到0x41000000
   └─ Ramdisk加载到0x42000000(如果有)

4. 设置启动参数
   ├─ bootargs环境变量
   ├─ 内核命令行参数
   └─ 设备树地址

5. 跳转到内核
   └─ 执行bootm命令启动内核

关键环境变量:

# 查看U-Boot环境变量
=> printenv

# 重要的环境变量
bootargs=console=ttyFIQ0,1500000n8 root=/dev/mmcblk0p7 rootwait rw
bootcmd=mmc dev 0; mmc read 0x40000000 0x8000 0x10000; bootm 0x40000000
bootdelay=3
3. 提供交互环境

U-Boot提供了一个命令行界面,用于:

  • 调试硬件 - 读写内存、GPIO、寄存器
  • 测试功能 - 测试存储、网络、USB等
  • 手动启动 - 手动加载和启动内核
  • 固件升级 - 通过网络或USB升级固件

常用命令分类:

类别 命令 说明
信息查看 version 查看U-Boot版本
bdinfo 查看板级信息
printenv 查看环境变量
内存操作 md 显示内存内容
mm 修改内存
mw 写入内存
cp 复制内存
存储操作 mmc list 列出MMC设备
mmc dev 选择MMC设备
mmc read 读取MMC
mmc write 写入MMC
网络操作 ping 测试网络连通性
dhcp 获取IP地址
tftp TFTP下载文件
启动操作 boot 启动系统
bootm 启动内核镜像
reset 重启系统
4. 启动模式选择

U-Boot支持多种启动模式:

┌─────────────────────────────────────────────────────────┐
│              U-Boot启动模式                               │
└─────────────────────────────────────────────────────────┘

1. 正常启动模式 (Normal Boot)
   ├─ 加载boot分区的内核
   ├─ 挂载rootfs分区
   └─ 启动正常系统

2. Recovery模式
   ├─ 加载recovery分区的内核
   ├─ 挂载recovery ramdisk
   └─ 用于系统恢复和升级

3. Fastboot模式
   ├─ 进入USB Fastboot协议
   ├─ 用于快速烧录固件
   └─ 支持分区擦除、写入

4. 网络启动模式 (TFTP Boot)
   ├─ 通过TFTP下载内核
   ├─ 通过NFS挂载根文件系统
   └─ 用于开发调试

5. USB启动模式
   ├─ 从USB存储设备启动
   └─ 用于系统恢复

启动模式切换方法:

# 方法1:通过misc分区控制
# Android/Linux系统写入BCB数据到misc分区
# U-Boot读取misc分区决定启动模式

# 方法2:通过按键组合
# 上电时按住特定按键进入Recovery

# 方法3:通过U-Boot命令
=> setenv bootcmd "run recoveryboot"
=> saveenv
=> reset

1.3 U-Boot在RV1126B平台的特点

RV1126B的U-Boot配置文件
# U-Boot配置文件位置
/home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot/configs/

# 正点原子的配置
alientek_rv1126b_defconfig          # 正点原子标准配置

# Rockchip官方配置
rv1126b_defconfig                   # RV1126B基础配置
rv1126b-emmc-fastboot_defconfig     # eMMC + Fastboot
rv1126b-spi-nor_defconfig           # SPI NOR Flash
rv1126b-spi-nand-fastboot_defconfig # SPI NAND + Fastboot

image-20260302161052414

二、U-Boot移植步骤

2.1 移植前的准备工作

1. 了解硬件差异

在开始移植之前,需要明确硬件与参考板的差异

如何获取硬件信息:

# 1. 查看原理图
# 对比你的原理图和正点原子的原理图

# 2. 查看现有设备树
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot/arch/arm/dts/
cat rv1126b-alientek.dts

# 3. 查看现有配置
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot/configs/
cat alientek_rv1126b_defconfig
2. 准备开发环境
# 确保SDK已经完整编译过一次
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk
./build.sh

# 进入U-Boot目录
cd u-boot

# 查看当前配置
ls -l .config
ls -l defconfig
3. 备份原始文件
# 备份重要文件
cp configs/alientek_rv1126b_defconfig configs/alientek_rv1126b_defconfig.bak
cp arch/arm/dts/rv1126-alientek-dlrv1126b.dts arch/arm/dts/rv1126-alientek-dlrv1126b.dts.bak

2.2 第1步:创建板级配置文件

如果你的硬件与正点原子的板子有差异,建议创建自己的配置文件:

方法1:复制现有配置
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot

# 复制配置文件
cp configs/alientek_rv1126b_defconfig configs/my_rv1126b_defconfig

# 编辑配置文件
vim configs/my_rv1126b_defconfig
方法2:通过menuconfig创建
# 加载基础配置
make alientek_rv1126b_defconfig

# 图形化配置界面
make menuconfig

# 保存配置
make savedefconfig

# 移动到configs目录
mv defconfig configs/my_rv1126b_defconfig

defconfig文件示例:

# configs/my_rv1126b_defconfig

CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ROCKCHIP_RV1126=y
CONFIG_ROCKCHIP_SPL_RESERVE_IRAM=0x0
CONFIG_TARGET_RV1126_RV1109=y
CONFIG_SPL_STACK_R_ADDR=0x600000
CONFIG_DEFAULT_DEVICE_TREE="rv1126-my-board"  # 修改设备树名称
CONFIG_DEBUG_UART=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# ... 更多配置

2.3 第2步:修改设备树(DTS)

设备树(Device Tree)是描述硬件信息的文件,U-Boot和Linux内核都会使用它。

设备树文件位置
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot/arch/arm/dts/

# 查看RV1126相关的设备树
ls -l rv1126*.dts*

# 主要文件
rv1126.dtsi                          # RV1126芯片级设备树(基础)
rv1126-alientek-dlrv1126b.dts        # 正点原子板级设备树
rv1126-alientek-dlrv1126b-*.dtsi     # 正点原子板级设备树片段
创建自己的设备树
# 复制正点原子的设备树
cp rv1126-alientek-dlrv1126b.dts rv1126-my-board.dts

# 编辑设备树
vim rv1126-my-board.dts
设备树基本结构
/dts-v1/;
#include "rv1126.dtsi"
#include "rv1126-my-board-camera.dtsi"  // 摄像头配置
#include "rv1126-my-board-display.dtsi" // 显示配置

/ {
    model = "My RV1126B Board";
    compatible = "my-company,rv1126b", "rockchip,rv1126";

    chosen {
        stdout-path = "serial2:1500000n8";  // 调试串口
    };

    // 板级配置
    // ...
};

// 外设配置
&uart2 {
    status = "okay";
};

&i2c0 {
    status = "okay";
    clock-frequency = <400000>;

    // I2C设备
};

// 更多外设配置...
常见修改项详解
1. GPIO配置
// 修改LED GPIO
&gpio0 {
    status = "okay";
};

/ {
    leds {
        compatible = "gpio-leds";

        led_power {
            label = "power_led";
            gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
            default-state = "on";
        };

        led_status {
            label = "status_led";
            gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
            linux,default-trigger = "heartbeat";
        };
    };

    gpio-keys {
        compatible = "gpio-keys";
        autorepeat;

        power-key {
            label = "Power Key";
            gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
            linux,code = <KEY_POWER>;
            wakeup-source;
        };
    };
};
2. I2C设备配置(陀螺仪)
&i2c2 {
    status = "okay";
    clock-frequency = <400000>;

    icm20948: icm20948@68 {
        compatible = "invensense,icm20948";
        reg = <0x68>;
        interrupt-parent = <&gpio0>;
        interrupts = <RK_PB0 IRQ_TYPE_EDGE_RISING>;

        // 陀螺仪配置
        gyro-range = <250>;  // ±250°/s
        accel-range = <2>;   // ±2g
    };
};
3. SPI设备配置
&spi0 {
    status = "okay";
    max-freq = <48000000>;

    spiflash: spi-flash@0 {
        compatible = "jedec,spi-nor";
        reg = <0>;
        spi-max-frequency = <48000000>;

        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;

            partition@0 {
                label = "bootloader";
                reg = <0x0 0x100000>;
            };

            partition@100000 {
                label = "env";
                reg = <0x100000 0x10000>;
            };
        };
    };
};
4. MIPI屏幕配置
&dsi {
    status = "okay";

    panel@0 {
        compatible = "simple-panel-dsi";
        reg = <0>;
        backlight = <&backlight>;
        power-supply = <&vcc_lcd>;
        reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;

        display-timings {
            native-mode = <&timing0>;

            timing0: timing0 {
                clock-frequency = <65000000>;
                hactive = <720>;
                vactive = <1280>;
                hfront-porch = <20>;
                hsync-len = <10>;
                hback-porch = <20>;
                vfront-porch = <10>;
                vsync-len = <4>;
                vback-porch = <10>;
                hsync-active = <0>;
                vsync-active = <0>;
                de-active = <0>;
                pixelclk-active = <0>;
            };
        };

        port {
            panel_in_dsi: endpoint {
                remote-endpoint = <&dsi_out_panel>;
            };
        };
    };
};

&dsi_in_vop {
    status = "okay";
};

&dsi_out_panel {
    status = "okay";
};

&route_dsi {
    status = "okay";
};
5. USB配置(5G模组)
&usb_host0_ehci {
    status = "okay";
};

&usb_host0_ohci {
    status = "okay";
};

&usb2phy0 {
    status = "okay";

    usb2phy0_host: host-port {
        status = "okay";
    };
};

// 5G模组电源控制
/ {
    vcc_5g: vcc-5g-regulator {
        compatible = "regulator-fixed";
        regulator-name = "vcc_5g";
        gpio = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
        enable-active-high;
        regulator-always-on;
        regulator-boot-on;
    };
};
6. SDIO配置(WiFi模组)
&sdio {
    status = "okay";
    max-frequency = <150000000>;
    bus-width = <4>;
    cap-sd-highspeed;
    cap-sdio-irq;
    keep-power-in-suspend;
    non-removable;
    rockchip,default-sample-phase = <90>;
    sd-uhs-sdr104;

    // WiFi模组
    wifi@1 {
        compatible = "realtek,rtl8733bs";
        reg = <1>;
        interrupt-parent = <&gpio0>;
        interrupts = <RK_PA6 IRQ_TYPE_LEVEL_HIGH>;
    };
};

// WiFi电源控制
/ {
    sdio_pwrseq: sdio-pwrseq {
        compatible = "mmc-pwrseq-simple";
        reset-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
        post-power-on-delay-ms = <200>;
    };
};

&sdio {
    mmc-pwrseq = <&sdio_pwrseq>;
};
7. eMMC配置
&emmc {
    status = "okay";
    bus-width = <8>;
    cap-mmc-highspeed;
    mmc-hs200-1_8v;
    supports-emmc;
    non-removable;
    rockchip,default-sample-phase = <90>;
};
设备树编译

修改设备树后,需要重新编译:

# 方法1:单独编译设备树
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot
make rv1126-my-board.dtb

# 方法2:编译整个U-Boot(会自动编译设备树)
make -j$(nproc)

# 查看编译后的设备树
ls -l arch/arm/dts/rv1126-my-board.dtb
设备树调试技巧
# 1. 反编译设备树查看
dtc -I dtb -O dts -o output.dts arch/arm/dts/rv1126-my-board.dtb

# 2. 查看设备树中的某个节点
fdtget arch/arm/dts/rv1126-my-board.dtb /chosen stdout-path

# 3. 在U-Boot中查看设备树
=> fdt addr ${fdtcontroladdr}
=> fdt print /
=> fdt print /chosen

2.4 第3步:修改板级代码

如果需要添加自定义的硬件初始化代码,需要修改板级文件。

板级代码位置
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot/board/rockchip/evb_rv1126b/

# 主要文件
ls -l
# evb_rv1126b.c  - 板级初始化代码
# Kconfig          - 配置选项
# MAINTAINERS      - 维护者信息
# Makefile         - 编译规则
板级初始化代码示例
// board/rockchip/rv1126_rv1109/rv1126-rv1109.c

#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

// 板级早期初始化(在DDR初始化之前)
int board_early_init_f(void)
{
    // 配置关键GPIO
    // 例如:电源使能、复位信号等

    return 0;
}

// 板级初始化(在DDR初始化之后)
int board_init(void)
{
    printf("Board: My RV1126B Board\n");

    // 初始化5G模组
    init_5g_module();

    // 初始化WiFi模组
    init_wifi_module();

    // 初始化其他硬件
    init_other_hardware();

    return 0;
}

// 5G模组初始化
static int init_5g_module(void)
{
    int ret;

    printf("Initializing 5G module (RM500Q)...\n");

    // 1. 配置5G模组电源GPIO
    ret = gpio_request(GPIO_5G_POWER, "5g_power");
    if (ret) {
        printf("Failed to request 5G power GPIO\n");
        return ret;
    }

    // 2. 使能5G模组电源
    gpio_direction_output(GPIO_5G_POWER, 1);
    mdelay(100);  // 等待电源稳定

    // 3. 配置5G模组复位GPIO
    ret = gpio_request(GPIO_5G_RESET, "5g_reset");
    if (ret) {
        printf("Failed to request 5G reset GPIO\n");
        return ret;
    }

    // 4. 复位5G模组
    gpio_direction_output(GPIO_5G_RESET, 0);
    mdelay(10);
    gpio_direction_output(GPIO_5G_RESET, 1);
    mdelay(100);

    printf("5G module initialized\n");
    return 0;
}

// WiFi模组初始化
static int init_wifi_module(void)
{
    int ret;

    printf("Initializing WiFi module (RTL8733)...\n");

    // 1. 配置WiFi电源GPIO
    ret = gpio_request(GPIO_WIFI_POWER, "wifi_power");
    if (ret) {
        printf("Failed to request WiFi power GPIO\n");
        return ret;
    }

    // 2. 使能WiFi电源
    gpio_direction_output(GPIO_WIFI_POWER, 1);
    mdelay(50);

    // 3. 配置WiFi复位GPIO
    ret = gpio_request(GPIO_WIFI_RESET, "wifi_reset");
    if (ret) {
        printf("Failed to request WiFi reset GPIO\n");
        return ret;
    }

    // 4. 复位WiFi模组
    gpio_direction_output(GPIO_WIFI_RESET, 0);
    mdelay(10);
    gpio_direction_output(GPIO_WIFI_RESET, 1);
    mdelay(100);

    printf("WiFi module initialized\n");
    return 0;
}

// 板级晚期初始化
int board_late_init(void)
{
    // 设置环境变量
    env_set("board_name", "my_rv1126b");
    env_set("board_rev", "v1.0");

    // 检测启动模式
    check_boot_mode();

    return 0;
}

// 检测启动模式
static void check_boot_mode(void)
{
    // 读取按键状态
    int recovery_key = gpio_get_value(GPIO_RECOVERY_KEY);

    if (recovery_key == 0) {
        printf("Recovery key pressed, entering recovery mode\n");
        env_set("bootcmd", "run recoveryboot");
    }
}

// 显示板级信息
int checkboard(void)
{
    printf("Board: My RV1126B Board v1.0\n");
    printf("CPU:   Rockchip RV1126B\n");
    printf("Model: 5G/WiFi Law Enforcement Recorder\n");

    return 0;
}
GPIO定义

在头文件中定义GPIO:

// board/rockchip/rv1126_rv1109/rv1126-rv1109.h

#ifndef __RV1126_RV1109_H
#define __RV1126_RV1109_H

// GPIO定义
#define GPIO_5G_POWER       GPIO0_A3
#define GPIO_5G_RESET       GPIO0_A4
#define GPIO_WIFI_POWER     GPIO0_A5
#define GPIO_WIFI_RESET     GPIO0_A6
#define GPIO_RECOVERY_KEY   GPIO0_B0

// 其他定义
// ...

#endif

2.5 第4步:配置U-Boot功能

使用menuconfig配置U-Boot的功能选项。

启动menuconfig
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot

# 加载配置
make alientek_rv1126b_defconfig

# 启动图形化配置
make menuconfig
常用配置项
1. 设备驱动配置
Device Drivers  --->
    [*] GPIO Support  --->
        [*] Rockchip GPIO driver

    [*] I2C Support  --->
        [*] Rockchip I2C driver

    [*] SPI Support  --->
        [*] Rockchip SPI driver

    [*] MMC Support  --->
        [*] Rockchip SD/MMC controller support
        [*] Rockchip SDHCI controller support

    [*] USB Support  --->
        [*] USB Host Controller Drivers
        [*] EHCI HCD (USB 2.0) support
        [*] OHCI HCD (USB 1.1) support
        [*] USB Gadget Support  --->
            [*] USB Gadget Download support
            [*] USB Fastboot support

    [*] Network device support  --->
        [*] Ethernet driver support
        [*] Realtek PHY support

    [*] Video support  --->
        [*] Enable Rockchip Video Support
        [*] Rockchip MIPI DSI support
2. 命令行配置
Command line interface  --->
    [*] Network commands  --->
        [*] bootp, tftpboot
        [*] dhcp
        [*] ping
        [*] tftp

    [*] Device access commands  --->
        [*] i2c
        [*] gpio
        [*] mmc
        [*] usb

    [*] Memory commands  --->
        [*] md, mm, nm, mw, cp, cmp, base, loop
        [*] memtest

    [*] Filesystem commands  --->
        [*] ext2 command support
        [*] ext4 command support
        [*] fat command support
3. 启动选项配置
Boot options  --->
    (3) delay in seconds before automatically booting
    [*] Enable a default value for bootcmd
    (mmc dev 0; mmc read 0x40000000 0x8000 0x10000; bootm 0x40000000) bootcmd value

    [*] Enable boot arguments
    (console=ttyFIQ0,1500000n8 root=/dev/mmcblk0p7 rootwait rw) Boot arguments

    [*] Support for booting from FIT image
    [*] Enable signature verification of FIT images
4. 环境变量配置
Environment  --->
    [*] Environment in MMC
    (0) Device number for MMC
    (0x1f8000) Offset for environment in MMC
    (0x8000) Size of environment in MMC
保存配置
# 保存配置到defconfig
make savedefconfig

# 移动到configs目录
mv defconfig configs/my_rv1126b_defconfig

# 或者直接保存到.config
# 下次编译时会使用.config

2.6 第5步:编译U-Boot

完成配置后,开始编译U-Boot。

编译方法
# 方法1:使用SDK的build.sh脚本(推荐)
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk
./build.sh uboot

# 方法2:单独编译U-Boot
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/u-boot

# 清理之前的编译
make clean

# 加载配置
make alientek_rv1126b_defconfig
# 或使用自己的配置
# make my_rv1126b_defconfig

# 编译(使用多核加速)
make -j$(nproc)

# 查看编译进度
# 编译时间约5-10分钟
编译产物
# 编译完成后,查看生成的文件
ls -lh uboot.img
ls -lh u-boot.bin
ls -lh u-boot.dtb

# 主要产物说明
uboot.img           # 最终的U-Boot镜像(FIT格式)
                    # 包含:u-boot.bin + trust.img + u-boot.dtb

u-boot.bin          # U-Boot二进制文件
u-boot.dtb          # U-Boot设备树
u-boot              # U-Boot ELF文件(用于调试)
u-boot.map          # 符号表文件
编译错误处理

常见编译错误:

  1. 设备树编译错误
# 错误信息
Error: arch/arm/dts/rv1126-my-board.dts:123: syntax error

# 解决方法
# 检查设备树语法,确保括号、分号正确
vim arch/arm/dts/rv1126-my-board.dts
  1. 缺少头文件
# 错误信息
fatal error: xxx.h: No such file or directory

# 解决方法
# 检查include路径,确保头文件存在
find . -name "xxx.h"
  1. 链接错误
# 错误信息
undefined reference to `xxx'

# 解决方法
# 检查函数定义,确保相关代码已编译
grep -r "xxx" .

2.7 第6步:烧录和测试

编译完成后,将U-Boot烧录到开发板进行测试。

烧录方法
方法1:使用RKDevTool(Windows)
1. 打开RKDevTool工具
2. 开发板进入Maskrom模式或Loader模式
3. 选择"下载镜像"标签
4. 勾选"uboot"分区
5. 选择uboot.img文件
6. 点击"执行"按钮
方法2:使用upgrade_tool(Linux)
# 安装upgrade_tool
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk/tools/linux/Linux_Upgrade_Tool
sudo ./upgrade_tool

# 查看设备
sudo ./upgrade_tool ld

# 烧录U-Boot到uboot分区
sudo ./upgrade_tool di -u /path/to/uboot.img

# 或者烧录完整固件
cd /home/alientek/atk_dlrv1126b_linux6.1_sdk
./build.sh firmware
sudo ./tools/linux/Linux_Upgrade_Tool/upgrade_tool uf rockdev/update.img
方法3:通过U-Boot命令烧录(高级)
# 如果U-Boot已经可以启动,可以通过TFTP更新
=> setenv serverip 192.168.1.100
=> setenv ipaddr 192.168.1.10
=> tftp 0x40000000 uboot.img
=> mmc dev 0
=> mmc write 0x40000000 0x4000 0x2000
=> reset
测试步骤
1. 连接串口
# 连接串口(波特率1500000)
sudo minicom -D /dev/ttyUSB0 -b 1500000

# 或使用screen
sudo screen /dev/ttyUSB0 1500000

# 或使用picocom
sudo picocom -b 1500000 /dev/ttyUSB0
2. 上电启动
# 正常启动日志示例
DDR Version V1.08 20210810
LPDDR3, 528MHz
BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=1024MB

U-Boot 2017.09 (Feb 01 2025 - 14:20:00 +0800)

Model: My RV1126B Board v1.0
DRAM:  1 GiB
Relocation Offset is: 3dee0000
Initializing 5G module (RM500Q)...
5G module initialized
Initializing WiFi module (RTL8733)...
WiFi module initialized
MMC:   dwmmc@ffc50000: 0
Loading Environment from MMC... OK
In:    serial@ff560000
Out:   serial@ff560000
Err:   serial@ff560000
Model: My RV1126B Board v1.0
Net:   No ethernet found.
Hit any key to stop autoboot:  3
=>
3. 测试基本功能
# 测试1:查看版本信息
=> version
U-Boot 2017.09 (Feb 01 2025 - 14:20:00 +0800)

# 测试2:查看板级信息
=> bdinfo
arch_number = 0x00000000
boot_params = 0x40000100
DRAM bank   = 0x00000000
-> start    = 0x40000000
-> size     = 0x40000000

# 测试3:查看环境变量
=> printenv
bootargs=console=ttyFIQ0,1500000n8 root=/dev/mmcblk0p7 rootwait rw
bootcmd=mmc dev 0; mmc read 0x40000000 0x8000 0x10000; bootm 0x40000000
bootdelay=3

# 测试4:测试MMC
=> mmc list
dwmmc@ffc50000: 0

=> mmc dev 0
switch to partitions #0, OK
mmc0 is current device

=> mmc info
Device: dwmmc@ffc50000
Manufacturer ID: 15
OEM: 100
Name: 8GTF4
Bus Speed: 52000000
Mode : MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 7.3 GiB

# 测试5:测试GPIO
=> gpio status
Bank gpio0:
gpio0_0: input: 0 [ ]
gpio0_1: input: 0 [ ]
gpio0_2: input: 0 [ ]
gpio0_3: output: 1 [x] 5g_power

# 测试6:读取内存
=> md.l 0x40000000 0x10
40000000: 00000000 00000000 00000000 00000000    ................
40000010: 00000000 00000000 00000000 00000000    ................
40000020: 00000000 00000000 00000000 00000000    ................
40000030: 00000000 00000000 00000000 00000000    ................

# 测试7:手动启动内核
=> mmc dev 0
=> mmc read 0x40000000 0x8000 0x10000
=> bootm 0x40000000
4. 测试启动模式
# 测试正常启动
=> boot

# 测试Recovery模式
=> setenv bootcmd "run recoveryboot"
=> saveenv
=> reset

# 测试Fastboot模式
=> fastboot usb 0

2.8 第7步:调试和优化

如果启动有问题,需要进行调试。

常见问题排查
问题1:U-Boot无法启动

现象: 串口无输出或输出乱码

排查步骤:

# 1. 检查串口连接
# - 确认串口线连接正确
# - 确认波特率设置为1500000

# 2. 检查U-Boot镜像
# - 确认uboot.img烧录成功
# - 确认烧录到正确的分区

# 3. 检查DDR配置
# - DDR参数是否正确
# - DDR初始化是否成功
问题2:设备树加载失败

现象: 提示"Failed to load device tree"

排查步骤:

# 1. 检查设备树编译
cd u-boot
make rv1126-my-board.dtb

# 2. 检查设备树语法
dtc -I dtb -O dts -o output.dts arch/arm/dts/rv1126-my-board.dtb

# 3. 在U-Boot中查看设备树
=> fdt addr ${fdtcontroladdr}
=> fdt print /
问题3:外设无法工作

现象: GPIO、I2C、SPI等外设不工作

排查步骤:

# 1. 检查设备树配置
# - 确认外设节点status = "okay"
# - 确认GPIO配置正确

# 2. 检查驱动是否启用
# - 在menuconfig中确认驱动已选中

# 3. 添加调试打印
# 在驱动代码中添加printf调试
问题4:内核无法启动

现象: U-Boot正常,但无法启动内核

排查步骤:

# 1. 检查boot分区
=> mmc dev 0
=> mmc read 0x40000000 0x8000 0x10000
=> iminfo 0x40000000

# 2. 检查bootargs
=> printenv bootargs
# 确认root分区、console等参数正确

# 3. 手动启动内核
=> bootm 0x40000000
# 查看启动日志
性能优化
1. 减少启动延迟
# 修改bootdelay
=> setenv bootdelay 1
=> saveenv

# 或在defconfig中修改
CONFIG_BOOTDELAY=1
2. 并行初始化
// 在board_init()中使用并行初始化
int board_init(void)
{
    // 启动初始化线程
    start_init_thread(init_5g_module);
    start_init_thread(init_wifi_module);

    // 等待初始化完成
    wait_init_complete();

    return 0;
}
3. 禁用不需要的功能
# 在menuconfig中禁用不需要的命令和驱动
# 减小U-Boot体积,加快启动速度

三、U-Boot调试方法

3.1 串口调试(最常用)

串口是U-Boot调试的主要方法,几乎所有问题都可以通过串口日志定位。

连接串口
# 方法1:使用minicom
sudo minicom -D /dev/ttyUSB0 -b 1500000

# minicom配置
# Ctrl+A -> Z -> O -> Serial port setup
# A - Serial Device      : /dev/ttyUSB0
# E - Bps/Par/Bits       : 1500000 8N1
# F - Hardware Flow Control : No
# G - Software Flow Control : No

# 方法2:使用screen
sudo screen /dev/ttyUSB0 1500000

# 方法3:使用picocom
sudo picocom -b 1500000 /dev/ttyUSB0

# 方法4:使用putty(Windows)
# 配置串口参数:
# Speed: 1500000
# Data bits: 8
# Stop bits: 1
# Parity: None
# Flow control: None
U-Boot命令详解
信息查看命令
# 查看U-Boot版本
=> version
U-Boot 2017.09 (Feb 01 2025 - 14:20:00 +0800)
arm-linux-gnueabihf-gcc (Linaro GCC 7.3-2018.05) 7.3.1 20180425
GNU ld (Linaro_Binutils-2018.05) 2.28.2.20170706

# 查看板级信息
=> bdinfo
arch_number = 0x00000000
boot_params = 0x40000100
DRAM bank   = 0x00000000
-> start    = 0x40000000
-> size     = 0x40000000
baudrate    = 1500000 bps
TLB addr    = 0x7FFF0000
relocaddr   = 0x7DF20000
reloc off   = 0x3DF20000
irq_sp      = 0x7CEFF6E0
sp start    = 0x7CEFF6D0

# 查看环境变量
=> printenv
bootargs=console=ttyFIQ0,1500000n8 root=/dev/mmcblk0p7 rootwait rw
bootcmd=mmc dev 0; mmc read 0x40000000 0x8000 0x10000; bootm 0x40000000
bootdelay=3
baudrate=1500000
ethaddr=00:11:22:33:44:55

# 查看单个环境变量
=> printenv bootargs
bootargs=console=ttyFIQ0,1500000n8 root=/dev/mmcblk0p7 rootwait rw
内存操作命令
# 显示内存内容(字节)
=> md.b 0x40000000 0x100

# 显示内存内容(半字)
=> md.w 0x40000000 0x80

# 显示内存内容(字)
=> md.l 0x40000000 0x40
40000000: 00000000 00000000 00000000 00000000    ................
40000010: 00000000 00000000 00000000 00000000    ................

# 修改内存(交互式)
=> mm.l 0x40000000
40000000: 00000000 ? 12345678
40000004: 00000000 ? q

# 写入内存
=> mw.l 0x40000000 0x12345678 0x10

# 复制内存
=> cp.l 0x40000000 0x41000000 0x1000

# 比较内存
=> cmp.l 0x40000000 0x41000000 0x1000

# 内存测试
=> mtest 0x40000000 0x50000000
Pattern 00000000  Writing...  Reading...
MMC/SD卡操作命令
# 列出MMC设备
=> mmc list
dwmmc@ffc50000: 0

# 选择MMC设备
=> mmc dev 0
switch to partitions #0, OK
mmc0 is current device

# 查看MMC信息
=> mmc info
Device: dwmmc@ffc50000
Manufacturer ID: 15
OEM: 100
Name: 8GTF4
Bus Speed: 52000000
Mode : MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 7.3 GiB

# 查看MMC分区
=> mmc part

Partition Map for MMC device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00004000      0x00005fff      "uboot"
        attrs:  0x0000000000000000
        type:   ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
        guid:   b3e3e3e3-e3e3-e3e3-e3e3-e3e3e3e3e3e3

# 读取MMC
=> mmc read 0x40000000 0x8000 0x10000
MMC read: dev # 0, block # 32768, count 65536 ... 65536 blocks read: OK

# 写入MMC
=> mmc write 0x40000000 0x8000 0x10000
MMC write: dev # 0, block # 32768, count 65536 ... 65536 blocks written: OK

# 擦除MMC
=> mmc erase 0x8000 0x10000
MMC erase: dev # 0, block # 32768, count 65536 ... 65536 blocks erased: OK
GPIO操作命令
# 查看GPIO状态
=> gpio status
Bank gpio0:
gpio0_0: input: 0 [ ]
gpio0_1: input: 0 [ ]
gpio0_2: input: 0 [ ]
gpio0_3: output: 1 [x] 5g_power
gpio0_4: output: 1 [x] 5g_reset

# 设置GPIO为输出
=> gpio set 0
=> gpio clear 0

# 读取GPIO输入
=> gpio input 0
gpio: pin 0 (gpio 0) value is 1

# 切换GPIO
=> gpio toggle 0
I2C操作命令
# 扫描I2C总线
=> i2c dev 0
Setting bus to 0
=> i2c probe
Valid chip addresses: 68

# 读取I2C设备
=> i2c md 0x68 0x75 1
0075: 71

# 写入I2C设备
=> i2c mw 0x68 0x6b 0x00 1

# 连续读取
=> i2c md 0x68 0x00 0x10
0000: 71 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    q...............
网络操作命令
# 设置IP地址
=> setenv ipaddr 192.168.1.10
=> setenv serverip 192.168.1.100
=> setenv netmask 255.255.255.0
=> setenv gatewayip 192.168.1.1

# 测试网络连通性
=> ping 192.168.1.100
Using ethernet@ffc40000 device
host 192.168.1.100 is alive

# DHCP获取IP
=> dhcp
BOOTP broadcast 1
DHCP client bound to address 192.168.1.10 (5 ms)

# TFTP下载文件
=> tftp 0x40000000 uImage
Using ethernet@ffc40000 device
TFTP from server 192.168.1.100; our IP address is 192.168.1.10
Filename 'uImage'.
Load address: 0x40000000
Loading: #################################################################
         #################################################################
         done
Bytes transferred = 4567890 (45b2d2 hex)

# TFTP上传文件
=> tftpput 0x40000000 0x100000 uboot.img
启动相关命令
# 启动系统
=> boot

# 从内存启动内核
=> bootm 0x40000000

# 从FIT镜像启动
=> bootm 0x40000000#config@1

# 重启系统
=> reset

# 进入Fastboot模式
=> fastboot usb 0

3.2 添加调试打印

在U-Boot源码中添加调试信息是最直接的调试方法。

基本调试打印
// 在任何C文件中添加
#include <common.h>

void my_debug_function(void)
{
    // 普通打印(总是输出)
    printf("Debug: Entering my_debug_function\n");
    printf("GPIO0 value: 0x%08x\n", readl(GPIO0_BASE));

    // 详细调试打印(只在定义DEBUG时输出)
    debug("This only prints if DEBUG is defined\n");
    debug("Variable x = %d\n", x);

    // 错误打印
    pr_err("Error occurred: %d\n", error_code);

    // 警告打印
    pr_warn("Warning: something wrong\n");

    // 信息打印
    pr_info("Info: initialization complete\n");
}
启用调试输出
// 方法1:在文件开头定义DEBUG
#define DEBUG
#include <common.h>

// 方法2:在Makefile中添加
CFLAGS_xxx.o := -DDEBUG

// 方法3:在defconfig中启用
CONFIG_LOG=y
CONFIG_LOGLEVEL=7
调试宏定义
// 常用调试宏
#define DBG(fmt, args...) \
    printf("[%s:%d] " fmt, __func__, __LINE__, ##args)

#define DBG_HERE() \
    printf("[%s:%d] Here!\n", __func__, __LINE__)

#define DBG_VAR(var) \
    printf("[%s:%d] %s = 0x%x\n", __func__, __LINE__, #var, var)

// 使用示例
void test_function(void)
{
    int value = 0x12345678;

    DBG_HERE();                    // [test_function:123] Here!
    DBG("Starting test\n");        // [test_function:124] Starting test
    DBG_VAR(value);                // [test_function:125] value = 0x12345678
}

3.3 使用JTAG调试(高级)

JTAG是硬件级调试方法,可以单步调试、设置断点、查看寄存器等。

JTAG调试环境搭建
# 1. 安装OpenOCD
sudo apt-get install openocd

# 2. 安装GDB
sudo apt-get install gdb-multiarch

# 3. 准备JTAG配置文件
# 创建 rv1126.cfg
cat > rv1126.cfg << EOF
# RV1126 JTAG配置
adapter driver jlink
adapter speed 1000

transport select jtag
jtag newtap rv1126 cpu -irlen 4 -expected-id 0x0ba00477

target create rv1126.cpu cortex_a -chain-position rv1126.cpu
rv1126.cpu configure -work-area-phys 0x40000000 -work-area-size 0x10000

init
halt
EOF
启动JTAG调试
# 终端1:启动OpenOCD
openocd -f interface/jlink.cfg -f rv1126.cfg

# 终端2:启动GDB
arm-linux-gnueabihf-gdb u-boot

# GDB命令
(gdb) target remote localhost:3333
(gdb) load                          # 加载U-Boot
(gdb) break board_init              # 设置断点
(gdb) continue                      # 继续执行
(gdb) step                          # 单步执行
(gdb) next                          # 下一步
(gdb) print variable                # 打印变量
(gdb) info registers                # 查看寄存器
(gdb) backtrace                     # 查看调用栈

3.4 日志分析

正常启动日志分析
DDR Version V1.08 20210810                    # DDR初始化
LPDDR3, 528MHz                                # DDR类型和频率
BW=32 Col=10 Bk=8 CS0 Row=15 CS1 Row=15 CS=2 Die BW=16 Size=1024MB

U-Boot 2017.09 (Feb 01 2025 - 14:20:00 +0800) # U-Boot版本和编译时间

Model: My RV1126B Board v1.0                  # 板级型号
DRAM:  1 GiB                                  # 内存大小
Relocation Offset is: 3dee0000                # 重定位偏移

Initializing 5G module (RM500Q)...            # 5G模组初始化
5G module initialized
Initializing WiFi module (RTL8733)...         # WiFi模组初始化
WiFi module initialized

MMC:   dwmmc@ffc50000: 0                      # MMC设备
Loading Environment from MMC... OK            # 加载环境变量

In:    serial@ff560000                        # 输入设备
Out:   serial@ff560000                        # 输出设备
Err:   serial@ff560000                        # 错误输出设备

Model: My RV1126B Board v1.0
Net:   No ethernet found.                     # 网络设备
Hit any key to stop autoboot:  3              # 启动倒计时
异常日志分析

问题1:DDR初始化失败

DDR Version V1.08 20210810
LPDDR3, 528MHz
DDR init failed!                              # DDR初始化失败

原因: DDR参数配置错误
解决: 检查DDR配置文件

问题2:U-Boot重定位失败

U-Boot 2017.09 (Feb 01 2025 - 14:20:00 +0800)
Relocation Offset is: 3dee0000
### ERROR ### Please RESET the board ###      # 重定位失败

原因: 内存地址冲突或内存损坏
解决: 检查内存映射配置

问题3:环境变量加载失败

Loading Environment from MMC... *** Warning - bad CRC, using default environment

原因: 环境变量分区损坏或未初始化
解决: 重新保存环境变量 saveenv


四、针对执法记录仪项目的定制

4.1 5G模组初始化

U-Boot初始化代码
// board/rockchip/rv1126_rv1109/rv1126-rv1109.c

#define GPIO_5G_POWER    GPIO0_A3
#define GPIO_5G_RESET    GPIO0_A4

static int init_5g_module(void)
{
    int ret;

    printf("Initializing 5G module (RM500Q)...\n");

    // 1. 配置电源GPIO
    ret = gpio_request(GPIO_5G_POWER, "5g_power");
    if (ret) {
        pr_err("Failed to request 5G power GPIO: %d\n", ret);
        return ret;
    }

    // 2. 使能5G模组电源
    gpio_direction_output(GPIO_5G_POWER, 1);
    printf("5G power enabled\n");
    mdelay(100);  // 等待电源稳定

    // 3. 配置复位GPIO
    ret = gpio_request(GPIO_5G_RESET, "5g_reset");
    if (ret) {
        pr_err("Failed to request 5G reset GPIO: %d\n", ret);
        return ret;
    }

    // 4. 复位5G模组
    gpio_direction_output(GPIO_5G_RESET, 0);
    mdelay(10);
    gpio_direction_output(GPIO_5G_RESET, 1);
    printf("5G module reset complete\n");
    mdelay(100);

    // 5. 等待5G模组就绪
    printf("Waiting for 5G module ready...\n");
    mdelay(2000);  // RM500Q启动需要约2秒

    printf("5G module initialized successfully\n");
    return 0;
}
设备树配置
// arch/arm/dts/rv1126-my-board.dts

/ {
    // 5G模组电源
    vcc_5g: vcc-5g-regulator {
        compatible = "regulator-fixed";
        regulator-name = "vcc_5g";
        gpio = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
        enable-active-high;
        regulator-boot-on;
    };
};

// USB配置(5G模组使用USB接口)
&usb_host0_ehci {
    status = "okay";
};

&usb_host0_ohci {
    status = "okay";
};

&usb2phy0 {
    status = "okay";

    usb2phy0_host: host-port {
        status = "okay";
    };
};

4.2 WiFi模组初始化

U-Boot初始化代码
#define GPIO_WIFI_POWER    GPIO0_A5
#define GPIO_WIFI_RESET    GPIO0_A6

static int init_wifi_module(void)
{
    int ret;

    printf("Initializing WiFi module (RTL8733)...\n");

    // 1. 配置WiFi电源GPIO
    ret = gpio_request(GPIO_WIFI_POWER, "wifi_power");
    if (ret) {
        pr_err("Failed to request WiFi power GPIO: %d\n", ret);
        return ret;
    }

    // 2. 使能WiFi电源
    gpio_direction_output(GPIO_WIFI_POWER, 1);
    printf("WiFi power enabled\n");
    mdelay(50);

    // 3. 配置WiFi复位GPIO
    ret = gpio_request(GPIO_WIFI_RESET, "wifi_reset");
    if (ret) {
        pr_err("Failed to request WiFi reset GPIO: %d\n", ret);
        return ret;
    }

    // 4. 复位WiFi模组
    gpio_direction_output(GPIO_WIFI_RESET, 0);
    mdelay(10);
    gpio_direction_output(GPIO_WIFI_RESET, 1);
    printf("WiFi module reset complete\n");
    mdelay(100);

    printf("WiFi module initialized successfully\n");
    return 0;
}
设备树配置
/ {
    // WiFi电源序列
    sdio_pwrseq: sdio-pwrseq {
        compatible = "mmc-pwrseq-simple";
        reset-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
        post-power-on-delay-ms = <200>;
    };
};

// SDIO配置
&sdio {
    status = "okay";
    max-frequency = <150000000>;
    bus-width = <4>;
    cap-sd-highspeed;
    cap-sdio-irq;
    keep-power-in-suspend;
    non-removable;
    mmc-pwrseq = <&sdio_pwrseq>;
    rockchip,default-sample-phase = <90>;
    sd-uhs-sdr104;

    // WiFi设备
    wifi@1 {
        compatible = "realtek,rtl8733bs";
        reg = <1>;
    };
};

4.3 陀螺仪初始化

虽然U-Boot通常不需要初始化陀螺仪,但可以添加基本的检测功能。

#define ICM20948_I2C_ADDR    0x68
#define ICM20948_WHO_AM_I    0x75
#define ICM20948_CHIP_ID     0xEA

static int check_gyro_sensor(void)
{
    int ret;
    u8 chip_id;

    printf("Checking gyroscope sensor (ICM20948)...\n");

    // 读取WHO_AM_I寄存器
    ret = i2c_read(ICM20948_I2C_ADDR, ICM20948_WHO_AM_I, 1, &chip_id, 1);
    if (ret) {
        pr_err("Failed to read ICM20948 chip ID: %d\n", ret);
        return ret;
    }

    if (chip_id == ICM20948_CHIP_ID) {
        printf("ICM20948 detected, chip ID: 0x%02x\n", chip_id);
        return 0;
    } else {
        pr_err("ICM20948 not found, chip ID: 0x%02x (expected 0x%02x)\n",
               chip_id, ICM20948_CHIP_ID);
        return -ENODEV;
    }
}

4.4 MIPI屏幕配置

根据你的系统概述,支持多种分辨率的MIPI屏幕。

// arch/arm/dts/rv1126-my-board-display.dtsi

&dsi {
    status = "okay";

    panel@0 {
        compatible = "simple-panel-dsi";
        reg = <0>;
        backlight = <&backlight>;
        power-supply = <&vcc_lcd>;
        reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;

        // 720x1280分辨率配置
        display-timings {
            native-mode = <&timing_720x1280>;

            timing_720x1280: timing-720x1280 {
                clock-frequency = <65000000>;
                hactive = <720>;
                vactive = <1280>;
                hfront-porch = <20>;
                hsync-len = <10>;
                hback-porch = <20>;
                vfront-porch = <10>;
                vsync-len = <4>;
                vback-porch = <10>;
                hsync-active = <0>;
                vsync-active = <0>;
                de-active = <0>;
                pixelclk-active = <0>;
            };

            // 可以添加其他分辨率配置
            timing_1080x1920: timing-1080x1920 {
                clock-frequency = <148500000>;
                hactive = <1080>;
                vactive = <1920>;
                // ...
            };
        };

        port {
            panel_in_dsi: endpoint {
                remote-endpoint = <&dsi_out_panel>;
            };
        };
    };
};

// 背光控制
&pwm0 {
    status = "okay";
};

/ {
    backlight: backlight {
        compatible = "pwm-backlight";
        pwms = <&pwm0 0 25000 0>;
        brightness-levels = <
            0  1  2  3  4  5  6  7
            8  9 10 11 12 13 14 15
           16 17 18 19 20 21 22 23
           24 25 26 27 28 29 30 31
           32 33 34 35 36 37 38 39
           40 41 42 43 44 45 46 47
           48 49 50 51 52 53 54 55
           56 57 58 59 60 61 62 63
           64 65 66 67 68 69 70 71
           72 73 74 75 76 77 78 79
           80 81 82 83 84 85 86 87
           88 89 90 91 92 93 94 95
           96 97 98 99 100
        >;
        default-brightness-level = <80>;
    };
};

五、常见问题与解决方案

5.1 编译问题

问题1:找不到交叉编译工具链

错误信息:

arm-linux-gnueabihf-gcc: command not found

解决方案:

# 检查工具链路径
echo $PATH

# 添加工具链到PATH
export PATH=/home/alientek/atk_dlrv1126b_linux6.1_sdk/prebuilts/gcc/linux-x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin:$PATH

# 或在SDK根目录执行
source envsetup.sh
问题2:设备树编译错误

错误信息:

Error: arch/arm/dts/rv1126-my-board.dts:123: syntax error

解决方案:

# 检查设备树语法
# 1. 确保所有括号匹配
# 2. 确保每行以分号结尾
# 3. 确保节点名称正确

# 使用dtc工具检查
dtc -I dts -O dtb arch/arm/dts/rv1126-my-board.dts

5.2 启动问题

问题1:串口无输出

可能原因:

  1. 串口线连接错误
  2. 波特率设置错误
  3. U-Boot未正确烧录

解决方案:

# 1. 检查串口连接
# TX -> RX, RX -> TX, GND -> GND

# 2. 确认波特率
# RV1126B默认波特率: 1500000

# 3. 重新烧录U-Boot
sudo upgrade_tool di -u uboot.img
问题2:卡在DDR初始化

现象:

DDR Version V1.08 20210810
LPDDR3, 528MHz

然后无响应

解决方案:

# 检查DDR配置文件
# rkbin/bin/rv11/rv1126_ddr_*.bin

# 确认DDR型号和参数
# 可能需要联系硬件工程师确认DDR配置

5.3 功能问题

问题1:MMC设备无法识别

现象:

MMC:   dwmmc@ffc50000: 0
Card did not respond to voltage select!

解决方案:

// 检查设备树配置
&emmc {
    status = "okay";
    bus-width = <8>;
    cap-mmc-highspeed;
    mmc-hs200-1_8v;
    supports-emmc;
    non-removable;

    // 添加电源配置
    vmmc-supply = <&vcc_3v3>;
    vqmmc-supply = <&vcc_1v8>;
};
问题2:网络无法使用

现象:

Net:   No ethernet found.

解决方案:

# 1. 检查网络驱动是否启用
make menuconfig
# Device Drivers -> Network device support

# 2. 检查设备树配置
# 确认PHY地址、时钟配置等

六、总结

6.1 U-Boot移植核心要点

  1. 了解硬件差异 - 对比原理图,明确需要修改的部分
  2. 修改设备树 - 描述硬件信息,是移植的核心
  3. 配置功能选项 - 通过menuconfig启用所需驱动
  4. 添加板级代码 - 实现自定义硬件初始化
  5. 充分测试 - 通过串口调试验证各项功能

6.2 调试技巧总结

  • 串口调试 - 最基本、最常用的调试方法
  • 添加打印 - 在关键位置添加调试信息
  • U-Boot命令 - 使用内置命令测试硬件
  • JTAG调试 - 硬件级调试,适合复杂问题

附录

A. 参考资料

B. 常用命令速查

# 编译相关
make alientek_rv1126b_defconfig    # 加载配置
make menuconfig                     # 图形化配置
make -j$(nproc)                     # 编译
make clean                          # 清理

# 烧录相关
sudo upgrade_tool di -u uboot.img   # 烧录U-Boot
sudo upgrade_tool uf update.img     # 烧录完整固件

# 串口连接
sudo minicom -D /dev/ttyUSB0 -b 1500000
sudo screen /dev/ttyUSB0 1500000

# U-Boot命令
printenv                            # 查看环境变量
setenv                              # 设置环境变量
saveenv                             # 保存环境变量
mmc list                            # 列出MMC设备
gpio status                         # 查看GPIO状态
boot                                # 启动系统
reset                               # 重启
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐