diff --git a/Platform/QemuBoardPkg/Script/qemu_fwu.py b/Platform/QemuBoardPkg/Script/TestCases/firmware_update.py
similarity index 79%
rename from Platform/QemuBoardPkg/Script/qemu_fwu.py
rename to Platform/QemuBoardPkg/Script/TestCases/firmware_update.py
index 043ce7c6..d7f8f12b 100644
--- a/Platform/QemuBoardPkg/Script/qemu_fwu.py
+++ b/Platform/QemuBoardPkg/Script/TestCases/firmware_update.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
-## @ qemu_fwu.py
+## @ firmware_update.py
#
-# QEMU firmware update test script
+# Test firmware update on QEMU
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,7 +14,8 @@ import struct
import signal
import subprocess
from threading import Timer
-from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
+from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
+from test_base import *
class FlashMapDesc(Structure):
@@ -75,16 +76,17 @@ def get_check_lines (bp = 0, mode = 0):
])
return lines
-def check_result (lines):
+
+def check_fwu_result (output):
ret = 0
index = 0
cycle = 1
- count = len(lines)
+ count = len(output)
for bp, mode in [(0, 0x12), (1, 0x12), (0, 0)]:
for line in get_check_lines (bp, mode):
found = False
while not found and index < count:
- if line in lines[index]:
+ if line in output[index]:
found = True
break
else:
@@ -93,7 +95,7 @@ def check_result (lines):
index += 1
continue
else:
- print ("Failed locatting '%s' in cycke %d !" % (line, cycle))
+ print ("Failed locating '%s' in cycle %d !" % (line, cycle))
ret = -1
break
if ret < 0:
@@ -227,46 +229,6 @@ def handle_ts(bios_image, set_ts_val=0):
return fwu_flg
-def run_process (cmd, timeout = 0):
- def timerout (p):
- timer.cancel()
- os.kill(p.pid, signal.SIGTERM)
-
- lines = []
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)
- if timeout:
- timer = Timer(timeout, timerout, args=[p])
- timer.start()
- for line in iter(p.stdout.readline, ''):
- line = line.rstrip()
- print (line)
- lines.append (line)
- p.stdout.close()
- retcode = p.wait()
- if timeout:
- timer.cancel()
-
- return lines
-
-
-def run_qemu(bios_img, fwu_path, fwu_mode=False, timeout=0):
- if os.name == 'nt':
- path = r"C:\Program Files\qemu\qemu-system-x86_64"
- else:
- path = r"qemu-system-x86_64"
- cmd_list = [
- path, "-nographic", "-machine", "q35,accel=tcg",
- "-serial", "mon:stdio",
- "-m", "256M", "-drive",
- "id=mydrive,if=none,format=raw,file=fat:rw:%s" % fwu_path, "-device",
- "ide-hd,drive=mydrive", "-boot", "order=d%s" % ('an' if fwu_mode else ''),
- "-no-reboot", "-drive", "file=%s,if=pflash,format=raw" % bios_img
- ]
-
- lines = run_process (cmd_list, timeout)
- return lines
-
-
def usage():
print("usage:\n python %s bios_image fwu_cap_dir\n" % sys.argv[0])
print(" bios_image : QEMU Slim Bootloader firmware image.")
@@ -290,6 +252,22 @@ def main():
print("Firmware update for Slim BootLoader")
+ # create FWU capsule
+ create_dirs ([fwu_dir])
+ cmd = [ sys.executable,
+ 'BootloaderCorePkg/Tools/GenCapsuleFirmware.py',
+ '-p', 'BIOS', bios_img,
+ '-k', 'BootloaderCorePkg/Tools/Keys/TestSigningPrivateKey.pem',
+ '-o', '%s/FwuImage.bin' % fwu_dir
+ ]
+ try:
+ output = subprocess.run (cmd)
+ output.check_returncode()
+ except subprocess.CalledProcessError:
+ print ('Failed to generate QEMU SlimBootloader capsule image !')
+ return -3
+
+ # run FWU
output = []
fwu_mode = 2
lines = run_qemu(bios_img, fwu_dir, True if fwu_mode != 0 else False)
@@ -309,7 +287,7 @@ def main():
output.extend(lines)
# check test result
- ret = check_result (output)
+ ret = check_fwu_result (output)
print ('\nQEMU FWU test %s !\n' % ('PASSED' if ret == 0 else 'FAILED'))
diff --git a/Platform/QemuBoardPkg/Script/TestCases/linux_boot.py b/Platform/QemuBoardPkg/Script/TestCases/linux_boot.py
new file mode 100644
index 00000000..b32df0b6
--- /dev/null
+++ b/Platform/QemuBoardPkg/Script/TestCases/linux_boot.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+## @ linux_boot.py
+#
+# Test boot linux on QEMU
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+import os
+import sys
+import struct
+from ctypes import Structure, c_char, c_uint32, c_uint8, c_uint64, c_uint16, sizeof, ARRAY
+from test_base import *
+
+def get_check_lines ():
+ lines = [
+ "===== Intel Slim Bootloader STAGE1A =====",
+ "===== Intel Slim Bootloader STAGE1B =====",
+ "===== Intel Slim Bootloader STAGE2 ======",
+ "Jump to payload",
+ "Starting Kernel ...",
+ "Linux version",
+ "Freeing unused kernel image",
+ 'Welcome to "Minimal Linux"',
+ ]
+ return lines
+
+def usage():
+ print("usage:\n python %s bios_image os_image_dir\n" % sys.argv[0])
+ print(" bios_image : QEMU Slim Bootloader firmware image.")
+ print(" This image can be generated through the normal Slim Bootloader build process.")
+ print(" os_image_dir: Directory containing bootable OS image.")
+ print(" This image can be generated using GenContainer.py tool.")
+ print("")
+
+
+def main():
+ if sys.version_info.major < 3:
+ print ("This script needs Python3 !")
+ return -1
+
+ if len(sys.argv) != 3:
+ usage()
+ return -2
+
+ bios_img = sys.argv[1]
+ os_dir = sys.argv[2]
+
+ print("Linux boot test for Slim BootLoader")
+
+ # download and unzip OS image
+ tmp_dir = os.path.dirname(os_dir) + '/temp'
+ create_dirs ([tmp_dir, os_dir])
+ local_file = tmp_dir + '/QemuLinux.zip'
+ download_url (
+ 'https://github.com/slimbootloader/slimbootloader/files/4463548/QemuLinux.zip',
+ local_file
+ )
+ unzip_file (local_file, os_dir)
+
+ # run QEMU boot with timeout
+ output = []
+ lines = run_qemu(bios_img, os_dir, timeout = 8)
+ output.extend(lines)
+
+ # check test result
+ ret = check_result (output, get_check_lines())
+
+ print ('\nLinux Boot test %s !\n' % ('PASSED' if ret == 0 else 'FAILED'))
+
+ return ret
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/Platform/QemuBoardPkg/Script/TestCases/test_base.py b/Platform/QemuBoardPkg/Script/TestCases/test_base.py
new file mode 100644
index 00000000..b61ec464
--- /dev/null
+++ b/Platform/QemuBoardPkg/Script/TestCases/test_base.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+## @ test_base.py
+#
+# Provide common functions for test script
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+import os
+import sys
+import struct
+import signal
+import subprocess
+import zipfile
+import urllib.request
+from threading import Timer
+
+
+def unzip_file (zip_file, tgt_dir):
+ with zipfile.ZipFile(zip_file, 'r') as zip_ref:
+ zip_ref.extractall (tgt_dir)
+
+
+def download_url (url, save_path):
+ urllib.request.urlretrieve (url, save_path)
+
+
+def create_dirs (dirs):
+ # create dirs
+ for dir_name in dirs:
+ if not os.path.exists(dir_name):
+ os.mkdir (dir_name)
+
+
+def run_qemu (bios_img, fwu_path, fwu_mode=False, timeout=0):
+ if os.name == 'nt':
+ path = r"C:\Program Files\qemu\qemu-system-x86_64"
+ else:
+ path = r"qemu-system-x86_64"
+ cmd_list = [
+ path, "-nographic", "-machine", "q35,accel=tcg",
+ "-cpu", "max", "-serial", "mon:stdio",
+ "-m", "256M", "-drive",
+ "id=mydrive,if=none,format=raw,file=fat:rw:%s" % fwu_path, "-device",
+ "ide-hd,drive=mydrive", "-boot", "order=d%s" % ('an' if fwu_mode else ''),
+ "-no-reboot", "-drive", "file=%s,if=pflash,format=raw" % bios_img
+ ]
+
+ lines = run_process (cmd_list, timeout)
+ return lines
+
+
+def run_process (cmd, timeout = 0):
+ def timerout (p):
+ timer.cancel()
+ os.kill(p.pid, signal.SIGTERM)
+
+ lines = []
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)
+ if timeout:
+ timer = Timer(timeout, timerout, args=[p])
+ timer.start()
+ for line in iter(p.stdout.readline, ''):
+ line = line.rstrip()
+ print (line)
+ lines.append (line)
+ p.stdout.close()
+ retcode = p.wait()
+ if timeout:
+ timer.cancel()
+
+ return lines
+
+
+def check_result (output, check_lines):
+ ret = 0
+ index = 0
+ count = len (output)
+ for line in check_lines:
+ found = False
+ while not found and index < count:
+ if line in output[index]:
+ found = True
+ break
+ else:
+ index += 1
+ if found:
+ index += 1
+ continue
+ else:
+ print ("Failed locating '%s' !" % (line))
+ ret = -1
+ break
+ return ret
diff --git a/Platform/QemuBoardPkg/Script/qemu_test.py b/Platform/QemuBoardPkg/Script/qemu_test.py
index f4cee1f2..f00efae2 100644
--- a/Platform/QemuBoardPkg/Script/qemu_test.py
+++ b/Platform/QemuBoardPkg/Script/qemu_test.py
@@ -12,48 +12,40 @@ import sys
import shutil
import subprocess
+
def main():
sbl_img = 'Outputs/qemu/SlimBootloader.bin'
tst_img = 'Outputs/qemu/SblFwuTest.bin'
- fwu_dir = 'Outputs/qemu/temp'
+ tmp_dir = 'Outputs/qemu/temp'
+ fwu_dir = 'Outputs/qemu/fwu'
+ img_dir = 'Outputs/qemu/image'
# check QEMU SlimBootloader.bin
if not os.path.exists(sbl_img):
print ('Could not find QEMU SlimBootloader.bin image !')
return -1
- # copy a test image so that the original image will not change
- shutil.copyfile (sbl_img, tst_img)
+ # run test cases
+ test_cases = [
+ ('firmware_update.py', [tst_img, fwu_dir]),
+ ('linux_boot.py' , [tst_img, img_dir])
+ ]
- # generate QEMU FWU capsule
- if not os.path.exists(fwu_dir):
- os.mkdir (fwu_dir)
- cmd = [ sys.executable,
- 'BootloaderCorePkg/Tools/GenCapsuleFirmware.py',
- '-p', 'BIOS', tst_img,
- '-k', 'BootloaderCorePkg/Tools/Keys/TestSigningPrivateKey.pem',
- '-o', '%s/FwuImage.bin' % fwu_dir
- ]
- try:
- output = subprocess.run (cmd)
- output.check_returncode()
- except subprocess.CalledProcessError:
- print ('Failed to generate QEMU SlimBootloader capsule image !')
- return -2
+ for test_file, test_args in test_cases:
+ print ('######### Running run test %s' % test_file)
+ # copy a test image so that the original image will not change
+ shutil.copyfile (sbl_img, tst_img)
- # run QEMU FWU test
- cmd = [ sys.executable,
- 'Platform/QemuBoardPkg/Script/qemu_fwu.py',
- tst_img,
- fwu_dir
- ]
- try:
- output = subprocess.run (cmd)
- output.check_returncode()
- except subprocess.CalledProcessError:
- print ('Failed to run QEMU firmware update test !')
- return -3
+ # run QEMU test cases
+ cmd = [ sys.executable, 'Platform/QemuBoardPkg/Script/TestCases/%s' % test_file] + test_args
+ try:
+ output = subprocess.run (cmd)
+ output.check_returncode()
+ except subprocess.CalledProcessError:
+ print ('Failed to run test %s !' % test_file)
+ return -3
+ print ('######### Completed test %s\n\n' % test_file)
print ('\nAll tests passed !\n')