diff --git a/ovmf-vars-generator b/ovmf-vars-generator index d63e4cf..09c987a 100755 --- a/ovmf-vars-generator +++ b/ovmf-vars-generator @@ -20,18 +20,29 @@ 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, @@ -39,18 +50,14 @@ def generate_qemu_cmd(args, readonly, *extra_args): '-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): @@ -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: @@ -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='')