Files
u-boot/test/py/img/vbe.py
Simon Glass dfa072fd07 test: Move image creation to test/py/img
Rather than having this code mixed with the tests, it seems better to
put it up one level. Move the directory and tidy up references.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-17 15:32:25 -06:00

173 lines
5.6 KiB
Python

# SPDX-License-Identifier: GPL-2.0+
#
# Copyright 2025 Simon Glass <sjg@chromium.org>
# Author: Simon Glass <sjg@chromium.org>
"""Create test disk-images for VBE"""
import gzip
import os
import tempfile
import utils
from fs_helper import DiskHelper, FsHelper
from u_boot_pylib import tools
def dtb_for_compatible(log, kernpath, version, model):
"""Create a fake devicetree binary for a given model name
Args:
log (multiplexed_log.Logfile): Log to write to
kernpath (str): Path to place the created DTB
version (str): Version string to use with the dtb
model (str): Model name
Return:
str: Filename of devicetree file written
"""
dtb_file = os.path.join(kernpath, f'dtb-{version}-{model}')
data = f'/dts-v1/; / {{ compatible = "{model}"; version = "{version}"; }};'
utils.run_and_log_no_ubman(log, f'dtc -o {dtb_file}',
stdin=data.encode('utf-8'))
return dtb_file
def create_extlinux(config, log, kernpath, dirpath, slot, version, has_oem):
"""Create a fake extlinux image
Args:
config (ArbitraryAttributeContainer): Configuration
log (multiplexed_log.Logfile): Log to write to
kernpath (str): Directory path for the kernel
dirpath (str): Directory path to write to (created by this function)
slot (str): Slot name (A, B or recovery)
version (str): Linux version to use, e.g. '6.14.0-24'
has_oem (bool): true to create an OEM FIT
"""
ext_path = os.path.join(dirpath, 'extlinux')
if not os.path.exists(dirpath):
os.mkdir(dirpath)
if not os.path.exists(ext_path):
os.mkdir(ext_path)
dtb_info = ' (no-dtb)' if has_oem else ''
with open(os.path.join(ext_path, 'extlinux.conf'), 'w',
encoding='ascii') as outf:
print(f'''## /boot/extlinux/extlinux.conf
##
## IMPORTANT WARNING
##
## The configuration of this file is generated automatically.
## Do not edit this file manually, use: u-boot-update
default l0
menu title Ubuntu Menu ({slot})
prompt 1
timeout 50
label l0
menu label Ubuntu 24.04.2 LTS {version}{dtb_info}
fit /ubuntu-{version}.fit
append root=/dev/disk/by-id/dm-uuid-LVM-lNvIY7Drx7RGUJpQZGPr2axs2ueSe57B7p7jtyJGIUnMJMHCSPVphCu9IFivkJhK ro earlycon
''', file=outf)
# True to add devicetrees and multiple configurations
add_dts = not has_oem
# Create a FIT containing kernel, initrd and devicetree
with tempfile.TemporaryDirectory(suffix='vbe') as tmp:
kern = os.path.join(tmp, 'kern')
tools.write_file(kern, gzip.compress(f'vmlinux-{slot}'.encode('utf-8')))
mkimage = config.build_dir + '/tools/mkimage'
initrd = os.path.join(tmp, f'initrd.img-{version}')
tools.write_file(initrd, f'initrd {version}', binary=False)
snow = dtb_for_compatible(log, tmp, version, 'snow')
kevin = dtb_for_compatible(log, tmp, version, 'kevin')
fit = os.path.join(kernpath, f'ubuntu-{version}.fit')
cmd = f'{mkimage} -f auto -T kernel -A sandbox -O linux '
dts = f'-b {snow} -b {kevin}' if add_dts else ''
utils.run_and_log_no_ubman(log,
cmd + f'-d {kern} -i {initrd} {dts} {fit}')
# Create a FIT containing OEM devicetrees
if has_oem:
oem_snow = dtb_for_compatible(log, tmp, 'oem', 'snow')
oem_kevin = dtb_for_compatible(log, tmp, 'oem', 'kevin')
fit = os.path.join(dirpath, 'oem.fit')
utils.run_and_log_no_ubman(
log,
f'{mkimage} -f auto -A sandbox -O linux -T flat_dt --load-only'
f' -b {oem_snow} -b {oem_kevin} {fit}')
def setup_vbe_image(config, log):
"""Create three partitions (fat, boot and root) for a VBE boot flow
Args:
config (ArbitraryAttributeContainer): Configuration
log (multiplexed_log.Logfile): Log to write to
The intent is to load either one or two FITs.
Two separate images are created:
- vbe0 has no OEM FIT; OS FIT contains the devicetrees
- vbe1 has an OEM FIT containing the devicetrees; OS FIT does not
"""
for seq in range(2):
with (DiskHelper(config, seq, 'vbe') as img,
FsHelper(config, 'fat', 1, 'efi') as vfat,
FsHelper(config, 'ext4', 1, f'boot{seq}') as boot,
FsHelper(config, 'ext4', 17, 'root') as root):
with open(os.path.join(vfat.srcdir, 'u-boot.efi'), 'wb') as outf:
outf.write(b'fake binary\n')
vfat.mk_fs()
img.add_fs(vfat, DiskHelper.VFAT, bootable=True)
has_oem = bool(seq)
dir_a = os.path.join(boot.srcdir, 'a')
vera = '6.14.0-24-generic'
create_extlinux(config, log, boot.srcdir, dir_a, 'A', vera, has_oem)
dir_b = os.path.join(boot.srcdir, 'b')
verb = '6.8.0-1028-intel'
create_extlinux(config, log, boot.srcdir, dir_b, 'B', verb, has_oem)
boot_slot = 'b' if seq else 'a'
fname = os.path.join(config.result_dir, 'vbe-state.dts')
tools.write_file(fname, b'''// VBE state file
/dts-v1/;
/ {
compatible = "vbe,abrec-state";
os {
compatible = "vbe,os-state";
next-boot {
slot = "boot_slot";
};
};
};
'''.replace(b'boot_slot', boot_slot.encode('utf-8')))
utils.run_and_log_no_ubman(
log, ['dtc', fname, '-O', 'dtb', '-o',
f'{boot.srcdir}/vbe-state'])
boot.mk_fs()
img.add_fs(boot, DiskHelper.EXT4)
root.mk_fs()
img.add_fs(root, DiskHelper.EXT4)
img.create()
img.remove_img = False