您尚未登录。

#1 全志 SOC » 为F1C100S的SPI Flash制作SquashFS+JFFS2+OverlayFS的rootfs来增大可读写空间 » 2019-10-11 16:22:55

Rikka0w0
回复: 30

荔枝派标配的是16MB的W25Q128 SPI Flash,在放入荔枝派官方的uboot 内核 rootfs的情况下,可用空间一般不超过1MB。
其实仔细观察一下还是有很多可以调整的空间的。

SquashFS可以对rootfs进行压缩,但是rootfs会变成只读的。可以使用OverlayFS将只读分区和可写分区合并,这样的rootfs优先使用SquashFS里的数据并且会把更改储存到JFFS2分区里面。只要运行时没有过多修改SquashFS里的数据,那这种方案节省的空间还是很多的。大名鼎鼎的OpenWRT既是采用了这种解决方案从而能在8MB Flash的路由器上运行的。这种方案运行时修改来自SquashFS的文件时,那个文件并不会动,而是会在JFFS2里储存修改后的文件,这样会有一个文件的两个版本,OverlayFS优先使用JFFS2里的版本,但是这样会造成两个版本同时存在,反而浪费空间,但是这也没办法。有得有失嘛。

这个是我的SPI Flash的结构:

Partition	Content		Offset		Size (byte)
mtd0		uboot-bin		0			0x58000 (360448 Byte)
		uboot-env		0x58000		0x8000
mtd1		dtb			0x60000		0x4000  (16kB)
mtd2		kernel		0x64000		0x400000 (4MB)
mtd3		rootfs		0x464000		0x4FC000 (4.98MB)
mtd4		overlay		0x960000		0x500000 (5MB)

相比官方的镜像,多了一个mtd4分区,就是用于储存运行时对rootfs修改的地方。注意这个mtd4的起始地址和大小必须是擦除区块大小的整数倍,不然无法写!我用的W25Q128这个数字是0x10000(64kB)。

首先是降低uboot的空间占用, https://whycan.cn/t_2179.html 里提到了uboot本体只有270kb,我看了下,确实是这样,我的u-boot.bin是268kb。
于是激进一点,把Environment Offset从0x100000调成了0x58000,这样Uboot部分分400kB就可以了,比原版的1MB小太多了。
话说回来Uboot一般也不会在之后加太多东西了,最多变变启动参数什么的,本体大小变化不大,这个应该是安全的。
具体的Uboot配置需要在`make ARCH=arm menuconfig`里修改,一共有三处:

# [ *] Enable boot arguments
   = console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=squashfs init=/etc/preinit
# [ *] Enable a default value for bootcmd
   = sf probe 0 50000000; sf read 0x80C00000 0x60000 0x4000; sf read 0x80008000 0x64000 0x400000; bootz 0x80008000 - 0x80C00000
# Environment -> Environment Offset = 0x58000

分别是:

1. 指定Linux的启动参数,要点是rootfstype=squashfs init=/etc/preinit这部分,之后会说。
2. 告诉UBoot如何把dtb和内核zImage从SPI Flash装载到内存里,这部分的SPI Flash地址要和上面的表对应。
3. 修改UBoot环境变量储存区的开始位置,减小空间浪费。

UBoot不需要修改c或者h文件。




然后是修改Linux内核的配置,同样还是`make ARCH=arm menuconfig`:

<*> Overlay filesystem support
[ *] Miscellaneous filesystems  --->
--><*>   Journalling Flash File System v2 (JFFS2) support
--><*>   SquashFS 4.0 - Squashed file system support

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

分别是启用了OverlayFS、JFFS2、SquashFS文件系统的支持,
启动MTD设备的缓存(这样才能用SPI Flash上启动)
然后就是修正原版.config里SPI控制器选错了的问题。

还有需要修改dts文件(arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts):

    flash: w25q128@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "winbond,w25q128", "jedec,spi-nor";
        reg = <0>;
        spi-max-frequency = <50000000>;
        partitions {
            compatible = "fixed-partitions";
            #address-cells = <1>;
            #size-cells = <1>;

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

            partition@60000 {
                label = "dtb";
                reg = <0x60000 0x4000>;
                read-only;
            };

            partition@64000 {
                label = "kernel";
                reg = <0x64000 0x400000>;
                read-only;
            };

            partition@464000 {
                label = "rootfs";
                reg = <0x464000 0x4FC000>;
                read-only;
            };

            partition@960000 {
                label = "overlayfs";
                reg = <0x960000 0x500000>;
            };

        };
    };

   

