Complete Yocto mirror with license table for TQMa6UL (2038-compliance)
- 264 license table entries with exact download URLs (224/264 resolved) - Complete sources/ directory with all BitBake recipes - Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl) - Full traceability for Softwarefreigabeantrag - GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4 - License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'bootimg-biosplusefi' source plugin class for 'wic'
|
||||
#
|
||||
# AUTHORS
|
||||
# William Bourque <wbourque [at) gmail.com>
|
||||
|
||||
import types
|
||||
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from importlib.machinery import SourceFileLoader
|
||||
|
||||
class BootimgBiosPlusEFIPlugin(SourcePlugin):
|
||||
"""
|
||||
Create MBR + EFI boot partition
|
||||
|
||||
This plugin creates a boot partition that contains both
|
||||
legacy BIOS and EFI content. It will be able to boot from both.
|
||||
This is useful when managing PC fleet with some older machines
|
||||
without EFI support.
|
||||
|
||||
Note it is possible to create an image that can boot from both
|
||||
legacy BIOS and EFI by defining two partitions : one with arg
|
||||
--source bootimg-efi and another one with --source bootimg-pcbios.
|
||||
However, this method has the obvious downside that it requires TWO
|
||||
partitions to be created on the storage device.
|
||||
Both partitions will also be marked as "bootable" which does not work on
|
||||
most BIOS, has BIOS often uses the "bootable" flag to determine
|
||||
what to boot. If you have such a BIOS, you need to manually remove the
|
||||
"bootable" flag from the EFI partition for the drive to be bootable.
|
||||
Having two partitions also seems to confuse wic : the content of
|
||||
the first partition will be duplicated into the second, even though it
|
||||
will not be used at all.
|
||||
|
||||
Also, unlike "isoimage-isohybrid" that also does BIOS and EFI, this plugin
|
||||
allows you to have more than only a single rootfs partitions and does
|
||||
not turn the rootfs into an initramfs RAM image.
|
||||
|
||||
This plugin is made to put everything into a single /boot partition so it
|
||||
does not have the limitations listed above.
|
||||
|
||||
The plugin is made so it does tries not to reimplement what's already
|
||||
been done in other plugins; as such it imports "bootimg-pcbios"
|
||||
and "bootimg-efi".
|
||||
Plugin "bootimg-pcbios" is used to generate legacy BIOS boot.
|
||||
Plugin "bootimg-efi" is used to generate the UEFI boot. Note that it
|
||||
requires a --sourceparams argument to know which loader to use; refer
|
||||
to "bootimg-efi" code/documentation for the list of loader.
|
||||
|
||||
Imports are handled with "SourceFileLoader" from importlib as it is
|
||||
otherwise very difficult to import module that has hyphen "-" in their
|
||||
filename.
|
||||
The SourcePlugin() methods used in the plugins (do_install_disk,
|
||||
do_configure_partition, do_prepare_partition) are then called on both,
|
||||
beginning by "bootimg-efi".
|
||||
|
||||
Plugin options, such as "--sourceparams" can still be passed to a
|
||||
plugin, as long they does not cause issue in the other plugin.
|
||||
|
||||
Example wic configuration:
|
||||
part /boot --source bootimg-biosplusefi --sourceparams="loader=grub-efi"\\
|
||||
--ondisk sda --label os_boot --active --align 1024 --use-uuid
|
||||
"""
|
||||
|
||||
name = 'bootimg-biosplusefi'
|
||||
|
||||
__PCBIOS_MODULE_NAME = "bootimg-pcbios"
|
||||
__EFI_MODULE_NAME = "bootimg-efi"
|
||||
|
||||
__imgEFIObj = None
|
||||
__imgBiosObj = None
|
||||
|
||||
@classmethod
|
||||
def __init__(cls):
|
||||
"""
|
||||
Constructor (init)
|
||||
"""
|
||||
|
||||
# XXX
|
||||
# For some reasons, __init__ constructor is never called.
|
||||
# Something to do with how pluginbase works?
|
||||
cls.__instanciateSubClasses()
|
||||
|
||||
@classmethod
|
||||
def __instanciateSubClasses(cls):
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
# Import bootimg-pcbios (class name "BootimgPcbiosPlugin")
|
||||
modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||
cls.__PCBIOS_MODULE_NAME + ".py")
|
||||
loader = SourceFileLoader(cls.__PCBIOS_MODULE_NAME, modulePath)
|
||||
mod = types.ModuleType(loader.name)
|
||||
loader.exec_module(mod)
|
||||
cls.__imgBiosObj = mod.BootimgPcbiosPlugin()
|
||||
|
||||
# Import bootimg-efi (class name "BootimgEFIPlugin")
|
||||
modulePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||
cls.__EFI_MODULE_NAME + ".py")
|
||||
loader = SourceFileLoader(cls.__EFI_MODULE_NAME, modulePath)
|
||||
mod = types.ModuleType(loader.name)
|
||||
loader.exec_module(mod)
|
||||
cls.__imgEFIObj = mod.BootimgEFIPlugin()
|
||||
|
||||
@classmethod
|
||||
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
|
||||
bootimg_dir, kernel_dir, native_sysroot):
|
||||
"""
|
||||
Called after all partitions have been prepared and assembled into a
|
||||
disk image.
|
||||
"""
|
||||
|
||||
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
||||
cls.__instanciateSubClasses()
|
||||
|
||||
cls.__imgEFIObj.do_install_disk(
|
||||
disk,
|
||||
disk_name,
|
||||
creator,
|
||||
workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
native_sysroot)
|
||||
|
||||
cls.__imgBiosObj.do_install_disk(
|
||||
disk,
|
||||
disk_name,
|
||||
creator,
|
||||
workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
native_sysroot)
|
||||
|
||||
@classmethod
|
||||
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
native_sysroot):
|
||||
"""
|
||||
Called before do_prepare_partition()
|
||||
"""
|
||||
|
||||
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
||||
cls.__instanciateSubClasses()
|
||||
|
||||
cls.__imgEFIObj.do_configure_partition(
|
||||
part,
|
||||
source_params,
|
||||
creator,
|
||||
cr_workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
native_sysroot)
|
||||
|
||||
cls.__imgBiosObj.do_configure_partition(
|
||||
part,
|
||||
source_params,
|
||||
creator,
|
||||
cr_workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
native_sysroot)
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
"""
|
||||
|
||||
if ( (not cls.__imgEFIObj) or (not cls.__imgBiosObj) ):
|
||||
cls.__instanciateSubClasses()
|
||||
|
||||
cls.__imgEFIObj.do_prepare_partition(
|
||||
part,
|
||||
source_params,
|
||||
creator,
|
||||
cr_workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
rootfs_dir,
|
||||
native_sysroot)
|
||||
|
||||
cls.__imgBiosObj.do_prepare_partition(
|
||||
part,
|
||||
source_params,
|
||||
creator,
|
||||
cr_workdir,
|
||||
oe_builddir,
|
||||
bootimg_dir,
|
||||
kernel_dir,
|
||||
rootfs_dir,
|
||||
native_sysroot)
|
||||
507
sources/poky/scripts/lib/wic/plugins/source/bootimg-efi.py
Normal file
507
sources/poky/scripts/lib/wic/plugins/source/bootimg-efi.py
Normal file
@@ -0,0 +1,507 @@
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'bootimg-efi' source plugin class for 'wic'
|
||||
#
|
||||
# AUTHORS
|
||||
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import re
|
||||
|
||||
from glob import glob
|
||||
|
||||
from wic import WicError
|
||||
from wic.engine import get_custom_config
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import (exec_cmd, exec_native_cmd,
|
||||
get_bitbake_var, BOOTDD_EXTRA_SPACE)
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class BootimgEFIPlugin(SourcePlugin):
|
||||
"""
|
||||
Create EFI boot partition.
|
||||
This plugin supports GRUB 2 and systemd-boot bootloaders.
|
||||
"""
|
||||
|
||||
name = 'bootimg-efi'
|
||||
|
||||
@classmethod
|
||||
def _copy_additional_files(cls, hdddir, initrd, dtb):
|
||||
bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not bootimg_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
|
||||
if initrd:
|
||||
initrds = initrd.split(';')
|
||||
for rd in initrds:
|
||||
cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, hdddir)
|
||||
exec_cmd(cp_cmd, True)
|
||||
else:
|
||||
logger.debug("Ignoring missing initrd")
|
||||
|
||||
if dtb:
|
||||
if ';' in dtb:
|
||||
raise WicError("Only one DTB supported, exiting")
|
||||
cp_cmd = "cp %s/%s %s" % (bootimg_dir, dtb, hdddir)
|
||||
exec_cmd(cp_cmd, True)
|
||||
|
||||
@classmethod
|
||||
def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params):
|
||||
"""
|
||||
Create loader-specific (grub-efi) config
|
||||
"""
|
||||
configfile = creator.ks.bootloader.configfile
|
||||
custom_cfg = None
|
||||
if configfile:
|
||||
custom_cfg = get_custom_config(configfile)
|
||||
if custom_cfg:
|
||||
# Use a custom configuration for grub
|
||||
grubefi_conf = custom_cfg
|
||||
logger.debug("Using custom configuration file "
|
||||
"%s for grub.cfg", configfile)
|
||||
else:
|
||||
raise WicError("configfile is specified but failed to "
|
||||
"get it from %s." % configfile)
|
||||
|
||||
initrd = source_params.get('initrd')
|
||||
dtb = source_params.get('dtb')
|
||||
|
||||
cls._copy_additional_files(hdddir, initrd, dtb)
|
||||
|
||||
if not custom_cfg:
|
||||
# Create grub configuration using parameters from wks file
|
||||
bootloader = creator.ks.bootloader
|
||||
title = source_params.get('title')
|
||||
|
||||
grubefi_conf = ""
|
||||
grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
|
||||
grubefi_conf += "default=boot\n"
|
||||
grubefi_conf += "timeout=%s\n" % bootloader.timeout
|
||||
grubefi_conf += "menuentry '%s'{\n" % (title if title else "boot")
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
label = source_params.get('label')
|
||||
label_conf = "root=%s" % creator.rootdev
|
||||
if label:
|
||||
label_conf = "LABEL=%s" % label
|
||||
|
||||
grubefi_conf += "linux /%s %s rootwait %s\n" \
|
||||
% (kernel, label_conf, bootloader.append)
|
||||
|
||||
if initrd:
|
||||
initrds = initrd.split(';')
|
||||
grubefi_conf += "initrd"
|
||||
for rd in initrds:
|
||||
grubefi_conf += " /%s" % rd
|
||||
grubefi_conf += "\n"
|
||||
|
||||
if dtb:
|
||||
grubefi_conf += "devicetree /%s\n" % dtb
|
||||
|
||||
grubefi_conf += "}\n"
|
||||
|
||||
logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg",
|
||||
cr_workdir)
|
||||
cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
|
||||
cfg.write(grubefi_conf)
|
||||
cfg.close()
|
||||
|
||||
@classmethod
|
||||
def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params):
|
||||
"""
|
||||
Create loader-specific systemd-boot/gummiboot config
|
||||
"""
|
||||
install_cmd = "install -d %s/loader" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
install_cmd = "install -d %s/loader/entries" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
bootloader = creator.ks.bootloader
|
||||
|
||||
unified_image = source_params.get('create-unified-kernel-image') == "true"
|
||||
|
||||
loader_conf = ""
|
||||
if not unified_image:
|
||||
loader_conf += "default boot\n"
|
||||
loader_conf += "timeout %d\n" % bootloader.timeout
|
||||
|
||||
initrd = source_params.get('initrd')
|
||||
dtb = source_params.get('dtb')
|
||||
|
||||
if not unified_image:
|
||||
cls._copy_additional_files(hdddir, initrd, dtb)
|
||||
|
||||
logger.debug("Writing systemd-boot config "
|
||||
"%s/hdd/boot/loader/loader.conf", cr_workdir)
|
||||
cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w")
|
||||
cfg.write(loader_conf)
|
||||
cfg.close()
|
||||
|
||||
configfile = creator.ks.bootloader.configfile
|
||||
custom_cfg = None
|
||||
if configfile:
|
||||
custom_cfg = get_custom_config(configfile)
|
||||
if custom_cfg:
|
||||
# Use a custom configuration for systemd-boot
|
||||
boot_conf = custom_cfg
|
||||
logger.debug("Using custom configuration file "
|
||||
"%s for systemd-boots's boot.conf", configfile)
|
||||
else:
|
||||
raise WicError("configfile is specified but failed to "
|
||||
"get it from %s.", configfile)
|
||||
|
||||
if not custom_cfg:
|
||||
# Create systemd-boot configuration using parameters from wks file
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
title = source_params.get('title')
|
||||
|
||||
boot_conf = ""
|
||||
boot_conf += "title %s\n" % (title if title else "boot")
|
||||
boot_conf += "linux /%s\n" % kernel
|
||||
|
||||
label = source_params.get('label')
|
||||
label_conf = "LABEL=Boot root=%s" % creator.rootdev
|
||||
if label:
|
||||
label_conf = "LABEL=%s" % label
|
||||
|
||||
boot_conf += "options %s %s\n" % \
|
||||
(label_conf, bootloader.append)
|
||||
|
||||
if initrd:
|
||||
initrds = initrd.split(';')
|
||||
for rd in initrds:
|
||||
boot_conf += "initrd /%s\n" % rd
|
||||
|
||||
if dtb:
|
||||
boot_conf += "devicetree /%s\n" % dtb
|
||||
|
||||
if not unified_image:
|
||||
logger.debug("Writing systemd-boot config "
|
||||
"%s/hdd/boot/loader/entries/boot.conf", cr_workdir)
|
||||
cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
|
||||
cfg.write(boot_conf)
|
||||
cfg.close()
|
||||
|
||||
|
||||
@classmethod
|
||||
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
native_sysroot):
|
||||
"""
|
||||
Called before do_prepare_partition(), creates loader-specific config
|
||||
"""
|
||||
hdddir = "%s/hdd/boot" % cr_workdir
|
||||
|
||||
install_cmd = "install -d %s/EFI/BOOT" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
try:
|
||||
if source_params['loader'] == 'grub-efi':
|
||||
cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params)
|
||||
elif source_params['loader'] == 'systemd-boot':
|
||||
cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params)
|
||||
elif source_params['loader'] == 'uefi-kernel':
|
||||
pass
|
||||
else:
|
||||
raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader'])
|
||||
except KeyError:
|
||||
raise WicError("bootimg-efi requires a loader, none specified")
|
||||
|
||||
if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None:
|
||||
logger.debug('No boot files defined in IMAGE_EFI_BOOT_FILES')
|
||||
else:
|
||||
boot_files = None
|
||||
for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
|
||||
if fmt:
|
||||
var = fmt % id
|
||||
else:
|
||||
var = ""
|
||||
|
||||
boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES" + var)
|
||||
if boot_files:
|
||||
break
|
||||
|
||||
logger.debug('Boot files: %s', boot_files)
|
||||
|
||||
# list of tuples (src_name, dst_name)
|
||||
deploy_files = []
|
||||
for src_entry in re.findall(r'[\w;\-\.\+/\*]+', boot_files):
|
||||
if ';' in src_entry:
|
||||
dst_entry = tuple(src_entry.split(';'))
|
||||
if not dst_entry[0] or not dst_entry[1]:
|
||||
raise WicError('Malformed boot file entry: %s' % src_entry)
|
||||
else:
|
||||
dst_entry = (src_entry, src_entry)
|
||||
|
||||
logger.debug('Destination entry: %r', dst_entry)
|
||||
deploy_files.append(dst_entry)
|
||||
|
||||
cls.install_task = [];
|
||||
for deploy_entry in deploy_files:
|
||||
src, dst = deploy_entry
|
||||
if '*' in src:
|
||||
# by default install files under their basename
|
||||
entry_name_fn = os.path.basename
|
||||
if dst != src:
|
||||
# unless a target name was given, then treat name
|
||||
# as a directory and append a basename
|
||||
entry_name_fn = lambda name: \
|
||||
os.path.join(dst,
|
||||
os.path.basename(name))
|
||||
|
||||
srcs = glob(os.path.join(kernel_dir, src))
|
||||
|
||||
logger.debug('Globbed sources: %s', ', '.join(srcs))
|
||||
for entry in srcs:
|
||||
src = os.path.relpath(entry, kernel_dir)
|
||||
entry_dst_name = entry_name_fn(entry)
|
||||
cls.install_task.append((src, entry_dst_name))
|
||||
else:
|
||||
cls.install_task.append((src, dst))
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
In this case, prepare content for an EFI (grub) boot partition.
|
||||
"""
|
||||
if not kernel_dir:
|
||||
kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not kernel_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
|
||||
staging_kernel_dir = kernel_dir
|
||||
|
||||
hdddir = "%s/hdd/boot" % cr_workdir
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
if source_params.get('create-unified-kernel-image') == "true":
|
||||
initrd = source_params.get('initrd')
|
||||
if not initrd:
|
||||
raise WicError("initrd= must be specified when create-unified-kernel-image=true, exiting")
|
||||
|
||||
deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
efi_stub = glob("%s/%s" % (deploy_dir, "linux*.efi.stub"))
|
||||
if len(efi_stub) == 0:
|
||||
raise WicError("Unified Kernel Image EFI stub not found, exiting")
|
||||
efi_stub = efi_stub[0]
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
label = source_params.get('label')
|
||||
label_conf = "root=%s" % creator.rootdev
|
||||
if label:
|
||||
label_conf = "LABEL=%s" % label
|
||||
|
||||
bootloader = creator.ks.bootloader
|
||||
cmdline = open("%s/cmdline" % tmp_dir, "w")
|
||||
cmdline.write("%s %s" % (label_conf, bootloader.append))
|
||||
cmdline.close()
|
||||
|
||||
initrds = initrd.split(';')
|
||||
initrd = open("%s/initrd" % tmp_dir, "wb")
|
||||
for f in initrds:
|
||||
with open("%s/%s" % (deploy_dir, f), 'rb') as in_file:
|
||||
shutil.copyfileobj(in_file, initrd)
|
||||
initrd.close()
|
||||
|
||||
# Searched by systemd-boot:
|
||||
# https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
|
||||
install_cmd = "install -d %s/EFI/Linux" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
staging_dir_host = get_bitbake_var("STAGING_DIR_HOST")
|
||||
target_sys = get_bitbake_var("TARGET_SYS")
|
||||
|
||||
objdump_cmd = "%s-objdump" % target_sys
|
||||
objdump_cmd += " -p %s" % efi_stub
|
||||
objdump_cmd += " | awk '{ if ($1 == \"SectionAlignment\"){print $2} }'"
|
||||
|
||||
ret, align_str = exec_native_cmd(objdump_cmd, native_sysroot)
|
||||
align = int(align_str, 16)
|
||||
|
||||
objdump_cmd = "%s-objdump" % target_sys
|
||||
objdump_cmd += " -h %s | tail -2" % efi_stub
|
||||
ret, output = exec_native_cmd(objdump_cmd, native_sysroot)
|
||||
|
||||
offset = int(output.split()[2], 16) + int(output.split()[3], 16)
|
||||
|
||||
osrel_off = offset + align - offset % align
|
||||
osrel_path = "%s/usr/lib/os-release" % staging_dir_host
|
||||
osrel_sz = os.stat(osrel_path).st_size
|
||||
|
||||
cmdline_off = osrel_off + osrel_sz
|
||||
cmdline_off = cmdline_off + align - cmdline_off % align
|
||||
cmdline_sz = os.stat(cmdline.name).st_size
|
||||
|
||||
dtb_off = cmdline_off + cmdline_sz
|
||||
dtb_off = dtb_off + align - dtb_off % align
|
||||
|
||||
dtb = source_params.get('dtb')
|
||||
if dtb:
|
||||
if ';' in dtb:
|
||||
raise WicError("Only one DTB supported, exiting")
|
||||
dtb_path = "%s/%s" % (deploy_dir, dtb)
|
||||
dtb_params = '--add-section .dtb=%s --change-section-vma .dtb=0x%x' % \
|
||||
(dtb_path, dtb_off)
|
||||
linux_off = dtb_off + os.stat(dtb_path).st_size
|
||||
linux_off = linux_off + align - linux_off % align
|
||||
else:
|
||||
dtb_params = ''
|
||||
linux_off = dtb_off
|
||||
|
||||
linux_path = "%s/%s" % (staging_kernel_dir, kernel)
|
||||
linux_sz = os.stat(linux_path).st_size
|
||||
|
||||
initrd_off = linux_off + linux_sz
|
||||
initrd_off = initrd_off + align - initrd_off % align
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/systemd-stub.html
|
||||
objcopy_cmd = "%s-objcopy" % target_sys
|
||||
objcopy_cmd += " --enable-deterministic-archives"
|
||||
objcopy_cmd += " --preserve-dates"
|
||||
objcopy_cmd += " --add-section .osrel=%s" % osrel_path
|
||||
objcopy_cmd += " --change-section-vma .osrel=0x%x" % osrel_off
|
||||
objcopy_cmd += " --add-section .cmdline=%s" % cmdline.name
|
||||
objcopy_cmd += " --change-section-vma .cmdline=0x%x" % cmdline_off
|
||||
objcopy_cmd += dtb_params
|
||||
objcopy_cmd += " --add-section .linux=%s" % linux_path
|
||||
objcopy_cmd += " --change-section-vma .linux=0x%x" % linux_off
|
||||
objcopy_cmd += " --add-section .initrd=%s" % initrd.name
|
||||
objcopy_cmd += " --change-section-vma .initrd=0x%x" % initrd_off
|
||||
objcopy_cmd += " %s %s/EFI/Linux/linux.efi" % (efi_stub, hdddir)
|
||||
|
||||
exec_native_cmd(objcopy_cmd, native_sysroot)
|
||||
else:
|
||||
if source_params.get('install-kernel-into-boot-dir') != 'false':
|
||||
install_cmd = "install -m 0644 %s/%s %s/%s" % \
|
||||
(staging_kernel_dir, kernel, hdddir, kernel)
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
|
||||
for src_path, dst_path in cls.install_task:
|
||||
install_cmd = "install -m 0644 -D %s %s" \
|
||||
% (os.path.join(kernel_dir, src_path),
|
||||
os.path.join(hdddir, dst_path))
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
try:
|
||||
if source_params['loader'] == 'grub-efi':
|
||||
shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
|
||||
"%s/grub.cfg" % cr_workdir)
|
||||
for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]:
|
||||
cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:])
|
||||
exec_cmd(cp_cmd, True)
|
||||
shutil.move("%s/grub.cfg" % cr_workdir,
|
||||
"%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
|
||||
elif source_params['loader'] == 'systemd-boot':
|
||||
for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]:
|
||||
cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[8:])
|
||||
exec_cmd(cp_cmd, True)
|
||||
elif source_params['loader'] == 'uefi-kernel':
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if not kernel:
|
||||
raise WicError("Empty KERNEL_IMAGETYPE")
|
||||
target = get_bitbake_var("TARGET_SYS")
|
||||
if not target:
|
||||
raise WicError("Empty TARGET_SYS")
|
||||
|
||||
if re.match("x86_64", target):
|
||||
kernel_efi_image = "bootx64.efi"
|
||||
elif re.match('i.86', target):
|
||||
kernel_efi_image = "bootia32.efi"
|
||||
elif re.match('aarch64', target):
|
||||
kernel_efi_image = "bootaa64.efi"
|
||||
elif re.match('arm', target):
|
||||
kernel_efi_image = "bootarm.efi"
|
||||
else:
|
||||
raise WicError("UEFI stub kernel is incompatible with target %s" % target)
|
||||
|
||||
for mod in [x for x in os.listdir(kernel_dir) if x.startswith(kernel)]:
|
||||
cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, kernel_efi_image)
|
||||
exec_cmd(cp_cmd, True)
|
||||
else:
|
||||
raise WicError("unrecognized bootimg-efi loader: %s" %
|
||||
source_params['loader'])
|
||||
except KeyError:
|
||||
raise WicError("bootimg-efi requires a loader, none specified")
|
||||
|
||||
startup = os.path.join(kernel_dir, "startup.nsh")
|
||||
if os.path.exists(startup):
|
||||
cp_cmd = "cp %s %s/" % (startup, hdddir)
|
||||
exec_cmd(cp_cmd, True)
|
||||
|
||||
for paths in part.include_path or []:
|
||||
for path in paths:
|
||||
cp_cmd = "cp -r %s %s/" % (path, hdddir)
|
||||
exec_cmd(cp_cmd, True)
|
||||
|
||||
du_cmd = "du -bks %s" % hdddir
|
||||
out = exec_cmd(du_cmd)
|
||||
blocks = int(out.split()[0])
|
||||
|
||||
extra_blocks = part.get_extra_block_count(blocks)
|
||||
|
||||
if extra_blocks < BOOTDD_EXTRA_SPACE:
|
||||
extra_blocks = BOOTDD_EXTRA_SPACE
|
||||
|
||||
blocks += extra_blocks
|
||||
|
||||
logger.debug("Added %d extra blocks to %s to get to %d total blocks",
|
||||
extra_blocks, part.mountpoint, blocks)
|
||||
|
||||
# required for compatibility with certain devices expecting file system
|
||||
# block count to be equal to partition block count
|
||||
if blocks < part.fixed_size:
|
||||
blocks = part.fixed_size
|
||||
logger.debug("Overriding %s to %d total blocks for compatibility",
|
||||
part.mountpoint, blocks)
|
||||
|
||||
# dosfs image, created by mkdosfs
|
||||
bootimg = "%s/boot.img" % cr_workdir
|
||||
|
||||
label = part.label if part.label else "ESP"
|
||||
|
||||
dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \
|
||||
(label, part.fsuuid, bootimg, blocks)
|
||||
exec_native_cmd(dosfs_cmd, native_sysroot)
|
||||
|
||||
mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
|
||||
exec_native_cmd(mcopy_cmd, native_sysroot)
|
||||
|
||||
chmod_cmd = "chmod 644 %s" % bootimg
|
||||
exec_cmd(chmod_cmd)
|
||||
|
||||
du_cmd = "du -Lbks %s" % bootimg
|
||||
out = exec_cmd(du_cmd)
|
||||
bootimg_size = out.split()[0]
|
||||
|
||||
part.size = int(bootimg_size)
|
||||
part.source_file = bootimg
|
||||
197
sources/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
Normal file
197
sources/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
Normal file
@@ -0,0 +1,197 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'bootimg-partition' source plugin class for
|
||||
# 'wic'. The plugin creates an image of boot partition, copying over
|
||||
# files listed in IMAGE_BOOT_FILES bitbake variable.
|
||||
#
|
||||
# AUTHORS
|
||||
# Maciej Borzecki <maciej.borzecki (at] open-rnd.pl>
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
from glob import glob
|
||||
|
||||
from wic import WicError
|
||||
from wic.engine import get_custom_config
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import exec_cmd, get_bitbake_var
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class BootimgPartitionPlugin(SourcePlugin):
|
||||
"""
|
||||
Create an image of boot partition, copying over files
|
||||
listed in IMAGE_BOOT_FILES bitbake variable.
|
||||
"""
|
||||
|
||||
name = 'bootimg-partition'
|
||||
image_boot_files_var_name = 'IMAGE_BOOT_FILES'
|
||||
|
||||
@classmethod
|
||||
def do_configure_partition(cls, part, source_params, cr, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
native_sysroot):
|
||||
"""
|
||||
Called before do_prepare_partition(), create u-boot specific boot config
|
||||
"""
|
||||
hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
|
||||
install_cmd = "install -d %s" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
if not kernel_dir:
|
||||
kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not kernel_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
|
||||
boot_files = None
|
||||
for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
|
||||
if fmt:
|
||||
var = fmt % id
|
||||
else:
|
||||
var = ""
|
||||
|
||||
boot_files = get_bitbake_var(cls.image_boot_files_var_name + var)
|
||||
if boot_files is not None:
|
||||
break
|
||||
|
||||
if boot_files is None:
|
||||
raise WicError('No boot files defined, %s unset for entry #%d' % (cls.image_boot_files_var_name, part.lineno))
|
||||
|
||||
logger.debug('Boot files: %s', boot_files)
|
||||
|
||||
# list of tuples (src_name, dst_name)
|
||||
deploy_files = []
|
||||
for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files):
|
||||
if ';' in src_entry:
|
||||
dst_entry = tuple(src_entry.split(';'))
|
||||
if not dst_entry[0] or not dst_entry[1]:
|
||||
raise WicError('Malformed boot file entry: %s' % src_entry)
|
||||
else:
|
||||
dst_entry = (src_entry, src_entry)
|
||||
|
||||
logger.debug('Destination entry: %r', dst_entry)
|
||||
deploy_files.append(dst_entry)
|
||||
|
||||
cls.install_task = [];
|
||||
for deploy_entry in deploy_files:
|
||||
src, dst = deploy_entry
|
||||
if '*' in src:
|
||||
# by default install files under their basename
|
||||
entry_name_fn = os.path.basename
|
||||
if dst != src:
|
||||
# unless a target name was given, then treat name
|
||||
# as a directory and append a basename
|
||||
entry_name_fn = lambda name: \
|
||||
os.path.join(dst,
|
||||
os.path.basename(name))
|
||||
|
||||
srcs = glob(os.path.join(kernel_dir, src))
|
||||
|
||||
logger.debug('Globbed sources: %s', ', '.join(srcs))
|
||||
for entry in srcs:
|
||||
src = os.path.relpath(entry, kernel_dir)
|
||||
entry_dst_name = entry_name_fn(entry)
|
||||
cls.install_task.append((src, entry_dst_name))
|
||||
else:
|
||||
cls.install_task.append((src, dst))
|
||||
|
||||
if source_params.get('loader') != "u-boot":
|
||||
return
|
||||
|
||||
configfile = cr.ks.bootloader.configfile
|
||||
custom_cfg = None
|
||||
if configfile:
|
||||
custom_cfg = get_custom_config(configfile)
|
||||
if custom_cfg:
|
||||
# Use a custom configuration for extlinux.conf
|
||||
extlinux_conf = custom_cfg
|
||||
logger.debug("Using custom configuration file "
|
||||
"%s for extlinux.conf", configfile)
|
||||
else:
|
||||
raise WicError("configfile is specified but failed to "
|
||||
"get it from %s." % configfile)
|
||||
|
||||
if not custom_cfg:
|
||||
# The kernel types supported by the sysboot of u-boot
|
||||
kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"]
|
||||
has_dtb = False
|
||||
fdt_dir = '/'
|
||||
kernel_name = None
|
||||
|
||||
# Find the kernel image name, from the highest precedence to lowest
|
||||
for image in kernel_types:
|
||||
for task in cls.install_task:
|
||||
src, dst = task
|
||||
if re.match(image, src):
|
||||
kernel_name = os.path.join('/', dst)
|
||||
break
|
||||
if kernel_name:
|
||||
break
|
||||
|
||||
for task in cls.install_task:
|
||||
src, dst = task
|
||||
# We suppose that all the dtb are in the same directory
|
||||
if re.search(r'\.dtb', src) and fdt_dir == '/':
|
||||
has_dtb = True
|
||||
fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst))
|
||||
break
|
||||
|
||||
if not kernel_name:
|
||||
raise WicError('No kernel file found')
|
||||
|
||||
# Compose the extlinux.conf
|
||||
extlinux_conf = "default Yocto\n"
|
||||
extlinux_conf += "label Yocto\n"
|
||||
extlinux_conf += " kernel %s\n" % kernel_name
|
||||
if has_dtb:
|
||||
extlinux_conf += " fdtdir %s\n" % fdt_dir
|
||||
bootloader = cr.ks.bootloader
|
||||
extlinux_conf += "append root=%s rootwait %s\n" \
|
||||
% (cr.rootdev, bootloader.append if bootloader.append else '')
|
||||
|
||||
install_cmd = "install -d %s/extlinux/" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w")
|
||||
cfg.write(extlinux_conf)
|
||||
cfg.close()
|
||||
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
In this case, does the following:
|
||||
- sets up a vfat partition
|
||||
- copies all files listed in IMAGE_BOOT_FILES variable
|
||||
"""
|
||||
hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
|
||||
|
||||
if not kernel_dir:
|
||||
kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not kernel_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
|
||||
logger.debug('Kernel dir: %s', bootimg_dir)
|
||||
|
||||
|
||||
for task in cls.install_task:
|
||||
src_path, dst_path = task
|
||||
logger.debug('Install %s as %s', src_path, dst_path)
|
||||
install_cmd = "install -m 0644 -D %s %s" \
|
||||
% (os.path.join(kernel_dir, src_path),
|
||||
os.path.join(hdddir, dst_path))
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
logger.debug('Prepare boot partition using rootfs in %s', hdddir)
|
||||
part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
|
||||
native_sysroot, False)
|
||||
209
sources/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
Normal file
209
sources/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
Normal file
@@ -0,0 +1,209 @@
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'bootimg-pcbios' source plugin class for 'wic'
|
||||
#
|
||||
# AUTHORS
|
||||
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
from wic import WicError
|
||||
from wic.engine import get_custom_config
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import (exec_cmd, exec_native_cmd,
|
||||
get_bitbake_var, BOOTDD_EXTRA_SPACE)
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class BootimgPcbiosPlugin(SourcePlugin):
|
||||
"""
|
||||
Create MBR boot partition and install syslinux on it.
|
||||
"""
|
||||
|
||||
name = 'bootimg-pcbios'
|
||||
|
||||
@classmethod
|
||||
def _get_bootimg_dir(cls, bootimg_dir, dirname):
|
||||
"""
|
||||
Check if dirname exists in default bootimg_dir or in STAGING_DIR.
|
||||
"""
|
||||
staging_datadir = get_bitbake_var("STAGING_DATADIR")
|
||||
for result in (bootimg_dir, staging_datadir):
|
||||
if os.path.exists("%s/%s" % (result, dirname)):
|
||||
return result
|
||||
|
||||
# STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled
|
||||
# but dependency syslinux is still populated to original STAGING_DATADIR
|
||||
nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir)
|
||||
if os.path.exists(os.path.join(nonarch_datadir, dirname)):
|
||||
return nonarch_datadir
|
||||
|
||||
raise WicError("Couldn't find correct bootimg_dir, exiting")
|
||||
|
||||
@classmethod
|
||||
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
|
||||
bootimg_dir, kernel_dir, native_sysroot):
|
||||
"""
|
||||
Called after all partitions have been prepared and assembled into a
|
||||
disk image. In this case, we install the MBR.
|
||||
"""
|
||||
bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
|
||||
mbrfile = "%s/syslinux/" % bootimg_dir
|
||||
if creator.ptable_format == 'msdos':
|
||||
mbrfile += "mbr.bin"
|
||||
elif creator.ptable_format == 'gpt':
|
||||
mbrfile += "gptmbr.bin"
|
||||
else:
|
||||
raise WicError("Unsupported partition table: %s" %
|
||||
creator.ptable_format)
|
||||
|
||||
if not os.path.exists(mbrfile):
|
||||
raise WicError("Couldn't find %s. If using the -e option, do you "
|
||||
"have the right MACHINE set in local.conf? If not, "
|
||||
"is the bootimg_dir path correct?" % mbrfile)
|
||||
|
||||
full_path = creator._full_path(workdir, disk_name, "direct")
|
||||
logger.debug("Installing MBR on disk %s as %s with size %s bytes",
|
||||
disk_name, full_path, disk.min_size)
|
||||
|
||||
dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path)
|
||||
exec_cmd(dd_cmd, native_sysroot)
|
||||
|
||||
@classmethod
|
||||
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
native_sysroot):
|
||||
"""
|
||||
Called before do_prepare_partition(), creates syslinux config
|
||||
"""
|
||||
hdddir = "%s/hdd/boot" % cr_workdir
|
||||
|
||||
install_cmd = "install -d %s" % hdddir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
bootloader = creator.ks.bootloader
|
||||
|
||||
custom_cfg = None
|
||||
if bootloader.configfile:
|
||||
custom_cfg = get_custom_config(bootloader.configfile)
|
||||
if custom_cfg:
|
||||
# Use a custom configuration for grub
|
||||
syslinux_conf = custom_cfg
|
||||
logger.debug("Using custom configuration file %s "
|
||||
"for syslinux.cfg", bootloader.configfile)
|
||||
else:
|
||||
raise WicError("configfile is specified but failed to "
|
||||
"get it from %s." % bootloader.configfile)
|
||||
|
||||
if not custom_cfg:
|
||||
# Create syslinux configuration using parameters from wks file
|
||||
splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg")
|
||||
if os.path.exists(splash):
|
||||
splashline = "menu background splash.jpg"
|
||||
else:
|
||||
splashline = ""
|
||||
|
||||
syslinux_conf = ""
|
||||
syslinux_conf += "PROMPT 0\n"
|
||||
syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n"
|
||||
syslinux_conf += "\n"
|
||||
syslinux_conf += "ALLOWOPTIONS 1\n"
|
||||
syslinux_conf += "SERIAL 0 115200\n"
|
||||
syslinux_conf += "\n"
|
||||
if splashline:
|
||||
syslinux_conf += "%s\n" % splashline
|
||||
syslinux_conf += "DEFAULT boot\n"
|
||||
syslinux_conf += "LABEL boot\n"
|
||||
|
||||
kernel = "/" + get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
syslinux_conf += "KERNEL " + kernel + "\n"
|
||||
|
||||
syslinux_conf += "APPEND label=boot root=%s %s\n" % \
|
||||
(creator.rootdev, bootloader.append)
|
||||
|
||||
logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg",
|
||||
cr_workdir)
|
||||
cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w")
|
||||
cfg.write(syslinux_conf)
|
||||
cfg.close()
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
In this case, prepare content for legacy bios boot partition.
|
||||
"""
|
||||
bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
|
||||
|
||||
staging_kernel_dir = kernel_dir
|
||||
|
||||
hdddir = "%s/hdd/boot" % cr_workdir
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
cmds = ("install -m 0644 %s/%s %s/%s" %
|
||||
(staging_kernel_dir, kernel, hdddir, get_bitbake_var("KERNEL_IMAGETYPE")),
|
||||
"install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" %
|
||||
(bootimg_dir, hdddir),
|
||||
"install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" %
|
||||
(bootimg_dir, hdddir),
|
||||
"install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" %
|
||||
(bootimg_dir, hdddir),
|
||||
"install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" %
|
||||
(bootimg_dir, hdddir))
|
||||
|
||||
for install_cmd in cmds:
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
du_cmd = "du -bks %s" % hdddir
|
||||
out = exec_cmd(du_cmd)
|
||||
blocks = int(out.split()[0])
|
||||
|
||||
extra_blocks = part.get_extra_block_count(blocks)
|
||||
|
||||
if extra_blocks < BOOTDD_EXTRA_SPACE:
|
||||
extra_blocks = BOOTDD_EXTRA_SPACE
|
||||
|
||||
blocks += extra_blocks
|
||||
|
||||
logger.debug("Added %d extra blocks to %s to get to %d total blocks",
|
||||
extra_blocks, part.mountpoint, blocks)
|
||||
|
||||
# dosfs image, created by mkdosfs
|
||||
bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno)
|
||||
|
||||
label = part.label if part.label else "boot"
|
||||
|
||||
dosfs_cmd = "mkdosfs -n %s -i %s -S 512 -C %s %d" % \
|
||||
(label, part.fsuuid, bootimg, blocks)
|
||||
exec_native_cmd(dosfs_cmd, native_sysroot)
|
||||
|
||||
mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
|
||||
exec_native_cmd(mcopy_cmd, native_sysroot)
|
||||
|
||||
syslinux_cmd = "syslinux %s" % bootimg
|
||||
exec_native_cmd(syslinux_cmd, native_sysroot)
|
||||
|
||||
chmod_cmd = "chmod 644 %s" % bootimg
|
||||
exec_cmd(chmod_cmd)
|
||||
|
||||
du_cmd = "du -Lbks %s" % bootimg
|
||||
out = exec_cmd(du_cmd)
|
||||
bootimg_size = out.split()[0]
|
||||
|
||||
part.size = int(bootimg_size)
|
||||
part.source_file = bootimg
|
||||
89
sources/poky/scripts/lib/wic/plugins/source/empty.py
Normal file
89
sources/poky/scripts/lib/wic/plugins/source/empty.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
# The empty wic plugin is used to create unformatted empty partitions for wic
|
||||
# images.
|
||||
# To use it you must pass "empty" as argument for the "--source" parameter in
|
||||
# the wks file. For example:
|
||||
# part foo --source empty --ondisk sda --size="1024" --align 1024
|
||||
#
|
||||
# The plugin supports writing zeros to the start of the
|
||||
# partition. This is useful to overwrite old content like
|
||||
# filesystem signatures which may be re-recognized otherwise.
|
||||
# This feature can be enabled with
|
||||
# '--sourceparams="[fill|size=<N>[S|s|K|k|M|G]][,][bs=<N>[S|s|K|k|M|G]]"'
|
||||
# Conflicting or missing options throw errors.
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from wic import WicError
|
||||
from wic.ksparser import sizetype
|
||||
from wic.pluginbase import SourcePlugin
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class EmptyPartitionPlugin(SourcePlugin):
|
||||
"""
|
||||
Populate unformatted empty partition.
|
||||
|
||||
The following sourceparams are supported:
|
||||
- fill
|
||||
Fill the entire partition with zeros. Requires '--fixed-size' option
|
||||
to be set.
|
||||
- size=<N>[S|s|K|k|M|G]
|
||||
Set the first N bytes of the partition to zero. Default unit is 'K'.
|
||||
- bs=<N>[S|s|K|k|M|G]
|
||||
Write at most N bytes at a time during source file creation.
|
||||
Defaults to '1M'. Default unit is 'K'.
|
||||
"""
|
||||
|
||||
name = 'empty'
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
"""
|
||||
get_byte_count = sizetype('K', True)
|
||||
size = 0
|
||||
|
||||
if 'fill' in source_params and 'size' in source_params:
|
||||
raise WicError("Conflicting source parameters 'fill' and 'size' specified, exiting.")
|
||||
|
||||
# Set the size of the zeros to be written to the partition
|
||||
if 'fill' in source_params:
|
||||
if part.fixed_size == 0:
|
||||
raise WicError("Source parameter 'fill' only works with the '--fixed-size' option, exiting.")
|
||||
size = get_byte_count(part.fixed_size)
|
||||
elif 'size' in source_params:
|
||||
size = get_byte_count(source_params['size'])
|
||||
|
||||
if size == 0:
|
||||
# Nothing to do, create empty partition
|
||||
return
|
||||
|
||||
if 'bs' in source_params:
|
||||
bs = get_byte_count(source_params['bs'])
|
||||
else:
|
||||
bs = get_byte_count('1M')
|
||||
|
||||
# Create a binary file of the requested size filled with zeros
|
||||
source_file = os.path.join(cr_workdir, 'empty-plugin-zeros%s.bin' % part.lineno)
|
||||
if not os.path.exists(os.path.dirname(source_file)):
|
||||
os.makedirs(os.path.dirname(source_file))
|
||||
|
||||
quotient, remainder = divmod(size, bs)
|
||||
with open(source_file, 'wb') as file:
|
||||
for _ in range(quotient):
|
||||
file.write(bytearray(bs))
|
||||
file.write(bytearray(remainder))
|
||||
|
||||
part.size = (size + 1024 - 1) // 1024 # size in KB rounded up
|
||||
part.source_file = source_file
|
||||
@@ -0,0 +1,463 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
|
||||
#
|
||||
# AUTHORS
|
||||
# Mihaly Varga <mihaly.varga (at] ni.com>
|
||||
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from wic import WicError
|
||||
from wic.engine import get_custom_config
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class IsoImagePlugin(SourcePlugin):
|
||||
"""
|
||||
Create a bootable ISO image
|
||||
|
||||
This plugin creates a hybrid, legacy and EFI bootable ISO image. The
|
||||
generated image can be used on optical media as well as USB media.
|
||||
|
||||
Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
|
||||
implemented yet) as bootloader. The plugin creates the directories required
|
||||
by bootloaders and populates them by creating and configuring the
|
||||
bootloader files.
|
||||
|
||||
Example kickstart file:
|
||||
part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
|
||||
image_name= IsoImage" --ondisk cd --label LIVECD
|
||||
bootloader --timeout=10 --append=" "
|
||||
|
||||
In --sourceparams "loader" specifies the bootloader used for booting in EFI
|
||||
mode, while "image_name" specifies the name of the generated image. In the
|
||||
example above, wic creates an ISO image named IsoImage-cd.direct (default
|
||||
extension added by direct imeger plugin) and a file named IsoImage-cd.iso
|
||||
"""
|
||||
|
||||
name = 'isoimage-isohybrid'
|
||||
|
||||
@classmethod
|
||||
def do_configure_syslinux(cls, creator, cr_workdir):
|
||||
"""
|
||||
Create loader-specific (syslinux) config
|
||||
"""
|
||||
splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
|
||||
if os.path.exists(splash):
|
||||
splashline = "menu background splash.jpg"
|
||||
else:
|
||||
splashline = ""
|
||||
|
||||
bootloader = creator.ks.bootloader
|
||||
|
||||
syslinux_conf = ""
|
||||
syslinux_conf += "PROMPT 0\n"
|
||||
syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
|
||||
syslinux_conf += "\n"
|
||||
syslinux_conf += "ALLOWOPTIONS 1\n"
|
||||
syslinux_conf += "SERIAL 0 115200\n"
|
||||
syslinux_conf += "\n"
|
||||
if splashline:
|
||||
syslinux_conf += "%s\n" % splashline
|
||||
syslinux_conf += "DEFAULT boot\n"
|
||||
syslinux_conf += "LABEL boot\n"
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
syslinux_conf += "KERNEL /" + kernel + "\n"
|
||||
syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
|
||||
% bootloader.append
|
||||
|
||||
logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
|
||||
cr_workdir)
|
||||
|
||||
with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
|
||||
cfg.write(syslinux_conf)
|
||||
|
||||
@classmethod
|
||||
def do_configure_grubefi(cls, part, creator, target_dir):
|
||||
"""
|
||||
Create loader-specific (grub-efi) config
|
||||
"""
|
||||
configfile = creator.ks.bootloader.configfile
|
||||
if configfile:
|
||||
grubefi_conf = get_custom_config(configfile)
|
||||
if grubefi_conf:
|
||||
logger.debug("Using custom configuration file %s for grub.cfg",
|
||||
configfile)
|
||||
else:
|
||||
raise WicError("configfile is specified "
|
||||
"but failed to get it from %s", configfile)
|
||||
else:
|
||||
splash = os.path.join(target_dir, "splash.jpg")
|
||||
if os.path.exists(splash):
|
||||
splashline = "menu background splash.jpg"
|
||||
else:
|
||||
splashline = ""
|
||||
|
||||
bootloader = creator.ks.bootloader
|
||||
|
||||
grubefi_conf = ""
|
||||
grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
|
||||
grubefi_conf += "--parity=no --stop=1\n"
|
||||
grubefi_conf += "default=boot\n"
|
||||
grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
|
||||
grubefi_conf += "\n"
|
||||
grubefi_conf += "search --set=root --label %s " % part.label
|
||||
grubefi_conf += "\n"
|
||||
grubefi_conf += "menuentry 'boot'{\n"
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
grubefi_conf += "linux /%s rootwait %s\n" \
|
||||
% (kernel, bootloader.append)
|
||||
grubefi_conf += "initrd /initrd \n"
|
||||
grubefi_conf += "}\n"
|
||||
|
||||
if splashline:
|
||||
grubefi_conf += "%s\n" % splashline
|
||||
|
||||
cfg_path = os.path.join(target_dir, "grub.cfg")
|
||||
logger.debug("Writing grubefi config %s", cfg_path)
|
||||
|
||||
with open(cfg_path, "w") as cfg:
|
||||
cfg.write(grubefi_conf)
|
||||
|
||||
@staticmethod
|
||||
def _build_initramfs_path(rootfs_dir, cr_workdir):
|
||||
"""
|
||||
Create path for initramfs image
|
||||
"""
|
||||
|
||||
initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
|
||||
if not initrd:
|
||||
initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not initrd_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
|
||||
|
||||
image_name = get_bitbake_var("IMAGE_BASENAME")
|
||||
if not image_name:
|
||||
raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
|
||||
|
||||
image_type = get_bitbake_var("INITRAMFS_FSTYPES")
|
||||
if not image_type:
|
||||
raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
|
||||
|
||||
machine = os.path.basename(initrd_dir)
|
||||
|
||||
pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
|
||||
files = glob.glob(pattern)
|
||||
if files:
|
||||
initrd = files[0]
|
||||
|
||||
if not initrd or not os.path.exists(initrd):
|
||||
# Create initrd from rootfs directory
|
||||
initrd = "%s/initrd.cpio.gz" % cr_workdir
|
||||
initrd_dir = "%s/INITRD" % cr_workdir
|
||||
shutil.copytree("%s" % rootfs_dir, \
|
||||
"%s" % initrd_dir, symlinks=True)
|
||||
|
||||
if os.path.isfile("%s/init" % rootfs_dir):
|
||||
shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
|
||||
elif os.path.lexists("%s/init" % rootfs_dir):
|
||||
os.symlink(os.readlink("%s/init" % rootfs_dir), \
|
||||
"%s/init" % initrd_dir)
|
||||
elif os.path.isfile("%s/sbin/init" % rootfs_dir):
|
||||
shutil.copy2("%s/sbin/init" % rootfs_dir, \
|
||||
"%s" % initrd_dir)
|
||||
elif os.path.lexists("%s/sbin/init" % rootfs_dir):
|
||||
os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
|
||||
"%s/init" % initrd_dir)
|
||||
else:
|
||||
raise WicError("Couldn't find or build initrd, exiting.")
|
||||
|
||||
exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
|
||||
% (initrd_dir, cr_workdir), as_shell=True)
|
||||
exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
|
||||
shutil.rmtree(initrd_dir)
|
||||
|
||||
return initrd
|
||||
|
||||
@classmethod
|
||||
def do_configure_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
native_sysroot):
|
||||
"""
|
||||
Called before do_prepare_partition(), creates loader-specific config
|
||||
"""
|
||||
isodir = "%s/ISO/" % cr_workdir
|
||||
|
||||
if os.path.exists(isodir):
|
||||
shutil.rmtree(isodir)
|
||||
|
||||
install_cmd = "install -d %s " % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
# Overwrite the name of the created image
|
||||
logger.debug(source_params)
|
||||
if 'image_name' in source_params and \
|
||||
source_params['image_name'].strip():
|
||||
creator.name = source_params['image_name'].strip()
|
||||
logger.debug("The name of the image is: %s", creator.name)
|
||||
|
||||
@staticmethod
|
||||
def _install_payload(source_params, iso_dir):
|
||||
"""
|
||||
Copies contents of payload directory (as specified in 'payload_dir' param) into iso_dir
|
||||
"""
|
||||
|
||||
if source_params.get('payload_dir'):
|
||||
payload_dir = source_params['payload_dir']
|
||||
|
||||
logger.debug("Payload directory: %s", payload_dir)
|
||||
shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
In this case, prepare content for a bootable ISO image.
|
||||
"""
|
||||
|
||||
isodir = "%s/ISO" % cr_workdir
|
||||
|
||||
cls._install_payload(source_params, isodir)
|
||||
|
||||
if part.rootfs_dir is None:
|
||||
if not 'ROOTFS_DIR' in rootfs_dir:
|
||||
raise WicError("Couldn't find --rootfs-dir, exiting.")
|
||||
rootfs_dir = rootfs_dir['ROOTFS_DIR']
|
||||
else:
|
||||
if part.rootfs_dir in rootfs_dir:
|
||||
rootfs_dir = rootfs_dir[part.rootfs_dir]
|
||||
elif part.rootfs_dir:
|
||||
rootfs_dir = part.rootfs_dir
|
||||
else:
|
||||
raise WicError("Couldn't find --rootfs-dir=%s connection "
|
||||
"or it is not a valid path, exiting." %
|
||||
part.rootfs_dir)
|
||||
|
||||
if not os.path.isdir(rootfs_dir):
|
||||
rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
|
||||
if not os.path.isdir(rootfs_dir):
|
||||
raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
|
||||
|
||||
part.rootfs_dir = rootfs_dir
|
||||
deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
img_iso_dir = get_bitbake_var("ISODIR")
|
||||
|
||||
# Remove the temporary file created by part.prepare_rootfs()
|
||||
if os.path.isfile(part.source_file):
|
||||
os.remove(part.source_file)
|
||||
|
||||
# Support using a different initrd other than default
|
||||
if source_params.get('initrd'):
|
||||
initrd = source_params['initrd']
|
||||
if not deploy_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
|
||||
exec_cmd(cp_cmd)
|
||||
else:
|
||||
# Prepare initial ramdisk
|
||||
initrd = "%s/initrd" % deploy_dir
|
||||
if not os.path.isfile(initrd):
|
||||
initrd = "%s/initrd" % img_iso_dir
|
||||
if not os.path.isfile(initrd):
|
||||
initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
|
||||
|
||||
install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
# Remove the temporary file created by _build_initramfs_path function
|
||||
if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
|
||||
os.remove("%s/initrd.cpio.gz" % cr_workdir)
|
||||
|
||||
kernel = get_bitbake_var("KERNEL_IMAGETYPE")
|
||||
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
|
||||
if get_bitbake_var("INITRAMFS_IMAGE"):
|
||||
kernel = "%s-%s.bin" % \
|
||||
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
|
||||
|
||||
install_cmd = "install -m 0644 %s/%s %s/%s" % \
|
||||
(kernel_dir, kernel, isodir, kernel)
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
#Create bootloader for efi boot
|
||||
try:
|
||||
target_dir = "%s/EFI/BOOT" % isodir
|
||||
if os.path.exists(target_dir):
|
||||
shutil.rmtree(target_dir)
|
||||
|
||||
os.makedirs(target_dir)
|
||||
|
||||
if source_params['loader'] == 'grub-efi':
|
||||
# Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
|
||||
# didn't contains it
|
||||
target_arch = get_bitbake_var("TARGET_SYS")
|
||||
if not target_arch:
|
||||
raise WicError("Coludn't find target architecture")
|
||||
|
||||
if re.match("x86_64", target_arch):
|
||||
grub_src_image = "grub-efi-bootx64.efi"
|
||||
grub_dest_image = "bootx64.efi"
|
||||
elif re.match('i.86', target_arch):
|
||||
grub_src_image = "grub-efi-bootia32.efi"
|
||||
grub_dest_image = "bootia32.efi"
|
||||
else:
|
||||
raise WicError("grub-efi is incompatible with target %s" %
|
||||
target_arch)
|
||||
|
||||
grub_target = os.path.join(target_dir, grub_dest_image)
|
||||
if not os.path.isfile(grub_target):
|
||||
grub_src = os.path.join(deploy_dir, grub_src_image)
|
||||
if not os.path.exists(grub_src):
|
||||
raise WicError("Grub loader %s is not found in %s. "
|
||||
"Please build grub-efi first" % (grub_src_image, deploy_dir))
|
||||
shutil.copy(grub_src, grub_target)
|
||||
|
||||
if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
|
||||
cls.do_configure_grubefi(part, creator, target_dir)
|
||||
|
||||
else:
|
||||
raise WicError("unrecognized bootimg-efi loader: %s" %
|
||||
source_params['loader'])
|
||||
except KeyError:
|
||||
raise WicError("bootimg-efi requires a loader, none specified")
|
||||
|
||||
# Create efi.img that contains bootloader files for EFI booting
|
||||
# if ISODIR didn't exist or didn't contains it
|
||||
if os.path.isfile("%s/efi.img" % img_iso_dir):
|
||||
install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
|
||||
(img_iso_dir, isodir)
|
||||
exec_cmd(install_cmd)
|
||||
else:
|
||||
# Default to 100 blocks of extra space for file system overhead
|
||||
esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100'))
|
||||
|
||||
du_cmd = "du -bks %s/EFI" % isodir
|
||||
out = exec_cmd(du_cmd)
|
||||
blocks = int(out.split()[0])
|
||||
blocks += esp_extra_blocks
|
||||
logger.debug("Added 100 extra blocks to %s to get to %d "
|
||||
"total blocks", part.mountpoint, blocks)
|
||||
|
||||
# dosfs image for EFI boot
|
||||
bootimg = "%s/efi.img" % isodir
|
||||
|
||||
esp_label = source_params.get('esp_label', 'EFIimg')
|
||||
|
||||
dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \
|
||||
% (esp_label, bootimg, blocks)
|
||||
exec_native_cmd(dosfs_cmd, native_sysroot)
|
||||
|
||||
mmd_cmd = "mmd -i %s ::/EFI" % bootimg
|
||||
exec_native_cmd(mmd_cmd, native_sysroot)
|
||||
|
||||
mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
|
||||
% (bootimg, isodir)
|
||||
exec_native_cmd(mcopy_cmd, native_sysroot)
|
||||
|
||||
chmod_cmd = "chmod 644 %s" % bootimg
|
||||
exec_cmd(chmod_cmd)
|
||||
|
||||
# Prepare files for legacy boot
|
||||
syslinux_dir = get_bitbake_var("STAGING_DATADIR")
|
||||
if not syslinux_dir:
|
||||
raise WicError("Couldn't find STAGING_DATADIR, exiting.")
|
||||
|
||||
if os.path.exists("%s/isolinux" % isodir):
|
||||
shutil.rmtree("%s/isolinux" % isodir)
|
||||
|
||||
install_cmd = "install -d %s/isolinux" % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
cls.do_configure_syslinux(creator, cr_workdir)
|
||||
|
||||
install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
|
||||
install_cmd += "%s/isolinux/ldlinux.sys" % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
|
||||
install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
|
||||
install_cmd += "%s/isolinux/isolinux.bin" % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
|
||||
install_cmd += "%s/isolinux/ldlinux.c32" % isodir
|
||||
exec_cmd(install_cmd)
|
||||
|
||||
#create ISO image
|
||||
iso_img = "%s/tempiso_img.iso" % cr_workdir
|
||||
iso_bootimg = "isolinux/isolinux.bin"
|
||||
iso_bootcat = "isolinux/boot.cat"
|
||||
efi_img = "efi.img"
|
||||
|
||||
mkisofs_cmd = "mkisofs -V %s " % part.label
|
||||
mkisofs_cmd += "-o %s -U " % iso_img
|
||||
mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
|
||||
mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
|
||||
mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
|
||||
mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
|
||||
mkisofs_cmd += "-no-emul-boot %s " % isodir
|
||||
|
||||
logger.debug("running command: %s", mkisofs_cmd)
|
||||
exec_native_cmd(mkisofs_cmd, native_sysroot)
|
||||
|
||||
shutil.rmtree(isodir)
|
||||
|
||||
du_cmd = "du -Lbks %s" % iso_img
|
||||
out = exec_cmd(du_cmd)
|
||||
isoimg_size = int(out.split()[0])
|
||||
|
||||
part.size = isoimg_size
|
||||
part.source_file = iso_img
|
||||
|
||||
@classmethod
|
||||
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
|
||||
bootimg_dir, kernel_dir, native_sysroot):
|
||||
"""
|
||||
Called after all partitions have been prepared and assembled into a
|
||||
disk image. In this case, we insert/modify the MBR using isohybrid
|
||||
utility for booting via BIOS from disk storage devices.
|
||||
"""
|
||||
|
||||
iso_img = "%s.p1" % disk.path
|
||||
full_path = creator._full_path(workdir, disk_name, "direct")
|
||||
full_path_iso = creator._full_path(workdir, disk_name, "iso")
|
||||
|
||||
isohybrid_cmd = "isohybrid -u %s" % iso_img
|
||||
logger.debug("running command: %s", isohybrid_cmd)
|
||||
exec_native_cmd(isohybrid_cmd, native_sysroot)
|
||||
|
||||
# Replace the image created by direct plugin with the one created by
|
||||
# mkisofs command. This is necessary because the iso image created by
|
||||
# mkisofs has a very specific MBR is system area of the ISO image, and
|
||||
# direct plugin adds and configures an another MBR.
|
||||
logger.debug("Replaceing the image created by direct plugin\n")
|
||||
os.remove(disk.path)
|
||||
shutil.copy2(iso_img, full_path_iso)
|
||||
shutil.copy2(full_path_iso, full_path)
|
||||
115
sources/poky/scripts/lib/wic/plugins/source/rawcopy.py
Normal file
115
sources/poky/scripts/lib/wic/plugins/source/rawcopy.py
Normal file
@@ -0,0 +1,115 @@
|
||||
#
|
||||
# Copyright OpenEmbedded Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
|
||||
from wic import WicError
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import exec_cmd, get_bitbake_var
|
||||
from wic.filemap import sparse_copy
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class RawCopyPlugin(SourcePlugin):
|
||||
"""
|
||||
Populate partition content from raw image file.
|
||||
"""
|
||||
|
||||
name = 'rawcopy'
|
||||
|
||||
@staticmethod
|
||||
def do_image_label(fstype, dst, label):
|
||||
# don't create label when fstype is none
|
||||
if fstype == 'none':
|
||||
return
|
||||
|
||||
if fstype.startswith('ext'):
|
||||
cmd = 'tune2fs -L %s %s' % (label, dst)
|
||||
elif fstype in ('msdos', 'vfat'):
|
||||
cmd = 'dosfslabel %s %s' % (dst, label)
|
||||
elif fstype == 'btrfs':
|
||||
cmd = 'btrfs filesystem label %s %s' % (dst, label)
|
||||
elif fstype == 'swap':
|
||||
cmd = 'mkswap -L %s %s' % (label, dst)
|
||||
elif fstype in ('squashfs', 'erofs'):
|
||||
raise WicError("It's not possible to update a %s "
|
||||
"filesystem label '%s'" % (fstype, label))
|
||||
else:
|
||||
raise WicError("Cannot update filesystem label: "
|
||||
"Unknown fstype: '%s'" % (fstype))
|
||||
|
||||
exec_cmd(cmd)
|
||||
|
||||
@staticmethod
|
||||
def do_image_uncompression(src, dst, workdir):
|
||||
def subprocess_setup():
|
||||
# Python installs a SIGPIPE handler by default. This is usually not what
|
||||
# non-Python subprocesses expect.
|
||||
# SIGPIPE errors are known issues with gzip/bash
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
|
||||
extension = os.path.splitext(src)[1]
|
||||
decompressor = {
|
||||
".bz2": "bzip2",
|
||||
".gz": "gzip",
|
||||
".xz": "xz",
|
||||
".zst": "zstd -f",
|
||||
}.get(extension)
|
||||
if not decompressor:
|
||||
raise WicError("Not supported compressor filename extension: %s" % extension)
|
||||
cmd = "%s -dc %s > %s" % (decompressor, src, dst)
|
||||
subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
rootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
"""
|
||||
if not kernel_dir:
|
||||
kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
|
||||
if not kernel_dir:
|
||||
raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
|
||||
|
||||
logger.debug('Kernel dir: %s', kernel_dir)
|
||||
|
||||
if 'file' not in source_params:
|
||||
raise WicError("No file specified")
|
||||
|
||||
if 'unpack' in source_params:
|
||||
img = os.path.join(kernel_dir, source_params['file'])
|
||||
src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
|
||||
RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
|
||||
else:
|
||||
src = os.path.join(kernel_dir, source_params['file'])
|
||||
|
||||
dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
|
||||
|
||||
if not os.path.exists(os.path.dirname(dst)):
|
||||
os.makedirs(os.path.dirname(dst))
|
||||
|
||||
if 'skip' in source_params:
|
||||
sparse_copy(src, dst, skip=int(source_params['skip']))
|
||||
else:
|
||||
sparse_copy(src, dst)
|
||||
|
||||
# get the size in the right units for kickstart (kB)
|
||||
du_cmd = "du -Lbks %s" % dst
|
||||
out = exec_cmd(du_cmd)
|
||||
filesize = int(out.split()[0])
|
||||
|
||||
if filesize > part.size:
|
||||
part.size = filesize
|
||||
|
||||
if part.label:
|
||||
RawCopyPlugin.do_image_label(part.fstype, dst, part.label)
|
||||
|
||||
part.source_file = dst
|
||||
236
sources/poky/scripts/lib/wic/plugins/source/rootfs.py
Normal file
236
sources/poky/scripts/lib/wic/plugins/source/rootfs.py
Normal file
@@ -0,0 +1,236 @@
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This implements the 'rootfs' source plugin class for 'wic'
|
||||
#
|
||||
# AUTHORS
|
||||
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
|
||||
# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from oe.path import copyhardlinktree
|
||||
from pathlib import Path
|
||||
|
||||
from wic import WicError
|
||||
from wic.pluginbase import SourcePlugin
|
||||
from wic.misc import get_bitbake_var, exec_native_cmd
|
||||
|
||||
logger = logging.getLogger('wic')
|
||||
|
||||
class RootfsPlugin(SourcePlugin):
|
||||
"""
|
||||
Populate partition content from a rootfs directory.
|
||||
"""
|
||||
|
||||
name = 'rootfs'
|
||||
|
||||
@staticmethod
|
||||
def __validate_path(cmd, rootfs_dir, path):
|
||||
if os.path.isabs(path):
|
||||
logger.error("%s: Must be relative: %s" % (cmd, path))
|
||||
sys.exit(1)
|
||||
|
||||
# Disallow climbing outside of parent directory using '..',
|
||||
# because doing so could be quite disastrous (we will delete the
|
||||
# directory, or modify a directory outside OpenEmbedded).
|
||||
full_path = os.path.realpath(os.path.join(rootfs_dir, path))
|
||||
if not full_path.startswith(os.path.realpath(rootfs_dir)):
|
||||
logger.error("%s: Must point inside the rootfs:" % (cmd, path))
|
||||
sys.exit(1)
|
||||
|
||||
return full_path
|
||||
|
||||
@staticmethod
|
||||
def __get_rootfs_dir(rootfs_dir):
|
||||
if rootfs_dir and os.path.isdir(rootfs_dir):
|
||||
return os.path.realpath(rootfs_dir)
|
||||
|
||||
image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
|
||||
if not os.path.isdir(image_rootfs_dir):
|
||||
raise WicError("No valid artifact IMAGE_ROOTFS from image "
|
||||
"named %s has been found at %s, exiting." %
|
||||
(rootfs_dir, image_rootfs_dir))
|
||||
|
||||
return os.path.realpath(image_rootfs_dir)
|
||||
|
||||
@staticmethod
|
||||
def __get_pseudo(native_sysroot, rootfs, pseudo_dir):
|
||||
pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
|
||||
pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir
|
||||
pseudo += "export PSEUDO_PASSWD=%s;" % rootfs
|
||||
pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
|
||||
pseudo += "%s " % get_bitbake_var("FAKEROOTCMD")
|
||||
return pseudo
|
||||
|
||||
@classmethod
|
||||
def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
|
||||
oe_builddir, bootimg_dir, kernel_dir,
|
||||
krootfs_dir, native_sysroot):
|
||||
"""
|
||||
Called to do the actual content population for a partition i.e. it
|
||||
'prepares' the partition to be incorporated into the image.
|
||||
In this case, prepare content for legacy bios boot partition.
|
||||
"""
|
||||
if part.rootfs_dir is None:
|
||||
if not 'ROOTFS_DIR' in krootfs_dir:
|
||||
raise WicError("Couldn't find --rootfs-dir, exiting")
|
||||
|
||||
rootfs_dir = krootfs_dir['ROOTFS_DIR']
|
||||
else:
|
||||
if part.rootfs_dir in krootfs_dir:
|
||||
rootfs_dir = krootfs_dir[part.rootfs_dir]
|
||||
elif part.rootfs_dir:
|
||||
rootfs_dir = part.rootfs_dir
|
||||
else:
|
||||
raise WicError("Couldn't find --rootfs-dir=%s connection or "
|
||||
"it is not a valid path, exiting" % part.rootfs_dir)
|
||||
|
||||
part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
|
||||
part.has_fstab = os.path.exists(os.path.join(part.rootfs_dir, "etc/fstab"))
|
||||
pseudo_dir = os.path.join(part.rootfs_dir, "../pseudo")
|
||||
if not os.path.lexists(pseudo_dir):
|
||||
pseudo_dir = os.path.join(cls.__get_rootfs_dir(None), '../pseudo')
|
||||
|
||||
if not os.path.lexists(pseudo_dir):
|
||||
logger.warn("%s folder does not exist. "
|
||||
"Usernames and permissions will be invalid " % pseudo_dir)
|
||||
pseudo_dir = None
|
||||
|
||||
new_rootfs = None
|
||||
new_pseudo = None
|
||||
# Handle excluded paths.
|
||||
if part.exclude_path or part.include_path or part.change_directory or part.update_fstab_in_rootfs:
|
||||
# We need a new rootfs directory we can safely modify without
|
||||
# interfering with other tasks. Copy to workdir.
|
||||
new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno))
|
||||
|
||||
if os.path.lexists(new_rootfs):
|
||||
shutil.rmtree(os.path.join(new_rootfs))
|
||||
|
||||
if part.change_directory:
|
||||
cd = part.change_directory
|
||||
if cd[-1] == '/':
|
||||
cd = cd[:-1]
|
||||
orig_dir = cls.__validate_path("--change-directory", part.rootfs_dir, cd)
|
||||
else:
|
||||
orig_dir = part.rootfs_dir
|
||||
copyhardlinktree(orig_dir, new_rootfs)
|
||||
|
||||
# Convert the pseudo directory to its new location
|
||||
if (pseudo_dir):
|
||||
new_pseudo = os.path.realpath(
|
||||
os.path.join(cr_workdir, "pseudo%d" % part.lineno))
|
||||
if os.path.lexists(new_pseudo):
|
||||
shutil.rmtree(new_pseudo)
|
||||
os.mkdir(new_pseudo)
|
||||
shutil.copy(os.path.join(pseudo_dir, "files.db"),
|
||||
os.path.join(new_pseudo, "files.db"))
|
||||
|
||||
pseudo_cmd = "%s -B -m %s -M %s" % (cls.__get_pseudo(native_sysroot,
|
||||
new_rootfs,
|
||||
new_pseudo),
|
||||
orig_dir, new_rootfs)
|
||||
exec_native_cmd(pseudo_cmd, native_sysroot)
|
||||
|
||||
for in_path in part.include_path or []:
|
||||
#parse arguments
|
||||
include_path = in_path[0]
|
||||
if len(in_path) > 2:
|
||||
logger.error("'Invalid number of arguments for include-path")
|
||||
sys.exit(1)
|
||||
if len(in_path) == 2:
|
||||
path = in_path[1]
|
||||
else:
|
||||
path = None
|
||||
|
||||
# Pack files to be included into a tar file.
|
||||
# We need to create a tar file, because that way we can keep the
|
||||
# permissions from the files even when they belong to different
|
||||
# pseudo enviroments.
|
||||
# If we simply copy files using copyhardlinktree/copytree... the
|
||||
# copied files will belong to the user running wic.
|
||||
tar_file = os.path.realpath(
|
||||
os.path.join(cr_workdir, "include-path%d.tar" % part.lineno))
|
||||
if os.path.isfile(include_path):
|
||||
parent = os.path.dirname(os.path.realpath(include_path))
|
||||
tar_cmd = "tar c --owner=root --group=root -f %s -C %s %s" % (
|
||||
tar_file, parent, os.path.relpath(include_path, parent))
|
||||
exec_native_cmd(tar_cmd, native_sysroot)
|
||||
else:
|
||||
if include_path in krootfs_dir:
|
||||
include_path = krootfs_dir[include_path]
|
||||
include_path = cls.__get_rootfs_dir(include_path)
|
||||
include_pseudo = os.path.join(include_path, "../pseudo")
|
||||
if os.path.lexists(include_pseudo):
|
||||
pseudo = cls.__get_pseudo(native_sysroot, include_path,
|
||||
include_pseudo)
|
||||
tar_cmd = "tar cf %s -C %s ." % (tar_file, include_path)
|
||||
else:
|
||||
pseudo = None
|
||||
tar_cmd = "tar c --owner=root --group=root -f %s -C %s ." % (
|
||||
tar_file, include_path)
|
||||
exec_native_cmd(tar_cmd, native_sysroot, pseudo)
|
||||
|
||||
#create destination
|
||||
if path:
|
||||
destination = cls.__validate_path("--include-path", new_rootfs, path)
|
||||
Path(destination).mkdir(parents=True, exist_ok=True)
|
||||
else:
|
||||
destination = new_rootfs
|
||||
|
||||
#extract destination
|
||||
untar_cmd = "tar xf %s -C %s" % (tar_file, destination)
|
||||
if new_pseudo:
|
||||
pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo)
|
||||
else:
|
||||
pseudo = None
|
||||
exec_native_cmd(untar_cmd, native_sysroot, pseudo)
|
||||
os.remove(tar_file)
|
||||
|
||||
for orig_path in part.exclude_path or []:
|
||||
path = orig_path
|
||||
|
||||
full_path = cls.__validate_path("--exclude-path", new_rootfs, path)
|
||||
|
||||
if not os.path.lexists(full_path):
|
||||
continue
|
||||
|
||||
if new_pseudo:
|
||||
pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo)
|
||||
else:
|
||||
pseudo = None
|
||||
if path.endswith(os.sep):
|
||||
# Delete content only.
|
||||
for entry in os.listdir(full_path):
|
||||
full_entry = os.path.join(full_path, entry)
|
||||
rm_cmd = "rm -rf %s" % (full_entry)
|
||||
exec_native_cmd(rm_cmd, native_sysroot, pseudo)
|
||||
else:
|
||||
# Delete whole directory.
|
||||
rm_cmd = "rm -rf %s" % (full_path)
|
||||
exec_native_cmd(rm_cmd, native_sysroot, pseudo)
|
||||
|
||||
# Update part.has_fstab here as fstab may have been added or
|
||||
# removed by the above modifications.
|
||||
part.has_fstab = os.path.exists(os.path.join(new_rootfs, "etc/fstab"))
|
||||
if part.update_fstab_in_rootfs and part.has_fstab and not part.no_fstab_update:
|
||||
fstab_path = os.path.join(new_rootfs, "etc/fstab")
|
||||
# Assume that fstab should always be owned by root with fixed permissions
|
||||
install_cmd = "install -m 0644 -p %s %s" % (part.updated_fstab_path, fstab_path)
|
||||
if new_pseudo:
|
||||
pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo)
|
||||
else:
|
||||
pseudo = None
|
||||
exec_native_cmd(install_cmd, native_sysroot, pseudo)
|
||||
|
||||
part.prepare_rootfs(cr_workdir, oe_builddir,
|
||||
new_rootfs or part.rootfs_dir, native_sysroot,
|
||||
pseudo_dir = new_pseudo or pseudo_dir)
|
||||
Reference in New Issue
Block a user