]> git.proxmox.com Git - mirror_qemu.git/blame - scripts/qemu-binfmt-conf.sh
qemu-binfmt-conf.sh: add persistent (F) flags
[mirror_qemu.git] / scripts / qemu-binfmt-conf.sh
CommitLineData
08785f48 1#!/bin/sh
947aeab3 2# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA/Xtensa/microblaze
e4d966cc 3# program execution by the kernel
08785f48 4
bfe69cc8 5qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
3bef0451 6mips mipsel mipsn32 mipsn32el mips64 mips64el \
947aeab3 7sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb microblaze microblazeel"
3bef0451
LV
8
9i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
daf238dc 10i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
3bef0451
LV
11i386_family=i386
12
13i486_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'
daf238dc 14i486_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
3bef0451
LV
15i486_family=i386
16
17alpha_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
daf238dc 18alpha_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
3bef0451
LV
19alpha_family=alpha
20
21arm_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
22arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
23arm_family=arm
24
25armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
26armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
2ced93ee 27armeb_family=armeb
3bef0451
LV
28
29sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
daf238dc 30sparc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
3bef0451
LV
31sparc_family=sparc
32
33sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
daf238dc 34sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
3bef0451
LV
35sparc32plus_family=sparc
36
37ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
38ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
39ppc_family=ppc
40
41ppc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
42ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
43ppc64_family=ppc
44
45ppc64le_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
46ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
47ppc64le_family=ppcle
48
49m68k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
daf238dc 50m68k_mask='\xff\xff\xff\xff\xff\xff\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
3bef0451
LV
51m68k_family=m68k
52
53# FIXME: We could use the other endianness on a MIPS host.
54
55mips_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
56mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
57mips_family=mips
58
59mipsel_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
60mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
61mipsel_family=mips
62
63mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
64mipsn32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
65mipsn32_family=mips
66
67mipsn32el_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
68mipsn32el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
69mipsn32el_family=mips
70
71mips64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
72mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
73mips64_family=mips
74
75mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
76mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
77mips64el_family=mips
78
79sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
daf238dc 80sh4_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
3bef0451
LV
81sh4_family=sh4
82
83sh4eb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
daf238dc 84sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
3bef0451
LV
85sh4eb_family=sh4
86
87s390x_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
daf238dc 88s390x_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
3bef0451
LV
89s390x_family=s390x
90
91aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
92aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
93aarch64_family=arm
94
f772f212
MW
95aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
96aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
2ced93ee 97aarch64_be_family=armeb
f772f212 98
e4d966cc
LV
99hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
100hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
101hppa_family=hppa
102
25fa194b
MC
103riscv32_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00'
104riscv32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
105riscv32_family=riscv
106
107riscv64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00'
108riscv64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
109riscv64_family=riscv
110
d4090306
MF
111xtensa_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x5e\x00'
112xtensa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
113xtensa_family=xtensa
114
115xtensaeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x5e'
116xtensaeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
117xtensaeb_family=xtensaeb
118
947aeab3
LV
119microblaze_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xba\xab'
120microblaze_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
121microblaze_family=microblaze
122
123microblazeel_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xab\xba'
124microblazeel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
125microblazeel_family=microblazeel
126
3bef0451
LV
127qemu_get_family() {
128 cpu=${HOST_ARCH:-$(uname -m)}
129 case "$cpu" in
130 amd64|i386|i486|i586|i686|i86pc|BePC|x86_64)
131 echo "i386"
132 ;;
133 mips*)
134 echo "mips"
135 ;;
136 "Power Macintosh"|ppc64|powerpc|ppc)
137 echo "ppc"
138 ;;
139 ppc64el|ppc64le)
140 echo "ppcle"
141 ;;
2ced93ee 142 arm|armel|armhf|arm64|armv[4-9]*l|aarch64)
3bef0451
LV
143 echo "arm"
144 ;;
2ced93ee
MW
145 armeb|armv[4-9]*b|aarch64_be)
146 echo "armeb"
147 ;;
3bef0451
LV
148 sparc*)
149 echo "sparc"
150 ;;
25fa194b
MC
151 riscv*)
152 echo "riscv"
153 ;;
3bef0451
LV
154 *)
155 echo "$cpu"
156 ;;
157 esac
158}
159
160usage() {
161 cat <<EOF
162Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
163 [--help][--credential yes|no][--exportdir PATH]
01ecd22a 164 [--persistent yes|no]
3bef0451
LV
165
166 Configure binfmt_misc to use qemu interpreter
167
168 --help: display this usage
169 --qemu-path: set path to qemu interpreter ($QEMU_PATH)
170 --debian: don't write into /proc,
171 instead generate update-binfmts templates
172 --systemd: don't write into /proc,
173 instead generate file for systemd-binfmt.service
3ff48453
LV
174 for the given CPU. If CPU is "ALL", generate a
175 file for all known cpus
3bef0451
LV
176 --exportdir: define where to write configuration files
177 (default: $SYSTEMDDIR or $DEBIANDIR)
178 --credential: if yes, credential and security tokens are
179 calculated according to the binary to interpret
01ecd22a
LV
180 --persistent: if yes, the interpreter is loaded when binfmt is
181 configured and remains in memory. All future uses
182 are cloned from the open file.
3bef0451
LV
183
184 To import templates with update-binfmts, use :
185
186 sudo update-binfmts --importdir ${EXPORTDIR:-$DEBIANDIR} --import qemu-CPU
187
188 To remove interpreter, use :
189
190 sudo update-binfmts --package qemu-CPU --remove qemu-CPU $QEMU_PATH
191
192 With systemd, binfmt files are loaded by systemd-binfmt.service
193
194 The environment variable HOST_ARCH allows to override 'uname' to generate
195 configuration files for a different architecture than the current one.
196
197 where CPU is one of:
198
199 $qemu_target_list
200
201EOF
202}
203
204qemu_check_access() {
205 if [ ! -w "$1" ] ; then
206 echo "ERROR: cannot write to $1" 1>&2
207 exit 1
208 fi
209}
210
211qemu_check_bintfmt_misc() {
212 # load the binfmt_misc module
213 if [ ! -d /proc/sys/fs/binfmt_misc ]; then
214 if ! /sbin/modprobe binfmt_misc ; then
215 exit 1
216 fi
217 fi
218 if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
219 if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
220 exit 1
221 fi
222 fi
223
224 qemu_check_access /proc/sys/fs/binfmt_misc/register
225}
226
227installed_dpkg() {
228 dpkg --status "$1" > /dev/null 2>&1
229}
230
231qemu_check_debian() {
232 if [ ! -e /etc/debian_version ] ; then
233 echo "WARNING: your system is not a Debian based distro" 1>&2
234 elif ! installed_dpkg binfmt-support ; then
235 echo "WARNING: package binfmt-support is needed" 1>&2
236 fi
237 qemu_check_access "$EXPORTDIR"
238}
239
240qemu_check_systemd() {
241 if ! systemctl -q is-enabled systemd-binfmt.service ; then
242 echo "WARNING: systemd-binfmt.service is missing or disabled" 1>&2
243 fi
244 qemu_check_access "$EXPORTDIR"
245}
246
247qemu_generate_register() {
70a77984
LV
248 flags=""
249 if [ "$CREDENTIAL" = "yes" ] ; then
250 flags="OC"
251 fi
01ecd22a
LV
252 if [ "$PERSISTENT" = "yes" ] ; then
253 flags="${flags}F"
254 fi
70a77984
LV
255
256 echo ":qemu-$cpu:M::$magic:$mask:$qemu:$flags"
3bef0451
LV
257}
258
259qemu_register_interpreter() {
260 echo "Setting $qemu as binfmt interpreter for $cpu"
261 qemu_generate_register > /proc/sys/fs/binfmt_misc/register
262}
263
264qemu_generate_systemd() {
265 echo "Setting $qemu as binfmt interpreter for $cpu for systemd-binfmt.service"
266 qemu_generate_register > "$EXPORTDIR/qemu-$cpu.conf"
267}
268
269qemu_generate_debian() {
270 cat > "$EXPORTDIR/qemu-$cpu" <<EOF
271package qemu-$cpu
272interpreter $qemu
273magic $magic
274mask $mask
70a77984 275credential $CREDENTIAL
3bef0451 276EOF
3bef0451
LV
277}
278
279qemu_set_binfmts() {
280 # probe cpu type
281 host_family=$(qemu_get_family)
282
283 # register the interpreter for each cpu except for the native one
284
285 for cpu in ${qemu_target_list} ; do
286 magic=$(eval echo \$${cpu}_magic)
287 mask=$(eval echo \$${cpu}_mask)
288 family=$(eval echo \$${cpu}_family)
289
290 if [ "$magic" = "" ] || [ "$mask" = "" ] || [ "$family" = "" ] ; then
291 echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
292 continue
293 fi
294
295 qemu="$QEMU_PATH/qemu-$cpu"
296 if [ "$cpu" = "i486" ] ; then
297 qemu="$QEMU_PATH/qemu-i386"
298 fi
299
300 if [ "$host_family" != "$family" ] ; then
301 $BINFMT_SET
302 fi
303 done
304}
305
306CHECK=qemu_check_bintfmt_misc
307BINFMT_SET=qemu_register_interpreter
308
309SYSTEMDDIR="/etc/binfmt.d"
310DEBIANDIR="/usr/share/binfmts"
311
312QEMU_PATH=/usr/local/bin
70a77984 313CREDENTIAL=no
01ecd22a 314PERSISTENT=no
3bef0451 315
01ecd22a 316options=$(getopt -o ds:Q:e:hc:p: -l debian,systemd:,qemu-path:,exportdir:,help,credential:,persistent: -- "$@")
3bef0451
LV
317eval set -- "$options"
318
319while true ; do
320 case "$1" in
321 -d|--debian)
322 CHECK=qemu_check_debian
323 BINFMT_SET=qemu_generate_debian
324 EXPORTDIR=${EXPORTDIR:-$DEBIANDIR}
325 ;;
326 -s|--systemd)
327 CHECK=qemu_check_systemd
328 BINFMT_SET=qemu_generate_systemd
329 EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR}
330 shift
331 # check given cpu is in the supported CPU list
3ff48453
LV
332 if [ "$1" != "ALL" ] ; then
333 for cpu in ${qemu_target_list} ; do
334 if [ "$cpu" = "$1" ] ; then
335 break
336 fi
337 done
338
6f75023a 339 if [ "$cpu" = "$1" ] ; then
3ff48453
LV
340 qemu_target_list="$1"
341 else
342 echo "ERROR: unknown CPU \"$1\"" 1>&2
343 usage
344 exit 1
3bef0451 345 fi
3bef0451
LV
346 fi
347 ;;
348 -Q|--qemu-path)
349 shift
350 QEMU_PATH="$1"
351 ;;
352 -e|--exportdir)
353 shift
354 EXPORTDIR="$1"
355 ;;
356 -h|--help)
357 usage
358 exit 1
359 ;;
360 -c|--credential)
361 shift
70a77984 362 CREDENTIAL="$1"
3bef0451 363 ;;
01ecd22a
LV
364 -p|--persistent)
365 shift
366 PERSISTENT="$1"
367 ;;
3bef0451
LV
368 *)
369 break
370 ;;
371 esac
372 shift
373done
374
375$CHECK
376qemu_set_binfmts