[Linux学习笔记]F1C100s的Nor-Flash镜像制作与烧录

397 阅读7分钟

分区规划

本文以licheepi_nano为例,参考官方的flash分区规划,可以得到Flash空间的分区表。

分区编号分区作用分区大小地址空间
mtd0spl+u-boot1MB(0x100000)0x0 ~ 0x100000
mtd1dtb64KB(0x1000)0x100000 ~ 0x110000
mtd2kernel4MB(0x400000)0x110000 ~ 0x510000
mtd3rootfs剩余空间(0xAF000)0x510000 ~ 0x1000000

编译spl+U-BOOT

首先要拉取并编译荔枝派官方u-boot,详情可以参考licheepi_nano官方教程文档: 前言 - Sipeed Wiki 或者直接执行下列命令进入配置界面。

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` 的宏定义
[*] 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

bootcmd中的sf指令:

sf 命令专门用于访问 SPI NOR flash,在uboot命令行界面下输入help sf可以得到使用说明:

QQ截图20230706112914.png

sf probe [[bus:]cs] [hz] [mode]:

sf probe用于初始化flash,sf probe 0 50000000表示初始化SPI0上的flash设备,速度为50MHz。

sf read addr offset|partition len

sf read用于读flash,sf read 0x80C00000 0x100000 0x4000表示读取0x4000长度的字节从flash设备最开始0x100000偏移地址起,到内存0x80C0000处。

sf write addr offset|partition len

sf write用于写flash,sf write 0x80C00000 0x100000 0x4000表示将内存0x80C00000开始0x4000字节长度写入flash设备最开始偏移地址0x100000处。

sf erase offset|partition [+]len

sf erase用于擦除flash设备内容,sf erase 0x100000 0x400000表示擦除0x400000字节内容,从flash设备最开始0x100000偏移处开始。

bootcmd参数详解

console=ttyS0,115200即使用ttyS0作为控制台输出,buadrate=115200

earlyprintk表示内核在启动过程中打印信息到界面上。

panic=5代表内核在无响应5s后进入“恐慌”

rootwait指内核在挂载到根文件系统之前,将一直处于等待

mtdparts=spi32766.0:1M(uboot)ro,64k(dtb)ro,4M(kernel)ro,-(rootfs)表示分区信息,要想使该参数生效,需要在编译kernel时打开MTD(Memerory Technology Device Support)选项。spi32766.0指具体设备,为什么是32766.0可以参考以下文章为什么是spi32766.0-CSDN,后面的内容则是具体的分区大小和分区名称

root=/dev/mtdblock3 rw指明了根文件系统位于的分区,并允许读写

rootfstype=jffs2代表根文件系统类型为jffs2

编译完成后我们就得到了u-boot-sunxi-with-spl.bin,将其保存到新建的Image目录下,该文件夹存放带烧录的镜像文件

编译kernel + dtb

详细的编译流程可以参考Licheepi_nano的官方教程主线Linux编译 - Sipeed Wiki

在make前最好先检查一遍配置信息,并将下列重要选项勾选。

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分区信息。
		<*>   Caching block device access to MTD devices	# 勾选,读写块设备用户模块
		<*>   SPI-NOR device support  --->

编译完成后将得到的ZImage文件和suniv-f1c100s-licheepi-nano.dtb文件,拷贝到刚才创建的Image文件夹下。

编译rootfs,并生成镜像

运行menuconfig后可以进行如下配置,具体配置看个人喜好。

Target options  --->
	Target Architecture (ARM (little endian))  --->
	Target Architecture Variant (arm926t)  --->
Toolchain  ---> 
	C library (musl)  --->
System configuration  --->
	(ender) System hostname	#
	(Welcome to my linux) System banner
	[*] Enable root login with password (NEW)
		(root) 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

完成后执行make,这个过程比较慢,可耐心等待10来分钟。不出意外的话会在/out/image目录下生成rootfs.tar文件,将该文件通过以下命令解压到新文件夹。

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

制作根文件系统镜像

由于要烧录的目标为Norflash,因此需要先安装mtd-utils工具,可以使用如下命令来安装。

sudo apt-get install mtd-utils

安装完毕后就可以进行镜像制作了,使用以下命令进行分区镜像制作。

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

其中-e指定块大小,-s指定页大小,-e指定擦除块大小,--pad用于指定制作的镜像大小,-d指定要制作的文件目录,-o指定镜像输出文件名称。完成后即可得到名为rootfs.img的根文件系统镜像,将其拷贝至Image文件夹下。至此,系统启动的3块拼图都已经集齐,接下来就是如何将他们整合成一个整体的镜像文件,并烧录进入板子上的nor-flash。

系统镜像的制作

切换到之前我们创建的Image目录,这里存放着文件有我们刚刚编译好的u-boot-sunxi-with-spl.binsuniv-f1c100s-licheepi-nano.dtb,ZImage,rootfs.img。此时我们可以在该目录下新建一个shell脚本,并在里面添加以下内容:

#bin/sh

dd if=/dev/zero of=download_flash.img bs=1M count=16
dd if=u-boot-sunxi-with-spl.bin of=download_flash.img conv=notrunc
dd if=suniv-f1c100s-licheepi-nano.dtb of=download_flash.img bs=1M seek=1 conv=notrunc
dd if=zImage of=download_flash.img bs=1K seek=1088 conv=notrunc
dd if=rootfs.img of=download_flash.img bs=1K seek=5184 conv=notrunc

这样就将uboot、dtb、kernel、rootfs分别写入了一个空的二进制文件中,从而形成了所谓的系统镜像。而这个download_flash.img就是我们要烧入flash中的最终系统镜像文件。

烧录

为了烧录该镜像,我们需要使用sunxi-fel工具,在使F1C100S/F1C200S上电进入FEL模式后,可以执行以下命令进行烧录

sudo sunxi-fel -p spiflash-write 0x0 download_flash.img

以下是笔者在烧录过程中遇到的一些问题,特在此处记录,以免忘记。

问题一:No package 'libusb-1.0' found

No package 'libusb-1.0' found
fel_lib.c:26:10: fatal error: libusb.h: 没有那个文件或目录
 #include <libusb.h>
          ^~~~~~~~~~
compilation terminated.
Makefile:129: recipe for target 'sunxi-fel' failed
make: *** [sunxi-fel] Error 1

解决:这是因为没有安装libusb-1.0-0-dev,手动安装即可。

sudo apt-get install libusb-1.0-0-dev

问题二:usb_bulk_recv() ERROR:-7:Operation time out

在虚拟机中烧录到一半,进度条卡住不动,并提示usb_bulk_recv() ERROR:-7:Operation time out

解决:可能是在虚拟机环境下造成的,换成windows环境下进行烧录即可,以下提出在windows下使用sunxi-fel的办法

1.下载工具包,链接:链接:pan.baidu.com/s/1ojHNVRY6… 提取码:6w9f

2.接入开发板,使其进入FEL模式

3.解压后运行zadig-2.5.exe,并点击Options选项下的List All Device

屏幕截图 2023-07-06 141710.png

4.在列表中选择刚才插入的FEL设备(USB ID:1f3a efe8),选择完毕后点击Reinstall Driver

QQ20180416161712.png

5.安装完毕后即可在windows下使用sunxi-fel工具。注意:该工具需要在命令行下运行。不熟悉cmd的可以在windows下装一个git工具来使用。

当烧写完成后,即可重启开发板,可以看到系统成功起来了,至此整个镜像的制作、烧录流程结束。