这里面的分区开始位置和大小要和uboot启动参数还有最上面的表对应才行。
到此为止uboot和Linux内核就修改好了。现在可以对u-boot和linux分别使用:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4

然后是编译linux的内核模块:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=out modules_install

现在可以开始制作rootfs了。首先是制作SquashFS部分,这部分是基于原版的Rootfs的。
1. 释放原来的rootfs到一个文件夹:

mkdir rootfs_new
cd rootfs_new
tar xvpzf ../rootfs.tar.gz

2. 把新编译的内核模块放进去
3. 创建映射文件夹

mkdir rootfs_new/overlay
mkdir rootfs_new/chroot
mkdir rootfs_new/rom

4. 建立一个启动脚本`rootfs_new/etc/preinit`:

#!/bin/sh

# export PATH="/usr/sbin:/usr/bin:/sbin:/bin"

# mount the new rootfs
mount -t squashfs /dev/mtdblock3 /rom
mount -t jffs2 /dev/mtdblock4 /overlay
mount -n -t overlay overlayfs:/overlay -o lowerdir=/rom,upperdir=/overlay/rw,workdir=/overlay/work /chroot

# mount /dev and /sys for chroot environment
# /dev/pts, /dev/shm, /proc, /tmp and /run will be mounted by inittab from fstab
mount -t sysfs sysfs /sys
mount --rbind /sys /chroot/sys/
mount --rbind /dev /chroot/dev/


exec chroot /chroot /sbin/init

启动参数里的init=/etc/preinit就是指这个脚本。根据Linux文档,init=这个参数会替换原本的/sbin/init被执行。
咱们的preinit首先会挂载只读分区SquashFS和可写分区JFFS2,再在/chroot文件夹中创建overlay,
然后在新的rootfs里挂在/dev和/sys,最后执行chroot并在新的root环境下执行/sbin/init,
回归系统正常的启动程序,只不过是在新的rootfs下。这样之后的程序都不会察觉rootfs发生了变化。使用如下命令打包SquashFS:
mksquashfs rootfs_new/ rootfs_new.img -no-exports -no-xattrs -all-root

最后一步是制作JFFS2的镜像:

mkdir -p overlay/work
mkdir -p overlay/rw
mkfs.jffs2 -s 0x100 -e 0x10000 --pad=0x500000 -o jffs2.img -d overlay/

work文件夹是OverlayFS需要的一个空文件夹,rw是储存增量修改的地方。



烧写入SPI Flash, 注意地址别写错:

# uboot
sudo sunxi-fel -p spiflash-write 0 u-boot/u-boot-sunxi-with-spl.bin
# dtb
sudo sunxi-fel -p spiflash-write 0x60000 linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
# kernel
sudo sunxi-fel -p spiflash-write 0x64000 linux/arch/arm/boot/zImage
# squashfs
sudo sunxi-fel -p spiflash-write 0x464000 rootfs_new.img
# jffs2
sudo sunxi-fel -p spiflash-write 0x960000 jffs2.img

推荐阅读:
https://gist.github.com/rikka0w0/f56977f81d1228fc503b00ad7b526aa7
https://gist.github.com/rikka0w0/e04eee5fa623b37866ded805c855f287
https://whycan.cn/t_2179_2.html
https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

#2 Re: 全志 SOC » V3s内部的RTC很不准,误差每天接近两分钟!!!? » 2019-10-11 15:35:13

这货好像没有板载晶振 是从哪分频得到的内部时钟源吧

#3 Re: 全志 SOC » F1C100s如何在uboot触发芯片进入usb otg烧录模式 » 2019-10-11 15:32:00

可以在flash的1脚(Chip Select)和地(USB口外壳或者Flash的4脚)之间焊接一个按键,按住上电插USB就进FEL。如图:
7fa6dc8b991a3120.jpg

#4 Re: 全志 SOC » 请问下荔枝派Nano教程spi-flash启动适配一节中的二进制bin打包所需要的Module文件在什么位置 » 2019-10-08 17:32:19

晕哥 说:

上面那个只是一个临时存放 ko 文件的目录而已

用这个命令吧:

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make modules_install INSTALL_MOD_PATH=/opt/buildroot-2018.08.2/output/target/

根据实际情况调整参数。


之前还需要执行下
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make module

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn