assembler/qemu: support for zipl bootloader
Support the s390x bootloader zipl (z Initial Program Loader). We supply the parameters for the kernel+initrd as well es the target, i.e. the boot partition where the bootmap is creating, the device, here called 'targetbase', to install the bootloader on, including parameters describing the device (type, blocksize) and also the offset of the partition containing the target from the start of device (in sectors). The kernel and initrd are found via the bootloader entry, ignoring the rescue kernel. Since zipl needs the device as well as access to the boot partition the image is bound to a loopback device. Also keep the filesystem tree mounted during the execution of the zipl installation.
This commit is contained in:
parent
a32c30d06c
commit
49e1b91d47
1 changed files with 48 additions and 2 deletions
|
|
@ -45,9 +45,9 @@ STAGE_OPTS = """
|
|||
"type": {
|
||||
"description": "What bootloader to install",
|
||||
"type": "string",
|
||||
"enum": ["grub2"]
|
||||
"enum": ["grub2", "zipl"]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"description": "Image file format to use",
|
||||
|
|
@ -546,6 +546,46 @@ def install_grub2(image: str, pt: PartitionTable, options):
|
|||
grub2_write_boot_image(boot_f, image_f, core_loc)
|
||||
|
||||
|
||||
def parse_blsfile(blsfile):
|
||||
params = {}
|
||||
with open(blsfile, "r") as bls:
|
||||
for line in bls:
|
||||
key, value = line.split(' ', 1)
|
||||
params[key] = value.strip()
|
||||
return params
|
||||
|
||||
|
||||
def find_kernel(root):
|
||||
base = f"{root}/boot/loader/entries"
|
||||
for dirent in os.scandir(base):
|
||||
fn, ext = os.path.splitext(dirent.name)
|
||||
if ext != ".conf" or fn.endswith("rescue"):
|
||||
continue
|
||||
blsfile = f"{base}/{dirent.name}"
|
||||
params = parse_blsfile(blsfile)
|
||||
linux = root + params["linux"]
|
||||
initrd = root + params["initrd"]
|
||||
options = params.get("options", "")
|
||||
return linux, initrd, options
|
||||
|
||||
|
||||
def install_zipl(root: str, device: str, pt: PartitionTable):
|
||||
"""Install the bootloader on s390x via zipl"""
|
||||
kernel, initrd, kopts = find_kernel(root)
|
||||
part_with_boot = pt.partition_containing_boot()
|
||||
subprocess.run(["/usr/sbin/zipl",
|
||||
"--verbose",
|
||||
"--target", f"{root}/boot",
|
||||
"--image", kernel,
|
||||
"--ramdisk", initrd,
|
||||
"--parameters", kopts,
|
||||
"--targetbase", device,
|
||||
"--targettype", "SCSI",
|
||||
"--targetblocksize", "512",
|
||||
"--targetoffset", str(part_with_boot.start)],
|
||||
check=True)
|
||||
|
||||
|
||||
def main(tree, output_dir, options, loop_client):
|
||||
fmt = options["format"]
|
||||
filename = options["filename"]
|
||||
|
|
@ -580,6 +620,7 @@ def main(tree, output_dir, options, loop_client):
|
|||
# Now assemble the filesystem hierarchy and copy the tree into the image
|
||||
with contextlib.ExitStack() as cm:
|
||||
root = cm.enter_context(tempfile.TemporaryDirectory(prefix="osbuild-mnt"))
|
||||
disk = cm.enter_context(loop_client.device(image, 0, size))
|
||||
# iterate the partition according to their position in the filesystem tree
|
||||
for partition in pt.partitions_with_filesystems():
|
||||
offset, size = partition.start_in_bytes, partition.size_in_bytes
|
||||
|
|
@ -596,6 +637,11 @@ def main(tree, output_dir, options, loop_client):
|
|||
# copy the tree into the target image
|
||||
subprocess.run(["cp", "-a", f"{tree}/.", root], check=True)
|
||||
|
||||
# zipl needs access to the /boot directory and the whole image
|
||||
# via the loopback device node
|
||||
if bootloader["type"] == "zipl":
|
||||
install_zipl(root, disk, pt)
|
||||
|
||||
if fmt == "raw":
|
||||
subprocess.run(["cp", image, f"{output_dir}/{filename}"], check=True)
|
||||
elif fmt == "raw.xz":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue