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