Skip to content

Commit

Permalink
Add aarch64 support, and more responsive qemu interaction
Browse files Browse the repository at this point in the history
The qemu commands to start a aarch64 guest vary slightly
from the x86 version. Also, as the code to run the EFI
binary in qemu tends to get hung up in the menus on
aarch64 lets make it wait for the shell prompt
before trying to start the binary.

Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
  • Loading branch information
jlinton committed Oct 26, 2018
1 parent 69cee8b commit 2e2be2b
Showing 1 changed file with 52 additions and 22 deletions.
74 changes: 52 additions & 22 deletions ovmf-vars-generator
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,44 @@ import tempfile
import shutil
import string
import subprocess

import select

def strip_special(line):
return ''.join([c for c in str(line) if c in string.printable])


def generate_qemu_cmd(args, readonly, *extra_args):
if args.disable_smm:
is_x86 = True
new_args = []
if os.path.basename(args.qemu_binary) == 'qemu-system-aarch64':
machinetype = 'virt'
new_args.extend(['-cpu', 'cortex-a57'])
is_x86 = False
elif args.disable_smm:
machinetype = 'pc'
else:
machinetype = 'q35,smm=on'
machinetype += ',accel=%s' % ('kvm' if args.enable_kvm else 'tcg')
if is_x86 == True:
new_args.extend(['-chardev', 'pty,id=charserial1',
'-device', 'isa-serial,chardev=charserial1,id=serial1',
'-global', 'driver=cfi.pflash01,property=secure,value=%s' % (
'off' if args.disable_smm else 'on')])
return [
args.qemu_binary,
'-machine', machinetype,
'-display', 'none',
'-no-user-config',
'-nodefaults',
'-m', '256',
'-smp', '2,sockets=2,cores=1,threads=1',
'-chardev', 'pty,id=charserial1',
'-device', 'isa-serial,chardev=charserial1,id=serial1',
'-global', 'driver=cfi.pflash01,property=secure,value=%s' % (
'off' if args.disable_smm else 'on'),
'-smp', '1,sockets=1,cores=1,threads=1',
'-drive',
'file=%s,if=pflash,format=raw,unit=0,readonly=on' % (
args.ovmf_binary),
'-drive',
'file=%s,if=pflash,format=raw,unit=1,readonly=%s' % (
args.out_temp, 'on' if readonly else 'off'),
'-serial', 'stdio'] + list(extra_args)
'-serial', 'stdio'] + new_args + list(extra_args)


def download(url, target, suffix, no_download):
Expand Down Expand Up @@ -84,16 +91,16 @@ def enroll_keys(args):
args,
False,
'-drive',
'file=%s,format=raw,if=none,media=cdrom,id=drive-cd1,'
'readonly=on' % args.uefi_shell_iso,
'-device',
'ide-cd,drive=drive-cd1,id=cd1,'
'bootindex=1')
'file=%s,format=raw,if=virtio,media=cdrom,id=drive-cd1,'
'readonly=on' % args.uefi_shell_iso)
p = subprocess.Popen(cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
logging.info('Performing enrollment')
pollobj = select.poll()
pollobj.register(p.stdout, select.POLLIN)

# Wait until the UEFI shell starts (first line is printed)
read = p.stdout.readline()
if b'char device redirected' in read:
Expand All @@ -102,22 +109,45 @@ def enroll_keys(args):
print(strip_special(read), end='')
print()
# Send the escape char to enter the UEFI shell early
p.stdin.write(b'\x1b')
p.stdin.flush()
# And then run the following three commands from the UEFI shell:
# change into the first file system device; install the default
# keys and certificates, and reboot
p.stdin.write(b'fs0:\r\n')
p.stdin.write(b'EnrollDefaultKeys.efi\r\n')
p.stdin.write(b'reset -s\r\n')
p.stdin.write(b'\r\n')
p.stdin.flush()
Enrolled = False
wait_timeout = 100;
while True:
read = p.stdout.readline()
poll_result = pollobj.poll(1000)
if poll_result:
# readline can get stuck in menus and other
# UI elements in uefi which don't respond
# with a CR the poll above doesn't help
# with that case.
read = p.stdout.readline()
else:
wait_timeout-=1
if wait_timeout == 0:
logging.info('Failed enrollment')
# consider something stronger here
# as we can still get stuck in the p.wait()
break;
continue
if args.print_output:
print('OUT: %s' % strip_special(read), end='')
print()
if b'seconds to skip' in read:
p.stdin.write(b'\r\n')
p.stdin.flush()
if b'info: success' in read:
break
if b'Shell>' in read:
# And then run the following three commands from the UEFI shell:
# change into the first file system device; install the default
# keys and certificates, and reboot
if Enrolled == False:
p.stdin.write(b'\r\nfs0:\r\n')
p.stdin.write(b'EnrollDefaultKeys.efi\r\n')
p.stdin.write(b'reset -s\r\n')
p.stdin.flush()
Enrolled = True;

p.wait()
if args.print_output:
print(strip_special(p.stdout.read()), end='')
Expand Down

0 comments on commit 2e2be2b

Please sign in to comment.