前言:

我的开发环境是虚拟机下的ubuntu16.04,以下的工作是在我安装完需要的各种库的前提下进行的,但是我忘了需要在哪一步装哪个库,要不然我也会贴出来的,不过这些问题通过百度都可以解决的,不是大问题。

个人觉得官方的荔枝派资料全,但是不是很详细,不怎么适合入门的,有的地方让人摸不着头脑,因此,我大致整理了下我的SPI nor启动烧录过程,供参考。

若有不能运行或报错的地方,望讨论指正。

官方资料:https://licheezero.readthedocs.io/zh/latest/index.html,http://zero.lichee.pro/

参考资料:https://blog.csdn.net/qq_40860568/article/details/100519832

一.uboot下载及编译:

1.安装交叉编译器

获取交叉编译工具:

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
sudo tar -xvf gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz -C /opt

将交叉编译器加入到系统的环境变量中,编辑文件bashrc,将export PATH=/opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin:$PATH添加到文件末尾:

nano ~/.bashrc # 用自己喜欢的编辑器编辑

保存退出,执行下面命令更新环境变量:

source ~/.bashrc

测试交叉编译环境是否安装成功:

arm-linux-gnueabihf-gcc -v

上述用来查看 arm-linux-gcc 的版本,输出信息如下说明交叉编译环境安装成功:

2.uboot下载

下载包含SPI驱动的uboot:

git clone -b v3s-spi-experimental https://github.com/Lichee-Pi/u-boot.git

3.配置FLASH支持的型号

执行:

cd u-boot/

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero_800x480LCD_defconfig
#or make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero480x272LCD_defconfig
#or make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero_defconfig
make ARCH=arm menuconfig

配置uboot支持flash:

Device Drivers —>

SPI Flash Support —>

[*] Legacy SPI Flash Interface support

[*] SPI flash Bank/Extended address register support     (16M以上的flash需要开启这个选项)

[*] Macronix SPI flash support    (选择spi flash对应的厂商,我用的是MX25L25645GM2I-10G这个型号)

[*] Support for SPI Flash on Allwinner SoCs in SPL

如图:

4.添加环境变量

修改u-boot/include/configs/sun8i.h文件,添加以下内容,注意添加的位置在“#include <configs/sunxi-common.h>”的前边。

vi include/configs/sun8i.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"
  • 环境命令解析:
    sf probe 0; //初始化Flash设备(CS拉低)
    sf read 0x41800000 0x100000 0x10000; //从flash0x100000(1MB)位置读取dtb放到内存0x41800000偏移处。 //如果是bsp的bin,则是0x41d00000
    sf read 0x41000000 0x110000 0x400000; //从flash0x110000(1MB+64KB)位置读取dtb放到内存0x41000000偏移处。
    bootz 0x41000000 (内核地址)- 0x41800000(dtb地址) 启动内核
  • 启动参数解析:
    console=ttyS0,115200 earlyprintk panic=5 rootwait //在串口0上输出信息
    mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2 //spi32766.0是设备名,后面是分区大小,名字,读写属性。
    root=31:03表示根文件系统是mtd3;jffs2格式

5.编译uboot

切到u-boot目录下执行:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

会在目录下生成 u-boot-sunxi-with-spl.bin。

二.linux下载及编译

1.linux下载

执行:

git clone -b zero-4.13.y https://github.com/Lichee-Pi/linux.git

2.linux配置

执行:

cd linux
make ARCH=arm licheepi_zero_defconfig
make ARCH=arm menuconfig

进入配置界面,首先添加SPI-NOR的支持:

Device Drivers —>

<*> Memory Technology Device (MTD) support —>

<*> Command line partition table parsing     (该选项用来解析uboot传递过来的flash分区信息)

<*> SPI-NOR device support —>    (选中即可,下级菜单默认)

添加对jffs2文件系统的支持:

File systems —>

[*] Miscellaneous filesystems —>

<*> Journalling Flash File System v2 (JFFS2) support

3.设备树配置

修改dts配置,添加spi flash节点:

vi arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts

添加下面的代码:

&spi0 {
        status ="okay";

        mx25l25635e:mx25l25635e@0 {
                compatible = "jedec,spi-nor";
                reg = <0x0>;
                spi-max-frequency = <50000000>;
                #address-cells = <1>;
                #size-cells = <1>;
        };

};

flash芯片的型号需要在下表之中,否则将无法识别:(注意容量也一定要对应)

