-
-
Notifications
You must be signed in to change notification settings - Fork 322
/
Copy pathbuild-image.sh
executable file
·213 lines (162 loc) · 5.55 KB
/
build-image.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
213
#!/bin/bash
set -eE
trap 'echo Error: in $0 on line $LINENO' ERR
cleanup_loopdev() {
local loop="$1"
sync --file-system
sync
sleep 1
if [ -b "${loop}" ]; then
for part in "${loop}"p*; do
if mnt=$(findmnt -n -o target -S "$part"); then
umount "${mnt}"
fi
done
losetup -d "${loop}"
fi
}
wait_loopdev() {
local loop="$1"
local seconds="$2"
until test $((seconds--)) -eq 0 -o -b "${loop}"; do sleep 1; done
((++seconds))
ls -l "${loop}" &> /dev/null
}
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: $0 filename.rootfs.tar"
exit 1
fi
rootfs="$(readlink -f "$1")"
if [[ "$(basename "${rootfs}")" != *".rootfs.tar" || ! -e "${rootfs}" ]]; then
echo "Error: $(basename "${rootfs}") must be a rootfs tarfile"
exit 1
fi
cd "$(dirname -- "$(readlink -f -- "$0")")" && cd ..
mkdir -p images build && cd build
if [[ -z ${BOARD} ]]; then
echo "Error: BOARD is not set"
exit 1
fi
# Create an empty disk image
img="../images/$(basename "${rootfs}" .rootfs.tar)${KVER}.img"
size="$(( $(wc -c < "${rootfs}" ) / 1024 / 1024 ))"
truncate -s "$(( size + 2048 ))M" "${img}"
# Create loop device for disk image
loop="$(losetup -f)"
losetup -P "${loop}" "${img}"
disk="${loop}"
# Cleanup loopdev on early exit
trap 'cleanup_loopdev ${loop}' EXIT
# Ensure disk is not mounted
mount_point=/tmp/mnt
umount "${disk}"* 2> /dev/null || true
umount ${mount_point}/* 2> /dev/null || true
mkdir -p ${mount_point}
if [ -z "${img##*server*}" ]; then
# Setup partition table
dd if=/dev/zero of="${disk}" count=4096 bs=512
parted --script "${disk}" \
mklabel gpt \
mkpart primary fat32 16MiB 20MiB \
mkpart primary ext4 20MiB 100%
# Create partitions
{
echo "t"
echo "1"
echo "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
echo "t"
echo "2"
echo "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
echo "w"
} | fdisk "${disk}" &> /dev/null || true
partprobe "${disk}"
partition_char="$(if [[ ${disk: -1} == [0-9] ]]; then echo p; fi)"
sleep 1
wait_loopdev "${disk}${partition_char}2" 60 || {
echo "Failure to create ${disk}${partition_char}1 in time"
exit 1
}
sleep 1
wait_loopdev "${disk}${partition_char}1" 60 || {
echo "Failure to create ${disk}${partition_char}1 in time"
exit 1
}
sleep 1
# Generate random uuid for bootfs
boot_uuid=$(uuidgen | head -c8)
# Generate random uuid for rootfs
root_uuid=$(uuidgen)
# Create filesystems on partitions
mkfs.vfat -i "${boot_uuid}" -F32 -n CIDATA "${disk}${partition_char}1"
dd if=/dev/zero of="${disk}${partition_char}2" bs=1KB count=10 > /dev/null
mkfs.ext4 -U "${root_uuid}" -L cloudimg-rootfs "${disk}${partition_char}2"
# Mount partitions
mkdir -p ${mount_point}/{system-boot,writable}
mount "${disk}${partition_char}1" ${mount_point}/system-boot
mount "${disk}${partition_char}2" ${mount_point}/writable
# Cloud init config for server image
cp ../overlay/boot/firmware/{meta-data,user-data,network-config} ${mount_point}/system-boot
else
# Setup partition table
dd if=/dev/zero of="${disk}" count=4096 bs=512
parted --script "${disk}" \
mklabel gpt \
mkpart primary ext4 16MiB 100%
# Create partitions
{
echo "t"
echo "1"
echo "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
echo "w"
} | fdisk "${disk}" &> /dev/null || true
partprobe "${disk}"
partition_char="$(if [[ ${disk: -1} == [0-9] ]]; then echo p; fi)"
sleep 1
wait_loopdev "${disk}${partition_char}1" 60 || {
echo "Failure to create ${disk}${partition_char}1 in time"
exit 1
}
sleep 1
# Generate random uuid for rootfs
root_uuid=$(uuidgen)
# Create filesystems on partitions
dd if=/dev/zero of="${disk}${partition_char}1" bs=1KB count=10 > /dev/null
mkfs.ext4 -U "${root_uuid}" -L desktop-rootfs "${disk}${partition_char}1"
# Mount partitions
mkdir -p ${mount_point}/writable
mount "${disk}${partition_char}1" ${mount_point}/writable
fi
# Copy the rootfs to root partition
tar -xpf "${rootfs}" -C ${mount_point}/writable
# Create fstab entries
echo "# <file system> <mount point> <type> <options> <dump> <fsck>" > ${mount_point}/writable/etc/fstab
echo "UUID=${root_uuid,,} / ext4 defaults,x-systemd.growfs 0 1" >> ${mount_point}/writable/etc/fstab
# Write bootloader to disk image
if [ -f "${mount_point}/writable/usr/lib/u-boot/u-boot-rockchip.bin" ]; then
dd if="${mount_point}/writable/usr/lib/u-boot/u-boot-rockchip.bin" of="${loop}" seek=1 bs=32k conv=fsync
else
dd if="${mount_point}/writable/usr/lib/u-boot/idbloader.img" of="${loop}" seek=64 conv=notrunc
dd if="${mount_point}/writable/usr/lib/u-boot/u-boot.itb" of="${loop}" seek=16384 conv=notrunc
fi
# Run build image hook to handle board specific changes
if [[ $(type -t build_image_hook__"${BOARD}") == function ]]; then
build_image_hook__"${BOARD}"
fi
chroot ${mount_point}/writable/ u-boot-update
sync --file-system
sync
# Umount partitions
umount "${disk}${partition_char}1"
umount "${disk}${partition_char}2" 2> /dev/null || true
# Remove loop device
losetup -d "${loop}"
# Exit trap is no longer needed
trap '' EXIT
echo -e "\nCompressing $(basename "${img}.xz")\n"
xz -6 --force --keep --quiet --threads=0 "${img}"
rm -f "${img}"
cd ../images && sha256sum "$(basename "${img}.xz")" > "$(basename "${img}.xz.sha256")"