当前位置:首页 > 技术 > LINUX > 正文内容

[转]《保姆级教程》全志F1C100S/F1C200S spi-flash 启动全流程适配烧录及踩坑指南

watrt2年前 (2021-12-29)LINUX21110

转自哇酷网=丨晋丨

通过参考荔枝派nano官方和论坛大佬的帖子,总结了烧录 spi-flash 启动的方法。

通过搜寻资料,把其中有错误或者做了多余的操作的步骤做了修正,以免大家再次踩坑,耗费青春。

以下包括 uboot、kernel、buildroot 和 烧录的详细步骤和需要注意的问题,尽量精简方法,以期容易上手和理解。

各种配置项也做了详细注释,要知其然,也知其所以然。

最理想的状态应该是是:有的坑,踩的人多了,也便没有了坑。

论坛不太好排版,有需要的也可以去我的博客看:P:全志F1C100S/F1C200S学习笔记(11)——spi-flash 启动全流程适配烧录及踩坑指南

 正文开始 

分区规划

分区序号分区大小              分区作用     地址空间及分区名
mtd0        1MB (0x100000)        spl+uboot     0x0000000-0x0100000 : “uboot”
mtd1        64KB (0x10000)        dtb文件        0x0100000-0x0110000 : “dtb”
mtd2        4MB (0x400000)        linux内核     0x0110000-0x0510000 : “kernel”
mtd3        剩余 (0xAF0000)       根文件系统     0x0510000-0x1000000 : “rootfs”


uboot 配置和编译

这种方法只需要修改配置就行,不需要修改源码和设备树:
这里只写使spi-flash需要做的修改,详细配置参考:全志F1C100S/F1C200S学习笔记(3)——u-boot编译与烧录

git clone https://gitee.com/LicheePiNano/u-boot.git -b nano-v2018.01&&cd u-boot
make licheepi_nano_spiflash_defconfig
make menuconfig
# 对应 `CONFIG_BOOTCMD` 的宏定义
# 选中 然后 run distro_bootcmd 修改为以下参数
[*] Enable a default value for bootcmd
(sf probe 0 50000000; sf read 0x80C00000 0x100000 0x4000; sf read 0x80008000 0x110000 0x400000; bootz 0x80008000 - 0x80C00000) bootcmd value

# 对应 `CONFIG_BOOTARGS` 的宏定义

[*] Enable boot arguments
(console=ttyS0,115200 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=/dev/mtdblock3 rw rootfstype=jffs2)    Boot arguments

参数说明

# 初始化Flash设备(CS拉低)
sf probe 0 50000000;
# 从flash0x100000(1MB)位置读取dtb放到内存0x41800000偏移处。
sf read 0x41800000 0x100000 0x10000;
# 从flash0x110000(1MB+64KB)位置读取dtb放到内存0x41000000偏移处。
sf read 0x41000000 0x110000 0x400000;
# 启动内核
bootz 0x41000000 (内核地址)- 0x41800000(dtb地址)

# 在串口0上输出信息,如果要用串口1做控制台就改为 console=ttyS1
# 由于在kernel刚启动的过程中,还没有为串口等设备等注册console(在device probe阶段实现),此时无法通过正常的console来输出log。
# early console机制,用于实现为设备注册console之前的早期log的输出。
# earlyprintk 是基于 early console的基础上实现

console=ttyS0,115200 earlyprintk panic=5 rootwait

# spi32766.0是设备名,后面是分区大小,名字,读写属性。
# 根文件系统是mtd3;jffs2格式  root=31:03 等同于 /dev/mtdblock3 指的是mtd设备第三分区

mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) root=31:03 rw rootfstype=jffs2

说明
1. 重要!!!官方文档这里有错误,不是 "sf probe 0:50000000; " ,应该是 "sf probe 0 50000000; "
2. root=/dev/mtdblock3 也可以用 root=31:03 表示。
3. mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs) 是FLASH分区,分区指定也可以在dts中声明。即修改内核源码目录下的 ./arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts。

添加FLASH支持_xt25f128b
由于我这开发板的FLASH没在支持列表(xt25f128b),所以需要自己添加,不然的话启动后报错 SF: unrecognized JEDEC id bytes: 0b, 40, 18。

# 显示spiflash的信息

$ sudo sunxi-fel spiflash-info
Manufacturer: Unknown (0Bh), model: 40h, size: 16777216 bytes.

