Difference between revisions of "How to use overlayfs on Linux/zh"

From FriendlyELEC WiKi
Jump to: navigation, search
(updated by API)
 
(updated by API)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[How to build FriendlyELEC FriendlyWRT|English]]
+
[[How to use overlay fs on Linux|English]]
  
==FriendlyWRT简介==
+
==什么是OverlayFS==
FriendlyWRT是友善电子基于OpenWrt定制的系统,完全开源,用于企业物联网二次开发,个人定制NAS,家庭物联网网关等。
+
Overlayfs是Linux下的一种堆叠文件系统,通俗地讲,根文件系统虽然在逻辑仍然是一个分区,但物理上被拆分成了两个分区来存储,其中,一个分区只读存放固化的系统数据(rootfs分区),另一个分区存储写入的数据(userdata分区),优点如下:<br />
TODO <br />
+
1) 方便恢复出厂设置,格式化userdata分区即可;<br />
==下载体验版固件==
+
2) 避免重复掉电或异常掉电导致userdata分区挂载异常无法进入系统,由于rootfs是只读的,此时仍可以进入系统,方便维护升级;<br />
TODO <br />
+
==哪些平台与系统支持OverlayFS==
解压后用 dd 或者 win32image 烧写到 SD 卡。
+
===支持的硬件平台===
==帐户与密码==
+
H3, H5, S5P4418, S5P6818, RK3399, RK3328, RK3568, RK3588系列开发板
用户名: root<br />
+
===支持的软件平台===
密码: fa<br />
+
所有基于Linux的系统
<br />
+
===本文档的适用范围===
==获取项目源代码==
+
本文仅适用于Rockchip平台的产品,如果你是其他平台,请点击此链接:[[How to use overlayfs on S5Pxxxx,H3,H5 platform/zh]]
===安装 repo 工具===
+
==如何鉴别系统是否工作在OverlayFS==
首先需要安装 repo 工具:
+
执行df命令,如果/分区挂载类型为 overlay,表示OverlayFS正在工作:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
git clone https://github.com/friendlyarm/repo
+
pi@NanoPi-R6C:/etc$ df -h
cp repo/repo /usr/bin/
+
Filesystem      Size  Used Avail Use% Mounted on
 +
tmpfs          792M  2.2M  790M  1% /run
 +
overlay          25G  13G  11G  53% /
 +
tmpfs          3.9G    0  3.9G  0% /dev/shm
 +
tmpfs          5.0M  4.0K  5.0M  1% /run/lock
 +
tmpfs          793M  116K  793M  1% /run/user/1000
 
</syntaxhighlight>
 
