diff --git a/ovmf-vars-generator b/ovmf-vars-generator index 04bcda7..594246b 100755 --- a/ovmf-vars-generator +++ b/ovmf-vars-generator @@ -20,6 +20,7 @@ import tempfile import shutil import string import subprocess +import select def strip_special(line): @@ -27,12 +28,24 @@ def strip_special(line): def generate_qemu_cmd(args, readonly, *extra_args): - if args.disable_smm: + is_x86 = True + arch_args = [] + if os.path.basename(args.qemu_binary) == 'qemu-system-aarch64' or args.arch == 'aarch64': + machinetype = 'virt' + arch_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: + arch_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')]) + if args.oem_string is None: oemstrings = [] else: @@ -50,18 +63,14 @@ def generate_qemu_cmd(args, readonly, *extra_args): '-no-user-config', '-nodefaults', '-m', '768', - '-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'] + oemstrings + list(extra_args) + '-serial', 'stdio'] + oemstrings + arch_args + list(extra_args) def download(url, target, suffix, no_download): @@ -95,17 +104,17 @@ 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') # Wait until the UEFI shell starts (first line is printed) + pollobj = select.poll() + pollobj.register(p.stdout, select.POLLIN) + read = p.stdout.readline() if b'char device redirected' in read: read = p.stdout.readline() @@ -116,25 +125,46 @@ def enroll_keys(args): if args.print_output: 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') + # Send the press enter for the default boot (uefi shell) + p.stdin.write(b'\r\n') p.stdin.flush() + + 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 and len(read): print('OUT: %s' % strip_special(read), end='') print() - if b'info: success' in read: + if b'seconds to skip' in read: + p.stdin.write(b'\r\n') + p.stdin.flush() + elif b'info: success' in read: break elif b'Reset with ' in read: break + elif 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 + 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.flush() + p.wait() if args.print_output: print(strip_special(p.stdout.read()), end='') @@ -182,6 +212,8 @@ def test_keys(args): def parse_args(): parser = argparse.ArgumentParser() + parser.add_argument('--arch', '-a', help='Architecture hint', + choices=['x86_64', 'aarch64']) parser.add_argument('output', help='Filename for output vars file') parser.add_argument('--out-temp', help=argparse.SUPPRESS) parser.add_argument('--force', help='Overwrite existing output file',