您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

zero(全志V3S)-32MB Flash移植

写在前面
V3S 是块好板子 开发潜力极大

本文提供32M移植 Flash为 GD25Q256 内核 Linux 5.2.0

Linux 5.2.0 编译的镜像大小为4.2MB 所以需要修改分区
修改好的分区如下

分区号分区大小分区地址
mtd01MB0x0000000-0x0100000 : “uboot”
mtd164KB0x0100000-0x0110000: “dtb”
mtd25MB0x0110000-0x0610000 : “kernel”
mtd3-10x0510000-0x2000000 : “rootfs”

编译器

可参考设置路径如下

export PATH=$PATH:/gcc_build/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf/bin

Uboot部分

https://github.com/Lichee-Pi/u-boot.git

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

下载好之后,进入主目录
第一步make LicheePi_Zero_defconfig
第二步make ARCH=arm menuconfig
选上SPI flash Bank/Extended address register support支持 否则只能读取到16M
修改
修改Flash驱动项
在这里插入图片描述
下面开始修改代码段
文件 include/configs/sun8i.h
添加默认bootcmd和bootargs的环境变量设置

#define CONFIG_BOOTCOMMAND "sf probe 0; sf read 0x41800000 0x100000 0x10000; sf read 0x41000000 0x110000 0x500000; bootz 0x41000000 - 0x41800000"
#define CONFIG_BOOTARGS "console=ttyS0,115200 earlyprintk panic=5 rootwait mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,5M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2"

文件 drivers/mtd/spi 的spi_flash_ids.c
添加 GD25Q256 的描述

#ifdef CONFIG_SPI_FLASH_GIGADEVICE	/* GIGADEVICE */
	{"gd25q64b",	   INFO(0xc84017, 0x0, 64 * 1024,   128, SECT_4K) },
	{"gd25lq32",	   INFO(0xc86016, 0x0, 64 * 1024,    64, SECT_4K) },
	{"gd25q256",	   INFO(0xc84019, 0x0, 64 * 1024,    512, 0) },
#endif

编译Uboot

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

Kernel 部分

https://github.com/Lichee-Pi/linux/tree/zero-5.2.y

Github 下载可能有时候比较慢 可以多尝试一下或者找代理

下载好之后
进入主目录
执行 make ARCH=arm licheepi_zero_defconfig
执行 make ARCH=arm menuconfig

内核添加JFFS2支持 如下即可
在这里插入图片描述
进入 Device Drivers > Memory Technology Device (MTD) support
选中 Command line partition table parsing
用于解析Uboot参数
在这里插入图片描述
SPI-FLASH部分
5.2的版本默认配置 支持 m25p80的驱动 这部分就不需要修改了