修改 u-boot/drivers/mtd/spi/spi_flash_ids.c,根据上面查询的信息增加 xt25f128b:

const struct spi_flash_info spi_flash_ids[] = {
    ...
{"w25q128fw",   INFO(0xef6018, 0x0,64 * 1024,   256, RD_FULL | WR_QPP | SECT_4K) },
{"xt25f128b",   INFO(0x0b4018, 0x0,64 * 1024,   256, RD_FULL | WR_QPP | SECT_4K) },
    ...
};

修改 u-boot/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts:

&spi0 {
...
flash@0 {
        ...
compatible = "winbond,xt25f128b", "jedec,spi-nor";
...
};
};


kernel 配置

这里只写使用spi-flash需要做的修改,详细配置参考:
全志F1C100S/F1C200S学习笔记(5)——主线Linux编译
全志F1C100S/F1C200S学习笔记(6)——设备树添加节点

# 以下适配了 800*480屏幕 和 xt25f128bflash

git clone https://gitee.com/LicheePiNano/Linux.git && cd linux/
wget http://dl.sipeed.com/LICHEE/Nano/SDK/config
cp config .config
make menuconfig
File systems  --->
[*] Miscellaneous filesystems  --->
<*>   Journalling Flash File System v2 (JFFS2) support# 打开jffs2的文件系统支持
(0)     JFFS2 debugging verbosity (0 = quiet, 2 = noisy)
[*]     JFFS2 write-buffering support
[ ]     JFFS2 summary support
[ ]     JFFS2 XATTR support
[ ]     Advanced compression options for JFFS2
Device Drivers  --->
<*> Memory Technology Device (MTD) support  --->
<*>   Command line partition table parsing# 勾选,用来解析uboot传递过来的flash分区信息。(如果 bootarg 是用的我的方法一就需要勾选)
<*>   Caching block device access to MTD devices# 勾选,读写块设备用户模块
<*>   SPI-NOR device support  --->
[ ]   Use small 4096 B erase sectors# 取消勾选,否则jffs2文件系统会报错

注:

lichee官方的u-boot 中 kernel cmdline 使用jffs2格式的 mtdblock3 作为rootfs,但config中没有打开mtdblock设备接口。所以需要勾选 Caching block device access to MTD devices。

mkfs.jffs2 使用的最小擦除尺寸是 8KB,而spi flash的扇区大小是 4KB,所以按照扇区擦除的话,会无法使用,所以必须使用块擦除。即勾选 Use small 4096 B erase sectors。,这样以后添加FLASH也不用再修改源文件 linux/drivers/mtd/spi-nor/spi-nor.c 了

如果不勾选 Caching block device access to MTD devices,会卡在 Waiting for root device /dev/mtdblock3。

添加FLASH支持_xt25f128b
修改文件 linux/drivers/mtd/spi-nor/spi-nor.c :,在 { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }下面添加:

{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SECT_4K) },

buildroot 配置

git clone https://gitee.com/LicheePiNano/buildroot-2017.08.git
cd buildroot-2017.08/
make menuconfig
Target options  --->
Target Architecture (ARM (little endian))  --->
Target Architecture Variant (arm926t)  --->
Toolchain  ---> 
C library (musl)  --->
System configuration  --->
(gateway) System hostname# 主机名,随便改
(Welcome to gateway) System banner# 欢迎语,随便改
[*] Enable root login with password (NEW)
(123456) Root password# 登录密码,随便改
[*] remount root filesystem read-write during boot (NEW)# 重新挂载根文件系统到可读写
[*] Install timezone info# 安装时区信息,可选
(asia) timezone list
(Asia/Shanghai) default local time
Target packages  --->
System tools  --->
[*] util-linux  --->
[*]   mount/umount# 访问其它文件系统中的资源,如果要用overlayfs,那就要用这个挂载

** 生成 rootfs.jffs2 格式的rootfs,打开后会自动下载 mtd-utils 软件包。 **
看官方和论坛生成 rootfs.jffs2 格式的rootfs 都是自己再次打包的,其实 buildroot 可以直接选择生成这个格式的 rootfs :

