Skip to content

Commit 112403c

Browse files
committed
ixbin: Add util script to update image contents
[skip-ci]
1 parent a990e55 commit 112403c

File tree

1 file changed

+269
-0
lines changed

1 file changed

+269
-0
lines changed

utils/ixbin

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
usage()
6+
{
7+
cat <<EOF
8+
usage: $0 COMMAND [ARGS...]
9+
10+
Update contents of Infix images
11+
12+
Commands:
13+
14+
unpack PKG KEY-DIR DIR
15+
16+
Unpack the RAUC bundle PKG and the root filesystem contained in
17+
it, using the keys stored in KEY-DIR, and store the results in
18+
DIR.
19+
20+
pack DIR [KEY-DIR] PKG
21+
22+
Repackage the (possibly modified) root filesystem in DIR, updating
23+
all signatures as necessary using the keys stored in KEY-DIR (or
24+
the keys used to unpack the bundle, if not specified) and store
25+
the resulting bundle in PKG.
26+
27+
exec DIR COMMAND [ARGS...]
28+
29+
Run COMMAND, possibly with ARGS, from the root of the filesystem
30+
in DIR, inside of a fakeroot context that allows otherwise
31+
privileged operations such as ownership modifications.
32+
33+
help
34+
35+
Show this message and exit.
36+
37+
Key directories:
38+
39+
KEY-DIR arguments must reference a directory that contains the
40+
public/private keypair used to verify/sign an image. Most commonly,
41+
board/common/signing-keys/development from the Infix source tree is
42+
used to validate the input image.
43+
44+
Example:
45+
46+
Include a custom file inside a prebuilt Infix image, assign it to
47+
the UID/GID 1337; and package up the results, signing it with the
48+
same developer key that was used to create it:
49+
50+
ixbin unpack infix-aarch64.pkg ~/infix/board/common/signing-keys/development tmp
51+
cp VBRUN300.DLL tmp/rootfs/lib/
52+
ixbin exec tmp chown 1337:1337 lib/VBRUN300.DLL
53+
ixbin pack tmp infix-vb3-aarch64.pkg
54+
55+
EOF
56+
}
57+
58+
msg()
59+
{
60+
printf "\e[37;44mixbin: %-80s\e[0m\n" "$*"
61+
}
62+
63+
err()
64+
{
65+
printf "\e[37;41mixbin: ERROR: %-73s\e[0m\n" "$*" >&2
66+
}
67+
68+
die()
69+
{
70+
err "$*"
71+
exit 1
72+
}
73+
74+
ensuredeps()
75+
{
76+
local DEPS="fakeroot mksquashfs unsquashfs awk env mkimage truncate dtc fdtget rauc"
77+
local missing=
78+
79+
for dep in $DEPS; do
80+
command -v $dep >/dev/null && continue
81+
missing="$missing $dep"
82+
done
83+
84+
if [ -n "$missing" ]; then
85+
die "Missing dependencies:$missing"
86+
fi
87+
}
88+
89+
squnpack()
90+
{
91+
local sq="$WORKDIR"/pkg/rootfs.img
92+
93+
# Capture the original compression algo and block size for when we
94+
# resquash it later on.
95+
unsquashfs -s "$sq" | awk '
96+
/^Compression/ { printf(" -comp %s", $2); }
97+
/^Block size/ { printf(" -b %s", $3); }
98+
' >"$WORKDIR"/mksquash-opts
99+
100+
$FAKEROOT unsquashfs -d "$WORKDIR"/rootfs "$sq"
101+
}
102+
103+
sqexec()
104+
{
105+
$FAKEROOT env -C "$WORKDIR"/rootfs "$@"
106+
}
107+
108+
sqpack()
109+
{
110+
$FAKEROOT mksquashfs "$WORKDIR"/rootfs "$WORKDIR"/pkg/rootfs.img \
111+
$(cat "$WORKDIR"/mksquash-opts) -noappend "$@"
112+
}
113+
114+
sqsign()
115+
{
116+
local its="$1"
117+
local keys="$2"
118+
local hsize="$3"
119+
local out="$4"
120+
121+
mkimage -E -p "$hsize" -B "$hsize" -k "$keys" -f "$its" "$WORKDIR"/sign.itb
122+
truncate -s $(($hsize)) "$WORKDIR"/sign.itb
123+
mv "$WORKDIR"/sign.itb "$out"
124+
}
125+
126+
sqresign()
127+
{
128+
local keys="$1"
129+
local sq="$WORKDIR"/pkg/rootfs.img
130+
local itbh="$WORKDIR"/pkg/rootfs.itbh
131+
132+
signsize=$(printf '0x%x' $(fdtget "$itbh" /images/rootfs data-position))
133+
134+
dtc -I dtb -O dts "$itbh" | awk -v sq="$sq" '
135+
/timestamp =/ || /data-\w+ =/ || /signer-\w+ =/ || /value =/{
136+
/* Remove old signature */
137+
next;
138+
}
139+
140+
/compression = "none"/ {
141+
/* Splice in reference to the squash */
142+
print;
143+
sub("compression", "data");
144+
sub("\"none\"", sprintf("/incbin/(\"%s\")", sq));
145+
print;
146+
next;
147+
}
148+
149+
{
150+
/* Keep the rest as-is */
151+
print;
152+
};
153+
' >"$WORKDIR"/resign.its
154+
155+
sqsign "$WORKDIR"/resign.its "$keys" "$signsize" "$itbh"
156+
}
157+
158+
unpack()
159+
{
160+
local pkg="$1"
161+
local keys="$2"
162+
WORKDIR=$(readlink -f "$3")
163+
164+
case "$#" in
165+
3)
166+
;;
167+
*)
168+
echo "Usage: ixbin unpack PKG KEYS DIR" >&2
169+
exit 1
170+
esac
171+
172+
local crt=$(ls "$keys"/*.crt | head -n1)
173+
[ -r "$crt" ] || die "No public key found in $keys"
174+
175+
msg "Setting up working directory"
176+
mkdir -p "$WORKDIR"
177+
cp -a "$keys" "$WORKDIR"/in-keys
178+
179+
touch "$WORKDIR"/fakeroot-state
180+
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
181+
182+
msg "Unpacking RAUC bundle"
183+
rauc --keyring="$crt" extract "$pkg" "$WORKDIR"/pkg
184+
msg "Unpacking Squash filesystem"
185+
squnpack
186+
msg "OK, $WORKDIR/rootfs can now be modified"
187+
}
188+
189+
run()
190+
{
191+
WORKDIR=$(readlink -f "$1")
192+
shift
193+
194+
[ -r "$WORKDIR"/fakeroot-state ] || \
195+
die "$WORKDIR does not contain an unpacked image"
196+
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
197+
198+
sqexec "$@"
199+
}
200+
201+
pack()
202+
{
203+
WORKDIR=$(readlink -f "$1")
204+
local keys="$2"
205+
local pkg="$3"
206+
207+
case "$#" in
208+
3)
209+
;;
210+
2)
211+
keys="$WORKDIR"/in-keys
212+
pkg="$2"
213+
;;
214+
*)
215+
echo "Usage: ixbin pack DIR [KEYS] DIR" >&2
216+
exit 1
217+
esac
218+
219+
[ -r "$WORKDIR"/fakeroot-state ] || \
220+
die "$WORKDIR does not contain an unpacked image"
221+
222+
local crt=$(ls "$keys"/*.crt | head -n1)
223+
[ -r "$crt" ] || die "No public key found in $keys"
224+
225+
local key=$(ls "$keys"/*.key | head -n1)
226+
[ -r "$crt" ] || die "No private key found in $keys"
227+
228+
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
229+
230+
msg "Packing up Squash filesystem"
231+
sqpack
232+
[ -f "$WORKDIR"/pkg/rootfs.itbh ] && {
233+
msg "Updating Squash filesystem signature"
234+
sqresign "$keys"
235+
}
236+
237+
msg "Creating RAUC bundle"
238+
rauc --keyring="$crt" --cert="$crt" --key="$key" bundle "$WORKDIR"/pkg "$pkg"
239+
msg "OK, updated bundle available in $pkg"
240+
}
241+
242+
if [ $# -lt 1 ]; then
243+
usage
244+
exit 1
245+
fi
246+
247+
cmd="$1"
248+
shift
249+
250+
case "$cmd" in
251+
unpack)
252+
ensuredeps
253+
unpack "$@"
254+
;;
255+
"exec")
256+
ensuredeps
257+
run "$@"
258+
;;
259+
pack)
260+
ensuredeps
261+
pack "$@"
262+
;;
263+
help)
264+
usage
265+
;;
266+
*)
267+
die "Unknown command \"$cmd\""
268+
;;
269+
esac

0 commit comments

Comments
 (0)