-
Notifications
You must be signed in to change notification settings - Fork 24
/
build-rootfs-img.sh
executable file
·212 lines (199 loc) · 6.79 KB
/
build-rootfs-img.sh
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/bin/bash
set -eu
if [ $# -lt 2 ]; then
echo "Usage: $0 <rootfs dir> <img dir>"
echo "example:"
echo " ./tools/extract-rootfs-tar.sh rootfs-ubuntu-focal-desktop-arm64.tgz"
echo " ./build-rootfs-img.sh ubuntu-focal-desktop-arm64/rootfs ubuntu-focal-desktop-arm64"
exit 0
fi
TOP=$PWD
ROOTFS_DIR=$1
TARGET_OS=$(echo ${2,,}|sed 's/\///g')
IMG_FILE=$TARGET_OS/rootfs.img
if [ $# -eq 3 ]; then
IMG_SIZE=$3
else
IMG_SIZE=0
fi
true ${FS_TYPE:=ext4}
if [ ! -d ${ROOTFS_DIR} ]; then
echo "path '${ROOTFS_DIR}' not found."
exit 1
fi
# ----------------------------------------------------------
# Get host machine arch
HOST_ARCH=
if uname -mpi | grep aarch64 >/dev/null; then
HOST_ARCH="aarch64/"
fi
# Automatically re-run script under sudo if not root
if [ $(id -u) -ne 0 ]; then
echo "Re-running script under sudo..."
sudo --preserve-env "$0" "$@"
exit
fi
# Clean up temporary files
clean_rootfs() {
(cd $1 && {
# remove machine-id, the macaddress will be gen via it
[ -f etc/machine-id ] && > etc/machine-id
[ -f var/lib/dbus/machine-id ] && {
rm -f var/lib/dbus/machine-id
ln -s /etc/machine-id var/lib/dbus/machine-id
}
rm -f etc/pointercal
rm -f etc/fs.resized
rm -f etc/friendlyelec-release
rm -f root/running-state-file
rm -f etc/firstuse
rm -f etc/.overlayfs.disabled
rm -f var/cache/apt/archives/lock
rm -f var/lib/dpkg/lock
rm -f var/lib/dpkg/lock-frontend
rm -f var/cache/apt/archives/*.deb
[ -f etc/udev/rules.d/70-persistent-net.rules ] && cat /dev/null > etc/udev/rules.d/70-persistent-net.rules
rm -rf var/log/journal/*
[ -d ./tmp ] && find ./tmp -exec rm -rf {} +
mkdir -p ./tmp
chmod 1777 ./tmp
if [ -d ./var/lib/apt/lists ]; then
PERM=`grep "^_apt" ./etc/passwd | cut -d':' -f3`
if [ -e ./var/lib/apt/lists ]; then
[ -z ${PERM} ] || chown -R ${PERM}.0 ./var/lib/apt/lists
fi
if [ -e ./var/cache/apt/archives/partial ]; then
[ -z ${PERM} ] || chown -R ${PERM}.0 ./var/cache/apt/archives/partial
fi
fi
[ -d var/log ] && find var/log -type f -delete
[ -d var/tmp ] && find var/tmp -type f -delete
find -name .bash_history -type f -exec cp /dev/null {} \;
[ -e var/lib/systemd ] && touch var/lib/systemd/clock
[ -e var/lib/private/systemd/timesync ] && touch var/lib/private/systemd/timesync/clock
if [ -d var/lib/NetworkManager/ ]; then
rm -fr var/lib/NetworkManager/dhclient*
rm -fr var/lib/NetworkManager/secret_key
rm -fr var/lib/NetworkManager/timestamps
fi
(cd dev && find . ! -type d -exec rm {} \;)
})
}
clean_rootfs ${ROOTFS_DIR}
make_ext4_img() {
local RET=0
local MKFS_PID=
local MKFS="${TOP}/tools/${HOST_ARCH}mke2fs"
local MKFS_OPTS="-E android_sparse -t ext4 -L rootfs -M /root -b 4096"
case ${TARGET_OS} in
friendlywrt* | buildroot*)
# set default uid/gid to 0
MKFS_OPTS="-0 ${MKFS_OPTS}"
;;
*)
;;
esac
if [ ${IMG_SIZE} -le 0 ]; then
# calc image size
IMG_SIZE=$(((`du -s -B64M ${ROOTFS_DIR} | cut -f1` + 3) * 1024 * 1024 * 64))
IMG_BLK=$((${IMG_SIZE} / 4096))
INODE_SIZE=$((`find ${ROOTFS_DIR} | wc -l` + 128))
# make fs
[ -f ${IMG_FILE} ] && rm -f ${IMG_FILE}
set +e
MKE2FS_CONFIG="${TOP}/tools/mke2fs.conf" ${MKFS} -N ${INODE_SIZE} ${MKFS_OPTS} -d ${ROOTFS_DIR} ${IMG_FILE} ${IMG_BLK} &
MKFS_PID=$!
wait $MKFS_PID
RET=$?
set -e
else
IMG_BLK=$((${IMG_SIZE} / 4096))
INODE_SIZE=$((`find ${ROOTFS_DIR} | wc -l` + 128))
[ -f ${IMG_FILE} ] && rm -f ${IMG_FILE}
set +e
MKE2FS_CONFIG="${TOP}/tools/mke2fs.conf" ${MKFS} -N ${INODE_SIZE} ${MKFS_OPTS} -d ${ROOTFS_DIR} ${IMG_FILE} ${IMG_BLK} &
MKFS_PID=$!
wait $MKFS_PID
RET=$?
set -e
fi
if [ $RET -ne 0 ]; then
oom_log=$(dmesg | tail -n 50 | grep -i 'killed process')
if echo "$oom_log" | grep -q "Killed process ${MKFS_PID}"; then
echo "Error: failed to generate rootfs.img, mke2fs was killed by oom-killer, please ensure that there is sufficient system memory to execute this program."
else
echo "Error: failed to generate rootfs.img, mke2fs failed with exit code ${RET}"
fi
exit $RET
fi
}
make_btrfs_img() {
local RET=0
local MKFS_PID=
if [ ${IMG_SIZE} -le 0 ]; then
IMG_SIZE=$(((`du -s -B64M ${ROOTFS_DIR} | cut -f1` + 3) * 1024 * 1024 * 64))
[ -f ${IMG_FILE} ] && rm -f ${IMG_FILE}
fi
truncate -s ${IMG_SIZE} ${IMG_FILE}
set +e
mkfs.btrfs -L rootfs ${IMG_FILE}
RET=$?
set -e
if [ $RET -ne 0 ]; then
echo "Error: failed to generate rootfs.img, mkfs.btrfs failed with exit code ${RET}"
exit $RET
fi
TMPDIR=$(mktemp -d)
mount -o loop ${IMG_FILE} ${TMPDIR}
(cd ${ROOTFS_DIR} && {
case ${TARGET_OS} in
friendlywrt* | buildroot*)
# set default uid/gid to 0
tar --numeric-owner -cvpf - * 2>/dev/null | tar --owner=0 --group=0 --numeric-owner --numeric-owner -xpf - -C ${TMPDIR}
RET=$?
;;
*)
tar --same-owner --numeric-owner -cvpf - * 2>/dev/null | tar --same-owner --numeric-owner -xpf - -C ${TMPDIR}
RET=$?
;;
esac
})
umount ${TMPDIR}
if [ $RET -ne 0 ]; then
echo "Error: failed to copy files to rootfs.img"
exit $RET
fi
}
if [ "${FS_TYPE}" = "ext4" ]; then
make_ext4_img
if [ ${TARGET_OS} != "eflasher" ]; then
case ${TARGET_OS} in
openmediavault-*)
# disable overlayfs for openmediavault
cp ${TOP}/prebuilt/parameter-plain.txt ${TOP}/${TARGET_OS}/parameter.txt
;;
*)
${TOP}/tools/generate-partmap-txt.sh ${IMG_SIZE} ${TARGET_OS}
;;
esac
fi
elif [ "${FS_TYPE}" = "btrfs" ]; then
if ! command -v mkfs.btrfs &>/dev/null; then
apt-get install btrfs-progs
fi
make_btrfs_img
if [ ${TARGET_OS} != "eflasher" ]; then
# disable overlayfs for btrfs
cp ${TOP}/prebuilt/parameter-plain.txt ${TOP}/${TARGET_OS}/parameter.txt
# The difference between dtbo-plain.img and dtbo.img is that
# dtbo-plain.img does not use overlayfs
# and does not specify the data= parameter in the boot arguments.
# Additionally, the file system type is set to auto-detect instead of being fixed to ext4.
cp ${TOP}/prebuilt/dtbo-plain.img ${TOP}/${TARGET_OS}/dtbo.img
fi
else
echo "unknow FS_TYPE: ${FS_TYPE}."
exit 1
fi
echo "generating ${IMG_FILE} done."
echo 0