diff --git a/scripts/xtensa-build-zephyr.py b/scripts/xtensa-build-zephyr.py index aab811fabc79..fc3c536c7e24 100755 --- a/scripts/xtensa-build-zephyr.py +++ b/scripts/xtensa-build-zephyr.py @@ -63,6 +63,8 @@ sof_fw_version = None +signing_key = None + if py_platform.system() == "Windows": xtensa_tools_version_postfix = "-win32" elif py_platform.system() == "Linux": @@ -597,6 +599,8 @@ def clean_staging(platform): # detailed comments in west.yml RIMAGE_SOURCE_DIR = west_top / "sof" / "tools" / "rimage" +platform_wconfig = None + def rimage_west_configuration(platform_dict, dest_dir): """Configure rimage in a new file `dest_dir/westconfig.ini`, starting @@ -604,6 +608,8 @@ def rimage_west_configuration(platform_dict, dest_dir): Returns the pathlib.Path to the new file. """ + global platform_wconfig + saved_local_var = os.environ.get('WEST_CONFIG_LOCAL') workspace_west_config_path = os.environ.get('WEST_CONFIG_LOCAL', str(west_top / ".west" / "config")) @@ -671,12 +677,12 @@ def rimage_options(platform_dict): example: [ (-f, 2.5.0), (-b, 1), (-k, key.pem),... ] """ + global signing_key opts = [] if args.verbose > 0: opts.append(("-v",) * args.verbose) - signing_key = None if args.key: key_path = pathlib.Path(args.key) assert key_path.exists(), f"{key_path} not found" @@ -902,6 +908,69 @@ def build_platforms(): symlinks=True, ignore_dangling_symlinks=True, dirs_exist_ok=True) +def install_lib(platform, sof_output_dir, abs_build_dir): + """[summary] Sign loadable llext modules, if any, copy them to the + deployment tree and create UUID links for the kernel to find and load + them.""" + + global signing_key + global platform_wconfig + + with os.scandir(str(abs_build_dir)) as iter: + rimage_executable = platform_wconfig.get("rimage.path") + if rimage_executable is None: + rimage_executable = platform_wconfig.get("rimage.path", None, + west_config.ConfigFile.LOCAL) + + for entry in iter: + if (not entry.is_dir or + not entry.name.endswith('_llext')): + continue + uuids = pathlib.Path(entry.path) / 'llext.uuid' + if not os.path.exists(uuids): + continue + + # replace '_llext' with '.llext', e.g. + # eq_iir_llext/eq_iir.llext + llext_base = entry.name[:-6] + llext_file = llext_base + '.llext' + + sof_lib_dir = sof_output_dir / '..' / 'sof-ipc4-lib' / platform + if args.key_type_subdir != "none": + sof_lib_dir = sof_lib_dir / args.key_type_subdir + sof_lib_dir.mkdir(parents=True, exist_ok=True) + dst = sof_lib_dir / llext_file + + rimage_cfg = pathlib.Path(entry.path) / 'rimage_config.toml' + llext_input = pathlib.Path(entry.path) / str(llext_base + '.so') + llext_output = pathlib.Path(entry.path) / llext_file + + sign_cmd = [str(rimage_executable), "-o", str(llext_output), + "-e", "-c", str(rimage_cfg), + "-k", str(signing_key), "-l", "-r", + str(llext_input)] + execute_command(sign_cmd, cwd=west_top) + + # Explicitly rely on default exception handling + fdst = open(str(dst), 'wb') + fllext = open(str(llext_output), 'rb') + fman = open(str(llext_output) + '.xman', 'rb') + + shutil.copyfileobj(fman, fdst) + shutil.copyfileobj(fllext, fdst) + + fdst.close() + fman.close() + fllext.close() + + with open(uuids, 'r') as f_llext: + lines = f_llext.readlines() + for line in lines: + symlink_or_copy(sof_lib_dir, llext_file, + sof_lib_dir, line.strip() + '.bin') + f_llext.close() + + def install_platform(platform, sof_output_dir, platf_build_environ): # Keep in sync with caller @@ -1033,6 +1102,8 @@ class InstFile: gzip_res.result() # throws exception if gzip unexpectedly failed gzip_threads.shutdown() + if args.deployable_build and platform_configs[platform].ipc4: + install_lib(platform, sof_output_dir, abs_build_dir) # Zephyr's CONFIG_KERNEL_BIN_NAME default value BIN_NAME = 'zephyr'