</syntaxhighlight>
===下载项目源代码===
+
==使用OverlayFS时的分区布局==
有以下两种途径获取项目源代码,中国大陆用户建议使用方法1的途径下载:
+
用户数据将由rootfs分区与userdata分区组成,对应的映像文件是rootfs.img和userdata.img. <br />
====方法一:使用网盘里的repo压缩包====
+
使下如下命令查看分区布局:
网盘下载地址: [http://download.friendlyarm.com/{{#replace:{{#replace:{{BASEPAGENAME}}| |}}|/zh|}} 点击进入]<br />
+
文件位于网盘的以下路径:sources/friendlywrt-YYYYMMDD.tar (YYYYMMDD表示打包的日期)<br />
+
从网盘中获取的 repo 压缩包在解压之后,需要执行一下以下命令做一次解包动作:
+
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
tar xvf /path/to/netdisk/sources/friendlywrt-YYYYMMDD.tar
+
查看eMMC分区布局: sudo parted -s /dev/mmcblk2 unit MiB print
cd friendlywrt
+
查看SD卡分区布局: sudo parted -s /dev/mmcblk0 unit MiB print
repo sync -l
+
 
</syntaxhighlight>
 
</syntaxhighlight>
用此方法得到的源代码版本是repo打包时的版本,如果想拉取到官方最新的版本,可以去掉 -l 参数,执行一次 repo sync, 例如:
+
输出信息如下所示:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
cd friendlywrt
+
pi@NanoPi-R6C:/etc$ sudo apt install parted
repo sync
+
pi@NanoPi-R6C:/etc$ sudo parted /dev/mmcblk0 print
</syntaxhighlight>
+
Model: SD SR32G (sd/mmc)
====方法二:从github下载====
+
Disk /dev/mmcblk0: 31.9GB
<syntaxhighlight lang="bash">
+
Sector size (logical/physical): 512B/512B
mkdir friendlywrt
+
Partition Table: gpt
cd friendlywrt
+
Disk Flags:
repo init -u https://github.com/friendlyarm/friendlywrt_manifests -b master -m h3.xml --repo-url=https://github.com/friendlyarm/repo
+
repo sync -c
+
</syntaxhighlight>
+
====同步项目到最新版本====
+
<syntaxhighlight lang="bash">
+
cd friendlywrt
+
repo sync -c
+
</syntaxhighlight>
+
同步过程中,由于网络原因出现中断,可以使用下面脚本同步代码:
+
<syntaxhighlight lang="bash">
+
#! /bin/bash
+
repo sync -c
+
while [ $? -ne 0 ];
+
do 
+
    repo sync -c
+
done
+
</syntaxhighlight>
+
  
==如何编译==
+
Number  Start  End    Size    File system  Name      Flags
===搭建编译环境===
+
1      8389kB  12.6MB  4194kB              uboot
在PC的Ubuntu系统下 (建议使用版本18.04-64bit),执下以下命令安装所需的软件:
+
2      12.6MB  16.8MB  4194kB              misc
<syntaxhighlight lang="bash">
+
3      16.8MB  21.0MB  4194kB              dtbo
wget -O - https://raw.githubusercontent.com/friendlyarm/build-env-on-ubuntu-bionic/master/install.sh | bash
+
4      21.0MB  37.7MB  16.8MB              resource
 +
5      37.7MB  79.7MB  41.9MB              kernel
 +
6      79.7MB  113MB  33.6MB              boot
 +
7      113MB  147MB  33.6MB              recovery
 +
8      147MB  4173MB  4027MB  ext4        rootfs
 +
9      4173MB  31.9GB  27.7GB  ext4        userdata
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
其中,rootfs分区是只读挂载的,userdata是可读写挂载的, rootfs分区存放固化的系统数据,后续对根目录的写入,都会写入到userdata分区, 因此格式化userdata也就相当于恢复出厂设置。<br />
  
===查看帮助===
+
==常用操作==
不带参数执行 build.sh,默认是打印帮助信息:
+
'''注意事项: '''<br/>
 +
* 这些操作会擦除用户数据,需要预先备份好数据<br>
 +
* 需要将固件更新至2023/03/14或之后的版本,或者单独更新boot.img<br>
 +
* 命令中出现的/dev/mmcblkX设备节点是虚构的节点,需要改成真实的设备,eMMC的设备节点是/dev/mmcblk2,TF卡的设备节点是/dev/mmcblk0<br>
 +
===查看当前的分区布局===
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
./build.sh
+
sudo apt update
 +
sudo apt install parted
 +
export DEV=/dev/mmcblkX # 需要改成真实的设备
 +
sudo parted -s ${DEV} unit MiB print
 
</syntaxhighlight>
 
</syntaxhighlight>
显示的帮助信息如下:
+
===禁用OverlayFS特性===
 +
在根目录下创建一个名为“.init_wipedata”的文件,内容为“overlayfs=disable”,然后重启,命令如下所示:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
USAGE: ./build.sh <parameter>
+
sudo passwd root  # 为root用户创建密码,如果之前没有做
 
+
su - root -c 'echo "overlayfs=disable" > /.init_wipedata'
# 选择目标的硬件平台:
+
sudo reboot
  ./build.sh friendlyelec_h3_series.mk
+
 
+
# 编译各个模块:
+
  ./build.sh all                -编译所有组件
+
  ./build.sh uboot              -单独编译uboot
+
  ./build.sh kernel            -单独编译kernel
+
  ./build.sh friendlywrt        -单独编译friendlywrt
+
  ./build.sh sd-img            -生成sd启动的镜像文件
+
  ./build.sh emmc-img          -生成用于安装到emmc的镜像文件 (镜像文件需要dd到sd卡,通过sd卡启动安装程序)
+
# 清理:
+
  ./build.sh cleanall
+
 
</syntaxhighlight>
 
</syntaxhighlight>
===全自动方式编译===
+
===调整userdata分区大小并创建一个额外分区===
初次编译,需要选择目标的硬件平台,当前只有H3可用,后续会加入更多的硬件支持:
+
* 查看当前的分区布局
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
./build.sh friendlyelec_h3_series.mk
+
sudo apt update
 +
sudo apt install parted fdisk
 +
export DEV=/dev/mmcblkX # 需要改成真实的设备
 +
sudo parted -s ${DEV} unit MiB print
 
</syntaxhighlight>
 
</syntaxhighlight>
执行上述命令,会自动编译所有组件,其中包括u-boot, kernel 和 friendlywrt,并生成sd启动的烧写镜像文件。
+
* 调整userdata分区的大小
===编译单独的模块===
+
这里以调整为8G大小为例,在根目录下创建一个名为“.init_wipedata”的文件,内容为“overlayfs=enable userdata=8096”,然后重启,其中userdata=后跟新的userdata分区大小,单位为MB,命令如下所示:
====kernel====
+
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
./build.sh kernel
+
su - root -c 'echo "overlayfs=enable userdata=8096" > /.init_wipedata'
 +
sudo reboot
 
</syntaxhighlight>
 
</syntaxhighlight>
====u-boot====
+
重启后, 正常情况下,可以看到userdata分区已调整为8GB:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
./build.sh uboot
+
export DEV=/dev/mmcblkX  # 需要改成真实的设备
 +
sudo parted -s ${DEV} unit MiB print
 
</syntaxhighlight>
 
</syntaxhighlight>
====friendlywrt====
+
* 创建新分区并格式化
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
./build.sh friendlywrt
+
(echo n; echo ""; echo ""; echo ""; echo w) | sudo fdisk ${DEV}
 +
NUM=$(sudo parted ${DEV} print | awk 'NF > 1 {p = $1} END {print p}')  # 获取最后一个分区的序号
 +
sudo mkfs.ext4 ${DEV}p${NUM}
 
</syntaxhighlight>
 
</syntaxhighlight>
===生成sdcard固件===
+
* 挂载新分区到指定目录
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
sudo ./build.sh sd-img
+
sudo mkdir -p /oem
 +
sudo blkid ${DEV}p${NUM}
 +
# 记下UUID
 +
# 配置开机自动挂载新创建的分区
 +
sudo vi /etc/fstab
 +
# 在文件末尾加入如下内容(其中UUID需替换为真实的)
 +
UUID=bbb06fe1-df52-4c7c-b2eb-926b14605fe4 /oem ext4 suid,dev,exec,auto,nouser,async,noatime,nofail 0 0
 +
# 输入以下命令挂载分区
 +
sudo mount /oem
 
</syntaxhighlight>
 
</syntaxhighlight>
打包img成功后,终端会显示如下信息,可以参考下面的dd命令将img写入sd卡,注意/dev/sdX需要替换成真实的sd卡设备:<br />
+
===恢复出厂设置(清空userdata数据)===
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Run the following for sdcard install:
+
su - root -c 'echo "overlayfs=enable" > /.init_wipedata'
    sudo dd if=out/h3-sd-friendlywrt-4.14-armhf-20190807.img bs=1M of=/dev/sdX
+
sudo reboot
 
</syntaxhighlight>
 
</syntaxhighlight>
===生成emmc (eflasher) 固件===
+
下次启动到ramdisk阶段,会对userdata分区进行格式化,/var/.init_wipedata 文件也会被清除。
 +
===调试===
 +
如发现分区未变化,可能是出现了错误,用以下命令检查是否有错误信息打印:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
sudo ./build.sh emmc-img
+
dmesg | grep initfs
 
</syntaxhighlight>
 
</syntaxhighlight>
打包img成功后,终端会显示如下信息,可以参考下面的dd命令将img写入sd卡,注意/dev/sdX需要替换成真实的sd卡设备:<br />
 
<syntaxhighlight lang="bash">
 
Run the following for sdcard install:
 
    sudo dd if=out/h3-eflasher-friendlywrt-4.14-armhf-20190807.img bs=1M of=/dev/sdX
 
</syntaxhighlight>
 
用此sd卡启动eflasher系统,执行eflasher命令,将系统写入emmc,之后就可以拨掉sd卡,从emmc启动friendlywrt了。
 
==friendlywrt定制与开发==
 
===源代码目录结构===
 
<syntaxhighlight lang="bash">
 
├── friendlywrt
 
│  ├── friendlywrt -> friendlywrt源代码
 
|  └── configs -> 保存预设好的friendlywrt defconfig文件
 
│  ├── build.sh -> 全自动编译脚本
 
│  ├── device/friendlyelec -> 用于适配友善电子开发板的相关文件
 
│  ├── kernel -> 内核
 
│  └── u-boot -> u-boot
 
│  └── scripts -> 打包img的相关脚本
 
</syntaxhighlight>
 
===配置friendlywrt的软件包===
 
* 使用make menuconfig更改配置
 
<syntaxhighlight lang="bash">
 
cd friendlywrt
 
make menuconfig
 
</syntaxhighlight>
 
* 另存你个人的软件包配置
 
<syntaxhighlight lang="bash">
 
make menuconfig
 
./scripts/diffconfig.sh > ../configs/my_config
 
</syntaxhighlight>
 
* 让以后的编译使用你的friendlywrt配置
 
编辑以下文件:
 
<syntaxhighlight lang="bash">
 
device/friendlyelec/h3/friendlyelec_h3_series.mk
 
</syntaxhighlight>
 
将TARGET_FRIENDLYWRT_CONFIG的值改为你的配置。
 
* 重新编译friendlywrt并制成sd启动镜像
 
<syntaxhighlight lang="bash">
 
./build.sh friendlywrt
 
./build.sh sd-img
 
</syntaxhighlight>
 
===固化个人文件到friendlywrt===
 
将文件或目录放入以下目录即可,打包img时会把它们都打包进去:
 
<syntaxhighlight lang="bash">
 
device/friendlyelec/h3/common-files
 
</syntaxhighlight>
 
也可以放在新建的目录里,然后编辑以下文件:
 
<syntaxhighlight lang="bash">
 
device/friendlyelec/h3/friendlyelec_h3_series.mk
 
</syntaxhighlight>
 
在文件中新增一行 (XXX替换为你的目录名):
 
<syntaxhighlight lang="bash">
 
FRIENDLYWRT_FILES+=(device/friendlyelec/h3/XXX)
 
</syntaxhighlight>
 
===修改friendlywrt系统的默认配置(如网络、防火墙等)===
 
进入如下目录:
 
<syntaxhighlight lang="bash">
 
device/friendlyelec/h3/default-settings/files/root/board
 
</syntaxhighlight>
 
编辑你所用的开发板目录所在的配置文件即可,比如下面是NanoPi-R1的配置文件:
 
<syntaxhighlight lang="bash">
 
NanoPi-R1
 
└── etc
 
    └── config
 
        ├── network
 
        └── system
 
</syntaxhighlight>
 
===更改u-boot和kernel配置===
 
同样是编辑如下文件:
 
<syntaxhighlight lang="bash">
 
device/friendlyelec/h3/friendlyelec_h3_series.mk
 
</syntaxhighlight>
 
可通过以下设置,将uboot的配置改为你自已的:
 
<syntaxhighlight lang="bash">
 
TARGET_UBOOT_CONFIG=nanopi_h3_defconfig
 
</syntaxhighlight>
 
可通过以下设置,将kernel的配置改为你自已的:
 
<syntaxhighlight lang="bash">
 
TARGET_KERNEL_CONFIG=sunxi_defconfig
 
</syntaxhighlight>
 
===更换其他源代码===
 
编辑如下 xml 文件,即可替换 kernel 、uboot以及friendlywrt的源代码:
 
<syntaxhighlight lang="bash">
 
.repo/manifests/h3.xml
 
</syntaxhighlight>
 
想了解 xml 文件各个节点的含义和用法,请参考:[https://gerrit.googlesource.com/git-repo/+/refs/heads/master/docs/manifest-format.md repo Manifest Format]<br />
 
编辑完成后,需要用 repo 命令同步一下,比如更换了 kernel 的源代码,用以下命令同步一次:
 
<syntaxhighlight lang="bash">
 
repo sync --force-sync kernel
 
</syntaxhighlight>
 
同步后单独重新内核即可:
 
<syntaxhighlight lang="bash">
 
./build.sh kernel
 
</syntaxhighlight>
 
 
==常见问题及注意事项==
 
* Ubuntu下不能使用 root 用户来编译,需要使用普通用户
 
* 在 vnc 环境下编译可能会编译失败
 
 
==参考资料==
 
[https://source.android.com/setup/develop/repo repo使用指南]<br />
 

Latest revision as of 02:36, 17 May 2023

English

1 什么是OverlayFS

Overlayfs是Linux下的一种堆叠文件系统,通俗地讲,根文件系统虽然在逻辑仍然是一个分区,但物理上被拆分成了两个分区来存储,其中,一个分区只读存放固化的系统数据(rootfs分区),另一个分区存储写入的数据(userdata分区),优点如下:
1) 方便恢复出厂设置,格式化userdata分区即可;
2) 避免重复掉电或异常掉电导致userdata分区挂载异常无法进入系统,由于rootfs是只读的,此时仍可以进入系统,方便维护升级;

2 哪些平台与系统支持OverlayFS

2.1 支持的硬件平台

H3, H5, S5P4418, S5P6818, RK3399, RK3328, RK3568, RK3588系列开发板

2.2 支持的软件平台

所有基于Linux的系统

2.3 本文档的适用范围

本文仅适用于Rockchip平台的产品,如果你是其他平台,请点击此链接:How to use overlayfs on S5Pxxxx,H3,H5 platform/zh

3 如何鉴别系统是否工作在OverlayFS

执行df命令,如果/分区挂载类型为 overlay,表示OverlayFS正在工作:

pi@NanoPi-R6C:/etc$ df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           792M  2.2M  790M   1% /run
overlay          25G   13G   11G  53% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           793M  116K  793M   1% /run/user/1000

4 使用OverlayFS时的分区布局

用户数据将由rootfs分区与userdata分区组成,对应的映像文件是rootfs.img和userdata.img.
使下如下命令查看分区布局:

查看eMMC分区布局: sudo parted -s /dev/mmcblk2 unit MiB print
查看SD卡分区布局: sudo parted -s /dev/mmcblk0 unit MiB print

输出信息如下所示:

pi@NanoPi-R6C:/etc$ sudo apt install parted
pi@NanoPi-R6C:/etc$ sudo parted /dev/mmcblk0 print
Model: SD SR32G (sd/mmc)
Disk /dev/mmcblk0: 31.9GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
 
Number  Start   End     Size    File system  Name      Flags
 1      8389kB  12.6MB  4194kB               uboot
 2      12.6MB  16.8MB  4194kB               misc
 3      16.8MB  21.0MB  4194kB               dtbo
 4      21.0MB  37.7MB  16.8MB               resource
 5      37.7MB  79.7MB  41.9MB               kernel
 6      79.7MB  113MB   33.6MB               boot
 7      113MB   147MB   33.6MB               recovery
 8      147MB   4173MB  4027MB  ext4         rootfs
 9      4173MB  31.9GB  27.7GB  ext4         userdata

其中,rootfs分区是只读挂载的,userdata是可读写挂载的, rootfs分区存放固化的系统数据,后续对根目录的写入,都会写入到userdata分区, 因此格式化userdata也就相当于恢复出厂设置。

5 常用操作

注意事项:

  • 这些操作会擦除用户数据,需要预先备份好数据
  • 需要将固件更新至2023/03/14或之后的版本,或者单独更新boot.img
  • 命令中出现的/dev/mmcblkX设备节点是虚构的节点,需要改成真实的设备,eMMC的设备节点是/dev/mmcblk2,TF卡的设备节点是/dev/mmcblk0

5.1 查看当前的分区布局

sudo apt update
sudo apt install parted
export DEV=/dev/mmcblkX # 需要改成真实的设备
sudo parted -s ${DEV} unit MiB print

5.2 禁用OverlayFS特性

在根目录下创建一个名为“.init_wipedata”的文件,内容为“overlayfs=disable”,然后重启,命令如下所示:

sudo passwd root  # 为root用户创建密码,如果之前没有做
su - root -c 'echo "overlayfs=disable" > /.init_wipedata'
sudo reboot

5.3 调整userdata分区大小并创建一个额外分区

  • 查看当前的分区布局
sudo apt update
sudo apt install parted fdisk
export DEV=/dev/mmcblkX # 需要改成真实的设备
sudo parted -s ${DEV} unit MiB print
  • 调整userdata分区的大小

这里以调整为8G大小为例,在根目录下创建一个名为“.init_wipedata”的文件,内容为“overlayfs=enable userdata=8096”,然后重启,其中userdata=后跟新的userdata分区大小,单位为MB,命令如下所示:

su - root -c 'echo "overlayfs=enable userdata=8096" > /.init_wipedata'
sudo reboot

重启后, 正常情况下,可以看到userdata分区已调整为8GB:

export DEV=/dev/mmcblkX  # 需要改成真实的设备
sudo parted -s ${DEV} unit MiB print
  • 创建新分区并格式化
(echo n; echo ""; echo ""; echo ""; echo w) | sudo fdisk ${DEV}
NUM=$(sudo parted ${DEV} print | awk 'NF > 1 {p = $1} END {print p}')  # 获取最后一个分区的序号
sudo mkfs.ext4 ${DEV}p${NUM}
  • 挂载新分区到指定目录
sudo mkdir -p /oem
sudo blkid ${DEV}p${NUM}
# 记下UUID
# 配置开机自动挂载新创建的分区
sudo vi /etc/fstab
# 在文件末尾加入如下内容(其中UUID需替换为真实的)
UUID=bbb06fe1-df52-4c7c-b2eb-926b14605fe4 /oem ext4 suid,dev,exec,auto,nouser,async,noatime,nofail 0 0
# 输入以下命令挂载分区
sudo mount /oem

5.4 恢复出厂设置(清空userdata数据)

su - root -c 'echo "overlayfs=enable" > /.init_wipedata'
sudo reboot

下次启动到ramdisk阶段,会对userdata分区进行格式化,/var/.init_wipedata 文件也会被清除。

5.5 调试

如发现分区未变化,可能是出现了错误,用以下命令检查是否有错误信息打印:

dmesg | grep initfs