static const struct spi_device_id m25p_ids[] = {
        /*
        * Allow non-DT platform devices to bind to the "spi-nor" modalias, and
        * hack around the fact that the SPI core does not provide uevent
        * matching for .of_match_table
        */
        {"spi-nor"},

        /*
        * Entries not used in DTs that should be safe to drop after replacing
        * them with "spi-nor" in platform data.
        */
        {"s25sl064a"},  {"w25x16"},     {"m25p10"},     {"m25px64"},

        /*
        * Entries that were used in DTs without "jedec,spi-nor" fallback and
        * should be kept for backward compatibility.
        */
        {"at25df321a"}, {"at25df641"},  {"at26df081a"},
        {"mx25l4005a"}, {"mx25l1606e"}, {"mx25l6405d"}, {"mx25l12805d"},
        {"mx25l25635e"},{"mx66l51235l"},
        {"n25q064"},    {"n25q128a11"}, {"n25q128a13"}, {"n25q512a"},
        {"s25fl256s1"}, {"s25fl512s"},  {"s25sl12801"}, {"s25fl008k"},
        {"s25fl064k"},
        {"sst25vf040b"},{"sst25vf016b"},{"sst25vf032b"},{"sst25wf040"},
        {"m25p40"},     {"m25p80"},     {"m25p16"},     {"m25p32"},
        {"m25p64"},     {"m25p128"},
        {"w25x80"},     {"w25x32"},     {"w25q32"},     {"w25q32dw"},
        {"w25q80bl"},   {"w25q128"},    {"w25q256"},

        /* Flashes that can't be detected using JEDEC */
        {"m25p05-nonjedec"},    {"m25p10-nonjedec"},    {"m25p20-nonjedec"},
        {"m25p40-nonjedec"},    {"m25p80-nonjedec"},    {"m25p16-nonjedec"},
        {"m25p32-nonjedec"},    {"m25p64-nonjedec"},    {"m25p128-nonjedec"},

        /* Everspin MRAMs (non-JEDEC) */
        { "mr25h256" }, /* 256 Kib, 40 MHz */
        { "mr25h10" },  /*   1 Mib, 40 MHz */
        { "mr25h40" },  /*   4 Mib, 40 MHz */

        { },
};

4.编译

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules_install

编译完成后,zImagearch/arm/boot/下,驱动模块在out/下,sun8i-v3s-licheepi-zero-dock.dtbarch/arm/boot/dts/下。

三.bulidroot根文件系统制作

1.下载buildroot

首先安装下Linux的头文件:

sudo apt-get install linux-headers-$(uname -r)

获取buildroot:

wget https://buildroot.org/downloads/buildroot-2017.08.tar.gz
tar -xvf buildroot-2017.08.tar.gz

2.配置buildroot

执行:

cd buildroot-2017.08/
make menuconfig

首先配置工具链,因为之前开发uboot和内核都用到了自己下载的工具链,所以这里也配置成外部工具链。

  • 在本机上外部工具链配置为: /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/
  • 工具链前缀是: arm-linux-gnueabihf
  • 外部工具链gcc版本:我们使用的是最新的6.3版本
  • 外部工具链内核头文件:是在 arm-linux-gnueabi/libc/usr/include/linux/version.h 里读取内核版本信息。本机的版本是4.6
  • C库还是选择传统的glibc。需要小体积可以选uclibc(需要自行编译安装)。
  • 再在system 设置下主机名,root密码等。
  • 最后就是配置自己需要的软件包,在menuconfig中选中即可。
  • 有时候下载速度慢,可以复制下载链接,使用迅雷等下载好后,拷贝到dl目录下,会自动识别。

配置图(点击看大图):

基础配置完,可以自己添加需要的包,推荐添加lrzsz、motion、bluez(若不需要蓝牙功能,尽量不要添加这个包,占空间大)。

lrzsz可以方便的在xshell中传输文件,文件直接拖拽到xshell中就可以传到板子上。

我的一些配置放在右侧的画廊了(若是手机端,则在文章最下方)。

3.编译

执行:

make

buildroot编译时间较长,与添加包的有关系还有网络,耐心等待。

编译过程中若报错,一个是少库文件,这个可以直接把错误扔到百度,就会有解决办法,告诉你需要装哪些包;还有一种报错的可能是,内存超限了,可以把虚拟机重启下试试,编译过程会占用很大内存。

编译完生成的rootfs.tar压缩文件在output/images/下。

四.打包

1.准备文件

u-boot-sunxi-with-spl.binzImagesun8i-v3s-licheepi-zero-dock.dtb放在同一级文件夹下。

在同级目录下建立rootfs文件夹,将rootfs.tar解压到该目录。

mkdir rootfs
tar -xvf buildroot-2017.08/output/images/rootfs.tar -C rootfs/

2.打包镜像

下载jffs2文件系统制作工具:

sudo apt-get install mtd-utils

以下操作在上边提到的同级目录下进行(我的是~/workspace/v3s/spi)。

生成jffs2.img:

mkfs.jffs2 -s 0x100 -e 0x10000 -p 0x1AF0000 -d rootfs/ -o jffs2.img

运行:

./pack.sh 32 dock

pack.sh文件内容(下面代码的第三句和官方的不一样!!!注意不是我写错了,就是if的文件名要和你的对应,$1代表传入的第一个参数,即:32,$2代表第二个参数,即:dock):