Filesystem images  --->
[*] jffs2 root filesystem
Flash Type (Parallel flash with 64 kB erase size)  ---> # 具有64 kB擦除大小的并行闪存 -e 参数
[*]   Do not use Cleanmarker# 用于标记一个块是_完整地_被擦除了。 -n 参数 Do not use cleanmarkers if using NAND flash or Dataflash where the pagesize is not a power of 
[*]   Pad output
(0xAF0000) Pad output size (0x0 = to end of EB) # 指定 jffs2 分区总空间 -p(--pad) 参数
Endianess (little-endian)  --->
[ ]   Produce a summarized JFFS2 image (NEW)# 生成镜像的
[*]   Select custom virtual memory page size
(0x100) Virtual memory page size# 虚拟内存页大小-s 参数

当然,要自己用命令行手动生成方法也列在下面,并做了详细注释:(要把内核模块直接打包进文件系统还是要自己动手)

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

sudo apt-get install mtd-utils

# 解压
# -C 当前目录的绝对目录

mkdir rootfs && sudo tar -xvf rootfs.tar -C ./rootfs

# 生成 rootfs.jffs2
# -r :指定要做成image的目录名
# -o : 指定输出image的文件名
# -s :页大小 0x100 256 字节
# -e :块大小 0x10000 64k
# -p :或--pad 参数指定 jffs2 分区总空间
# 由此计算得到 0x1000000(16M)-0x10000(64K)-0x100000(1M)-0x400000(4M)=0xAF0000
# -n 如果挂载后会出现类似:CLEANMARKER node found at0x0042c000 has totlen 0xc != normal 0x0  的警告,则加上-n 就会消失。
# jffs2.img 是生成的文件系统镜像

sudo mkfs.jffs2 -s 0x100 -e 0x10000 -p 0xAF0000 -r rootfs -o rootfs.jffs2 -n

# 为根文件系统制作jffs2镜像包

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

# 或者

sudo mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0xAF0000 -d rootfs/ -o jffs2.img

烧录

烧录单独镜像

sudo sunxi-fel -p spiflash-write 0 ./u-boot/u-boot-sunxi-with-spl.bin   
sudo sunxi-fel -p spiflash-write 0x0100000 ./linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
sudo sunxi-fel -p spiflash-write 0x0110000 ./linux/arch/arm/boot/zImage 
sudo sunxi-fel -p spiflash-write 0x0510000 ./buildroot-2017.08/output/images/rootfs.jffs2

烧录完整镜像
16M 大小flash镜像打包脚本:nano_flash_dd.sh 如下:

#!/bin/sh
UBOOT_FILE=./u-boot/u-boot-sunxi-with-spl.bin
DTB_FILE=./Linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
KERNEL_FILE=./Linux/arch/arm/boot/zImage
ROOTFS_FILE=./buildroot-2021.02.4/output/images/rootfs.tar
MOD_FILE=./Linux/out/lib/modules/4.15.0-rc8-licheepi-nano+

dd if=/dev/zero of=flashimg.bin bs=1M count=16 &&\
dd if=$UBOOT_FILE of=flashimg.bin bs=1K conv=notrunc &&\
dd if=$DTB_FILE of=flashimg.bin bs=1K seek=1024 conv=notrunc &&\
dd if=$KERNEL_FILE of=flashimg.bin bs=1K seek=1088 conv=notrunc &&\
mkdir rootfs
tar -xvf $ROOTFS_FILE -C ./rootfs &&\
cp -r $MOD_FILE rootfs/lib/modules/ &&\

#为根文件系统制作jffs2镜像包
#--pad参数指定 jffs2大小
#由此计算得到 0x1000000(16M)-0x10000(64K)-0x100000(1M)-0x400000(4M)=0xAF0000
mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0xAF0000 -d rootfs/ -o jffs2.img &&\
dd if=jffs2.img of=flashimg.bin bs=1K seek=5184 conv=notrunc &&\
rm -rf rootfs &&\
rm jffs2.img

先用脚本打包成 flashimg.bin:

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

sudo apt-get install mtd-utils

# 给脚本权限

chmod 777 nano_flash_dd.sh

# 加 sudo,不然会报错 tar: 由于前次错误,将以上次的错误状态退出

sudo ./nano_flash_dd.sh

在执行以下命令烧录:

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

问题解决汇总

问题1:

$ sudo sunxi-fel ver
Warning: no 'soc_sram_info' data for your SoC (id=1663)
AWUSBFEX soc=00001663(unknown) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 00000000