修改设备树描述文件
路径 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
添加节点`


&spi0 {
        status ="okay";
		gd25q256:gd25q256@0 {
                compatible = "jedec,spi-nor";
                reg = <0x0>;
                spi-max-frequency = <50000000>;
                #address-cells = <1>;
                #size-cells = <1>;
				partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;

            partition@0 {
                label = "u-boot";
                reg = <0x000000 0x100000>;
                read-only;
            };

            partition@100000 {
                label = "dtb";
                reg = <0x100000 0x10000>;
                read-only;
            };

            partition@110000 {
                label = "kernel";
                reg = <0x110000 0x500000>;
                read-only;
            };

            partition@610000 {
                label = "rootfs";
                reg = <0x610000 0x19F0000>;
            };
        };
        };

};

修改 drivers\mtd\devices\m25p80.c 文件
在 static const struct spi_device_id m25p_ids[] 的成员中添加 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"},
	......
		{"w25q80bl"},	{"w25q128"},	{"w25q256"},{"gd25q256"},

修改 drivers\mtd\spi-nor\spi-nor.c 文件 去除 SECT_4K
mkfs.jffs2 使用的最小擦除尺寸是8KB,而spi flash的扇区大小是4KB,所以按照扇区擦除的话,会无法使用,所以必须使用块擦除 内核需要和文件系统的配置一致

	{
		"gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
			SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
			.quad_enable = macronix_quad_enable,
	},

以下函数需要添加特殊处理 打个补丁

int spi_nor_scan(struct spi_nor *nor, const char *name,
		 const struct spi_nor_hwcaps *hwcaps)
{

........
	if (info->flags & SPI_NOR_4B_OPCODES ||
	    (JEDEC_MFR(info) == SNOR_MFR_SPANSION && mtd->size > SZ_16M))
		nor->flags |= SNOR_F_4B_OPCODES;


// 添加以下代码段
	if (info->flags & SPI_NOR_4B_OPCODES ||
	    (JEDEC_MFR(nor->info) == SNOR_MFR_GIGADEVICE && mtd->size > SZ_16M)){
		nor->mtd.erasesize = nor->info->sector_size;
		}

	if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES &&
	    !(nor->flags & SNOR_F_HAS_4BAIT))
		spi_nor_set_4byte_opcodes(nor);
.......

编译内核
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

文件 路径 linux-zero-5.2.y/arch/arm/boot
dtb 文件需要使用 sun8i-v3s-licheepi-zero-dock.dtb

文件系统制作

使用JFFS2去制作文件系统
可以使用Busybox 等工具 制作出一个文件系统 这边就不展开了
使用mkfs.jffs2 打包成文件系统镜像

若没有 mkfs.jffs2 可以执行

sudo apt-get install mtd-utils

我使用的打包命令

mkfs.jffs2 -n -l -s 0x100 -e 0x10000 --pad=0x19F0000 -r ./system/ -o ./system.jffs2

-p 指的是rootfs占据的总空间: 32M-1M-64K-4M=0x1AF0000
-s 页大小0x100 256字节
-e 块大小0x10000 64k
jffs2.img是生成的文件系统镜像。

烧录

烧录工具
https://github.com/Icenowy/sunxi-tools.git

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

工具 修改针对 32M Falsh的支持
需要检查下代码在这里插入图片描述

原文:

#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;

这里附带另一下载工具
sunxi-tools-3s-spi
是另一个分支
路径如下

https://github.com/Icenowy/sunxi-tools/tree/v3s-spi

USB烧录需要使用 打包 后进行下载

可以使用如下脚本

dd if=/dev/zero of=flashimg.bin bs=32M count=1
dd if=u-boot/u-boot-sunxi-with-spl.bin of=flashimg.bin bs=1K conv=notrunc
dd if=dts/sun8i-v3s-licheepi-zero-dock.dtb of=flashimg.bin bs=1K seek=1024  conv=notrunc
dd if=kernel/zImage of=flashimg.bin bs=1K seek=1088  conv=notrunc
dd if=rootfs/system.jffs2 of=flashimg.bin  bs=1K seek=6208  conv=notrunc

第一步:生成一个空文件,大小是32MB
第二步:将uboot添加到文件开头
第三步:将dtb放到1M偏移处
第四步:将kernel放到1M+64K偏移处
第五步:将rootfs放到1M+64K+5M偏移处
偏移大小是seek,单位是KB。
执行完毕后生成镜像文件flashimg.bin

sudo sunxi-tools/sunxi-fel -p spiflash-write 0 flashimg.bin


fel 模式描述: usb下载模式称为fel模式,进入fel模式主要用下面2种情况:
1.TF卡和spi flash 同时没有可启动镜像
2.上电时SPI_MISO拉低到GND
V3S Zero的板子 可以通过短接 +号按键上方的 SPI CS 和GND 实现进入fel 模式


//列出所有芯片的信息:
sudo sunxi-fel -l

//查看芯片信息:
sudo sunxi-fel ver

//加载并执行uboot的spl
sudo sunxi-fel spl 文件名

//显示spiflash的信息 
sudo sunxi-fel spiflash-info

//调用指定地址的函数 
sudo sunxi-fel exec 地址

//把文件内容写入内存指定地址(-p是显示写入进度) 
sudo sunxi-fel -p write 地址 文件名

//读取spiflash指定地址的数据并写入到文件 
sudo sunxi-fel spiflash-read 地址 长度 存放数据的文件路径

//写入指定文件的指定长度的内容到spiflash的指定地址 
sudo sunxi-fel spiflash-write 地址 长度 存放数据的文件路径

分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进