荔枝派Zero全志V3s SPI Flash开发实战:从零构建嵌入式Linux系统
荔枝派Zero作为一款基于全志V3s处理器的超小型开发板,凭借其出色的性价比和丰富的外设接口,在物联网和嵌入式领域广受欢迎。本文将带您完成一个完整的开发流程:在16MB NOR Flash上构建可启动的嵌入式Linux系统。不同于常见的SD卡启动方案,SPI Flash启动具有体积小、功耗低、稳定性高的特点,特别适合量产产品。
1. 开发环境搭建与工具链配置
在开始之前,我们需要准备一个稳定的开发环境。推荐使用Ubuntu 20.04 LTS作为开发主机系统,这个版本对各种开发工具的支持最为完善。
首先安装基础依赖包:
sudo apt update sudo apt install -y build-essential git bison flex libssl-dev libncurses5-dev全志V3s采用ARM Cortex-A7架构,需要配置交叉编译工具链。我们选择Linaro提供的6.3.1版本,这个版本经过社区验证与V3s兼容性良好:
wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz tar xvf gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz sudo mv gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf /opt/ echo 'export PATH=$PATH:/opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc source ~/.bashrc验证工具链是否安装成功:
arm-linux-gnueabihf-gcc -v接下来需要安装SPI Flash相关的工具:
sudo apt install -y mtd-utils device-tree-compiler对于全志系列芯片,我们还需要专用的烧录工具sunxi-tools:
git clone -b spi-rebase https://github.com/Icenowy/sunxi-tools.git cd sunxi-tools make && sudo make install2. U-Boot移植与SPI Flash支持配置
U-Boot是嵌入式系统的引导加载程序,我们需要对其进行定制以支持SPI Flash启动。荔枝派社区维护了一个包含SPI驱动的特殊分支:
git clone -b v3s-spi-experimental https://github.com/Lichee-Pi/u-boot.git cd u-boot配置U-Boot支持XT25F128B Flash芯片:
make ARCH=arm menuconfig在配置界面中,需要确保以下选项被正确设置:
- Device Drivers → SPI Flash Support → Macronix SPI flash support
- 如果Flash容量大于16MB,需要启用CONFIG_SPI_FLASH_BAR
关键配置对比表:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
| CONFIG_SPI_FLASH_MACRONIX | y | 芯天下Flash兼容此驱动 |
| CONFIG_SPI_FLASH_BAR | y | 大容量Flash必须启用 |
| CONFIG_SPI_FLASH_USE_4K_SECTORS | n | XT25F128B不支持4K擦除 |
接下来需要配置默认环境变量,编辑include/configs/sun8i.h文件,在#include <configs/sunxi-common.h>之前添加:
#define CONFIG_BOOTCOMMAND "sf probe 0; " \ "sf read 0x41800000 0x100000 0x10000; " \ "sf read 0x41000000 0x110000 0x400000; " \ "bootz 0x41000000 - 0x41800000" #define CONFIG_BOOTARGS "console=ttyS0,115200 earlyprintk panic=5 rootwait " \ "mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2"编译U-Boot:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero_defconfig time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 2>&1 | tee build.log编译完成后会生成u-boot-sunxi-with-spl.bin文件,这是后续烧录的关键文件。
3. Linux内核配置与设备树修改
Linux内核需要针对SPI Flash进行特殊配置。我们使用荔枝派社区维护的4.13.y分支:
git clone https://github.com/Lichee-Pi/linux.git -b zero-4.13.y cd linux内核配置要点:
make ARCH=arm menuconfig确保以下选项被启用:
- Device Drivers → Memory Technology Device (MTD) support → Command line partition table parsing
- Device Drivers → Memory Technology Device (MTD) support → SPI-NOR device support
- File systems → Miscellaneous filesystems → Journalling Flash File System v2 (JFFS2) support
修改设备树文件arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts,添加SPI Flash节点:
&spi0 { status = "okay"; xt25f128b: xt25f128b@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; #address-cells = <1>; #size-cells = <1>; }; };编译内核和设备树:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc) make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs编译完成后,内核镜像位于arch/arm/boot/zImage,设备树文件位于arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dtb。
4. 根文件系统制作与镜像打包
SPI Flash通常使用JFFS2文件系统,这是专门为NOR Flash设计的日志型文件系统。我们以Buildroot生成的根文件系统为例:
tar xzvf rootfs-brmin.tar.gz mkfs.jffs2 -s 0x100 -e 0x10000 -p 0xAF0000 -d rootfs-brmin/ -o jffs2.img参数说明:
-s 0x100:页大小256字节-e 0x10000:擦除块大小64KB-p 0xAF0000:文件系统分区大小(16MB-1MB-64KB-4MB)
接下来将所有组件打包成一个完整的Flash镜像:
#!/bin/sh dd if=/dev/zero of=flashimg.bin bs=1M count=16 dd if=u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc dd if=sun8i-v3s-licheepi-zero.dtb of=flashimg.bin bs=1K seek=1024 conv=notrunc dd if=zImage of=flashimg.bin bs=1K seek=1088 conv=notrunc dd if=jffs2.img of=flashimg.bin bs=1K seek=5184 conv=notrunc分区布局表:
| 分区 | 起始地址 | 大小 | 内容 |
|---|---|---|---|
| uboot | 0x000000 | 1MB | SPL + U-Boot |
| dtb | 0x100000 | 64KB | 设备树 |
| kernel | 0x110000 | 4MB | Linux内核 |
| rootfs | 0x510000 | 剩余空间 | JFFS2根文件系统 |
5. 烧录与启动测试
全志V3s芯片有一个特殊的USB下载模式称为FEL模式,进入方法有三种:
- 不插入SD卡且SPI Flash为空
- 使用SD卡中的fel-sdboot.sunxi工具
- 上电时将SPI_MISO引脚拉低
进入FEL模式后,通过USB连接电脑,使用sunxi-fel工具烧录:
sudo sunxi-fel version sudo sunxi-fel spiflash-info sudo sunxi-fel -p spiflash-write 0 flashimg.bin烧录完成后断开USB连接,重新上电即可从SPI Flash启动。通过串口终端可以看到启动日志,正常情况应该能进入Linux系统。
6. 常见问题与调试技巧
在实际开发中,可能会遇到以下典型问题:
问题1:U-Boot无法识别Flash
- 检查
make menuconfig中的SPI Flash驱动配置 - 确认设备树中的SPI节点配置正确
- 测量Flash芯片的供电电压(应为3.3V)
问题2:内核挂载根文件系统失败
- 检查内核配置中的JFFS2支持是否启用
- 确认
mtdparts参数与实际分区一致 - 使用
mtd_debug工具检查Flash读写是否正常
问题3:系统运行不稳定
- 降低SPI时钟频率(修改设备树中的spi-max-frequency)
- 检查电源供电是否充足
- 在U-Boot中使用
sunxi_flash dump命令验证数据完整性
调试时可以充分利用U-Boot的命令行工具:
# 查看Flash信息 sf probe 0 sf info # 读写测试 sf read 0x43000000 0x100000 0x1000 md 0x43000000 # 擦除测试 sf erase 0x100000 0x1000通过以上步骤,我们完成了从零开始在荔枝派Zero的SPI Flash上构建完整Linux系统的全过程。这种方案特别适合需要小体积、低功耗的嵌入式应用场景。