解决:
sunxi-tools 分支不对,用 git checkout 切换分支,具体可查看 全志sunxi-tools烧录工具安装和使用

问题2:

SF: unrecognized JEDEC id bytes: 0b, 40, 18
*** Warning - spi_flash_probe_bus_cs() failed, using default environment

解决:
uboot没有板上使用的FLASH支持,参考 1 楼的添加FLASH支持章节。
识别成功后会显示:

SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB

问题3:

spi_flash@0:50000000: failed to activate chip-select 50000000
SF: error -2 reading JEDEC ID
Failed to initialize SPI flash at 0:50000000 (error -2)
No SPI flash selected. Please run `sf probe'
No SPI flash selected. Please run `sf probe'

解决:
上面说了,官方文档的错误,"sf probe 0:50000000; " ,修改为 "sf probe 0 50000000; "

问题4:

日志中有dts中的spiflash 分区信息打印,但仍然卡在 waiting for rootfs
解决:
内核配置:

Device Drivers  --->
<*> Memory Technology Device (MTD) support  --->
<*>   Caching block device access to MTD devices# 勾选,读写块设备用户模块
        [*] SPI support  --->
               < >   Allwinner A10 SoCs SPI controller   # 取消勾选
               <*>   Allwinner A31 SPI controller   # 勾选

问题5:

[    1.476051] VFS: Cannot open root device "mtdblock3" or unknown-block(31,3): error -19
[    1.484131] Please append a correct "root=" boot option; here are the available partitions:
[    1.492542] 1f00            1024 mtdblock0 
[    1.492554]  (driver?)
[    1.499197] 1f01              64 mtdblock1 
[    1.499208]  (driver?)
[    1.505747] 1f02            4096 mtdblock2 
[    1.505753]  (driver?)
[    1.512349] 1f03           11200 mtdblock3 
[    1.512358]  (driver?)

解决:

这个问题一般是 flash分区信息 没有正确配置导致的。

如果 bootarg 是用的我的传参方法配置的,内核需要勾选上mtd的 <*> Command line partition table parsing 支持,该项是用来解析uboot传递过来的flash分区信息。

没添加对jffs2文件系统的支持,需要勾选 File systems ‣ Miscellaneous filesystems ‣ Journalling Flash File System v2 (JFFS2) support



分享给朋友:

相关文章

mkfs 参数

mkfs 参数

#mkfs.jffs2 -r rootfs -o fs.jffs2 -e 0x20000 --pad=0x500000 -s 0x800 –n -l即可生成 rootfs.jffs2Mkfs.jffs2各参数的意义如下:-r:指定要做成image的目录名。-o:指定输出image的文件名。-e:每一块要擦除的block size,默认是64KB.要注意,不同的flash, 其block size会不一样,三星的K9F2G08U0A的block size为0x20000(从其datasheet里可...

基于 debootstrap 和 busybox 构建 mini ubuntu

基于 debootstrap 和 busybox 构建 mini ubuntu

最近的工作涉及到服务器自动安装和网络部署操作系统,然后使用 ansible 和 saltsatck 进行配置并安装 openstack 。难点在于服务器的自动安装,由于不单只是通过 PXE 安装服务器,还需要能够安装时进行分区、配置网卡等工作,因此需要在开始安装前,必须先收集服务器的硬件信息。调研了一下目前的开源项目中,提供此类功能的有 tinycorelinux 、 puppet razor-el-mk 可做类似的工作。tinycorelinux 是个很好的工具,整个系统在 PXE 之后在内存...

制作荔枝派Zero开发板(全志V3s) TF/SD卡启动盘

制作荔枝派Zero开发板(全志V3s) TF/SD卡启动盘

0. 前言近几天买了一块荔枝派0开发板,以及官方配的480×272的屏幕。让我记录一下入坑与采坑过程。1. u-boot的编译git clone https://github.com/Lichee-Pi/u-boot -b v3s-current cd u-boot make ARCH=arm LicheePi_Zero_480x272LCD_defconfig make ARCH=arm CROSS...

LINUX 使用sendmail邮件备份

LINUX 使用sendmail邮件备份

首先安装:sudo apt-get install sendmail然后在终端可以使用mail来发邮件echo "ESP32固件"|mail -s "esp32" -A "./fw.bin" -r "bak@xxx.com" xb100@qq.com注意很有可能收到的邮件在垃圾箱里面。把发件地址加到白 名单中...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。