#!/bin/sh
dd if=/dev/zero of=flashimg.bin bs=1M count=$1
dd if=u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc
dd if=sun8i-v3s-licheepi-zero-$2.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

最后生成在该目录下生成flashimg.bin文件,就是要烧写的文件(我的Flash是32M,所以flashimg.bin文件是32M)。

五.烧写镜像

1.下载烧写工具

git clone -b spi-rebase https://github.com/Icenowy/sunxi-tools.git

2.修改文件,使sunxi-fel增加对16M以上Flash的支持

若要烧写的Flash空间大于16M,则必须修改文件,小于16M跳过此小节,直接编译安装。

cd sunxi-tools/
nano fel-spiflash.c
#or vi fel-spiflash.c

添加以下代码:

#define CMD_WRITE_ENABLE 0x06
#define SPI_FLASH_16MB_BOUN  0x1000000
#define CMD_BANKADDR_BRWR              0x17	//only SPANSION flash use it
#define CMD_BANKADDR_BRRD              0x16
#define CMD_EXTNADDR_WREAR             0xC5
#define CMD_EXTNADDR_RDEAR             0xC8
size_t bank_curr = 0;

void aw_fel_spiflash_write_helper(feldev_handle *dev,
				  uint32_t offset, void *buf, size_t len,
				  size_t erase_size, uint8_t erase_cmd,
				  size_t program_size, uint8_t program_cmd)
{
	uint8_t *buf8 = (uint8_t *)buf;
	size_t max_chunk_size = dev->soc_info->scratch_addr - dev->soc_info->spl_addr;
	size_t cmd_idx, bank_sel;

	if (max_chunk_size > 0x1000)
		max_chunk_size = 0x1000;
	uint8_t *cmdbuf = malloc(max_chunk_size);
	cmd_idx = 0;

	prepare_spi_batch_data_transfer(dev, dev->soc_info->spl_addr);
	//add bank support
	{
	cmd_idx = 0;
	bank_sel = offset /SPI_FLASH_16MB_BOUN;
	if (bank_sel == bank_curr)
		goto bar_end;

	/* Emit write enable command */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 1;
	cmdbuf[cmd_idx++] = CMD_WRITE_ENABLE;
	/* Emit write bank */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 2;
	cmdbuf[cmd_idx++] = CMD_EXTNADDR_WREAR;
	cmdbuf[cmd_idx++] = offset >> 24;
	/* Emit wait for completion */
	cmdbuf[cmd_idx++] = 0xFF;
	cmdbuf[cmd_idx++] = 0xFF;
	/* Emit the end marker */
	cmdbuf[cmd_idx++] = 0;
	cmdbuf[cmd_idx++] = 0;
	aw_fel_write(dev, cmdbuf, dev->soc_info->spl_addr, cmd_idx);
	aw_fel_remotefunc_execute(dev, NULL);
	bar_end:
		bank_curr = bank_sel;
	}
	
	cmd_idx = 0;

具体的添加位置见下图,希望能看懂(左边未添加,右边添加完成):

修改完后保存退出。

3.编译安装

进入工具目录(sunxi-tools)执行:

make && sudo make install

4.进入fel模式

Zero有一个usb下载模式称为fel模式,进入fel模式有下面几种方式:

  1. TF卡和spi flash 同时没有可启动镜像;
    也就是说你不插卡,且焊接的是新的或者没有有效镜像的spi flash,那就上电自动进入fel下载模式
  2. TF卡中有进入fel模式的特殊固件 fel-sdboot.sunxi
    如果你的spiflash已经有了启动镜像,那么需要在TF卡中烧入一个sunxi提供的 启动工具 ( dd if=fel-sdboot.sunxi of=/dev/mmcblk0 bs=1024 seek=8 ), 那么插入该TF卡启动会进入fel模式;
  3. 上电时SPI_MISO拉低到地
    该引脚为boot引脚,上电时出于低电平即会进入fel下载模式。

5.烧写镜像

进入fel模式后使用usb数据线连接pc和zero,即可进行操作。

sudo sunxi-fel version              #查看连接的cpu信息
AWUSBFEX soc=00001681(V3s) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 00000000
sudo sunxi-fel spiflash-info        #显示flash信息
Manufacturer: Unknown (C2h), model: 20h, size: 33554432 bytes.

执行如下命令烧入我们前边制作好的镜像文件flashimg.bin

sudo sunxi-fel -p spiflash-write 0 flashimg.bin
# -p 显示进度条
#   spiflash-info                   Retrieves basic information
#   spiflash-hex[dump] addr length  Dumps SPI flash region in hex
#   spiflash-read addr length file  Write SPI flash contents into file
#   spiflash-write addr file        Store file contents into SPI flash

SPI flash下载速度约50KB/s,等待5分钟(16MB)或者10分钟(32MB),烧写完成,如果一切顺利,重新上电zero那么就会进入linux系统了。