erofs

erofs(extendable read-only file system)是和squashfs类似的文件系统,有两个显著的特定:只读和压缩,其在减小体积的同时,带来了比ext4更好的性能。

性能测试见下表,Kirin970 (A73 Big-core 2361Mhz, A53 little-core 0Mhz, DDR 1866Mhz)

compression EROFS seq read EXT4 seq read EROFS random read EXT4 random read
ratio bw[MB/s] bw[MB/s] bw[MB/s] (20%) bw[MB/s] (20%)
4 546.7 544.3 157.7 57.9
10 535.7 521.0 152.7 62.0
15 529.0 520.3 125.0 65.0
26 418.0 526.3 97.6 63.7
35 367.7 511.7 89.0 63.7
48 415.7 500.7 78.2 61.2
53 423.0 566.7 72.8 62.9
66 334.3 537.3 69.8 58.3
76 387.3 546.0 65.2 56.0
85 306.3 546.0 63.8 57.7
94 345.0 589.7 59.2 49.9
100 579.7 556.7 62.1 57.7

测试结果上看低压缩比的下性能比传统EXT4要好近3倍,高压缩比的情况下性能也与EXT4相当

编译参数

1
subproduct=EROFS export_para=UPDATE_PRODUCT_EROFS:true export_para=SYSTEMIMAGE_FS_TYPE:erofs

特别注意:preload功能也需要打开,否则mount会卡在preload处,后续的一些分区无法自动mount上来。

overlay

只读分区用于发布系统无可厚非,但在调试阶段将极大地降低调试效率,为解决这个问题,引入了overlay机制。例如,vendor分区会有对应的overlay分区,那个分区负责保存可写的内容。目前,root包会打开overlay机制方便调试。

overlay

/system是由/system_lower和/x目录拼起来的, 其中/x目录在上层, /system_lower在下层。往/system的写操作会在/x目录中生效, /x有多大, 就能往/system目录写多大。

x分区的选择:

  1. system分区由于有system-as-root方案,x分区是用cache分区作为x分区的,所以cache分区的大小限制了可以往system分区push多大的文件

  2. 除system分区外,其他分区的 x分区采用分区中除了erofs文件系统和verifyboot数据的内容, 映射成一个device-mapper设备

分区格式判断

  1. simg2img转换镜像
  2. 使用下面脚本检测magic
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/bin/bash -
#===============================================================================
#
#          FILE: get_erofs.sh
#
#         USAGE: ./get_erofs.sh
#
#   DESCRIPTION:
#
#       OPTIONS: ---
#  REQUIREMENTS: ---
#          BUGS: ---
#         NOTES: ---
#        AUTHOR: YOUR NAME (),
#  ORGANIZATION:
#       CREATED: 03/01/2019 10:35:26 AM
#      REVISION:  ---
#===============================================================================

set -o nounset                                  # Treat unset variables as an error

RET_IS_UNKNOWN=0
RET_IS_DIR=1
RET_IS_SPARSE=2
RET_IS_EXT4=3
RET_IS_GZIP=4
VERSION=1.20190307.0

usage(){
	echo "check_file_type.sh version:${VERSION}"
	echo "usage"
	echo "	check_file_type.sh <image>"
	echo "notes:"
	echo "	1. xxd V1.10 27oct98 by Juergen Weigert is depend"
	echo "	   Current xxd is: "	
	echo -n "	   "
	xxd --version
	echo "	2.simg2img is depend"
	exit 1
}

checkcmd() {
    echo -n "check cmd : $1 "
    if hash $1 > /dev/null 2>&1; then
    	echo "found"
        return 0
    else
        pr_red "$1 not found"
        usage
        exit 1
    fi
}

check_file_type(){
    local src=$1

    echo  "check file: $1"
    if [ -d $src ];then
        echo  "$src is dir ret=${RET_IS_DIR}"
        # "dir"
        return ${RET_IS_DIR}
    fi

    file $src | grep sparse >/dev/null 2>&1
    if [ $? = 0 ];then
        echo  "check file: $src is sparse img ret=${RET_IS_SPARSE}"
        #return "sparse"
        return ${RET_IS_SPARSE}
    fi

    file $src | grep ext4 >/dev/null 2>&1
    if [ $? = 0 ];then
        echo  "check file: $src is ext4 img ret=${RET_IS_EXT4}"
        #return "raw ext4"
        return ${RET_IS_EXT4}
    fi

    file $src | grep gzip >/dev/null 2>&1
    if [ $? = 0 ];then
        echo  "check file: $src is gizp img ret=${RET_IS_GZIP}"
        #return "gzip"
        return ${RET_IS_GZIP}
    fi
    return ${RET_IS_UNKNOWN}
}

is_erofs_img(){
	filename=$1

	echo "check img: ${filename}"
	#xxd should be xxd V1.10 27oct98 by Juergen Weigert
	magic_erofs=$(xxd -s +1024 -l4 -ps ${filename})
	magic_ext4=$(xxd -s +1080 -l2 -ps ${filename})

	if test ${magic_erofs} == e2e1f5e0
	then
		echo "${filename} is EROFS"
		return 0
	elif test ${magic_ext4} == 53ef
	then
		echo "${filename} is EXT4"
		return 0
	else
		echo "magic_erofs: ${magic_erofs}"
		echo "magic_ext4 : ${magic_ext4}"
		echo "${filename} is unknow, NOT EROFS or EXT4 !!"
		return 1
	fi
}

main() {
	filename=$1
	filename_raw=${filename}_raw
	check_file_type ${filename}
	file_type=$?

	if [ ${file_type} -eq ${RET_IS_UNKNOWN} ];then
		is_erofs_img ${filename}
		if [ $? -eq 1 ];then
			exit 1
		fi

	elif [ ${file_type} -eq ${RET_IS_DIR} ];then
		echo "$1 is a dir, ERROR !!"
		exit 1
	elif [ ${file_type} -eq ${RET_IS_EXT4} ];then
		echo "$1 is a EXT4!!"
		exit 1
	elif [ ${file_type} -eq ${RET_IS_SPARSE} ];then
		simg2img ${filename} ${filename_raw}
		is_erofs_img ${filename_raw}
		#rm -f ${filename_raw}

	elif [ ${file_type} -eq ${RET_IS_GZIP} ];then
		tempdir=.erofs_temp
		filename_zip=${filename}.zip
		mkdir ${tempdir}
		cp ${filename} ${tempdir}/${filename_zip}
		cd ${tempdir}
		gunzip ${filename_zip}
		simg2img ${filename} ${filename_raw}
		is_erofs_img ${filename_raw}
		cd ..
		#rm -rf ${tempdir}
		exit 0
	else
		echo "$1 is unknown file type !!"
		exit 1
	fi
}

if [ $# != 1 ];then
	usage
fi

checkcmd simg2img

if [ ! -e $1 ];then
	echo "$1 is NOT exist !!!"
	usage
	exit 1
fi
main $1

手工mount

  1. 使用make命令编译生成 erofs.ko文件
  2. 执行 sudo insmod erofs.ko
  3. 使用 工具 simg2img 将sparse格式转化为unsparse格式
  4. 挂载镜像,命令 mount -t erofs something somewhere -o loop

http://hi3ms-image.huawei.com/hi/3msimage/download-1434827189-58807-7a43faf792dfa3861b75b87cab4b1d45.bin?type=group_wiki