os-image-builder is OpenMandriva's approach to targeting devices beyond PCs and generic UEFI capable ARM boards. It is a bit of a hybrid between a traditional desktop OS ISO builder (like our own omdv-build-iso, currently still used to build x86 install images) and an embedded distribution builder like OpenEmbedded or Yocto.
Especially in the ARM world, the traditional approach of "one ISO file for every device" doesn't work -- many boards require custom patches, outside of server boards, few have standardized on a common boot process. Many distributions "solve" this by only targeting UEFI capable boards - but we don't want that limitiation.
os-image-builder can build a custom kernel and bootloader for every target board (the custom kernel ends up being packaged as an rpm, so it can still be updated through dnf), and each board can have a custom way of building the final images - from UEFI compliant booting to having to create an Android style "sparse image" and flashing it with fastboot. Board config files control the kernel source location, kernel configuration options, additional package sets (e.g. needed drivers or firmware packages) and more.
All other packages are pulled from the normal OpenMandriva repositories.
os-image-builder makes some assumptions about the host system - in particular it assumes dnf is available, binaries for the target architectures can be run (e.g. by having a corresponding qemu installed and registered with binfmt-misc, the way OpenMandriva qemu packages do).
It is therefore recommended to run os-image-builder on OpenMandriva -- but other
similar distributions may work.
If you don't have an OpenMandriva installation, a containerized OpenMandriva, e.g.
docker run -ti openmandriva/cooker /bin/sh
is sufficient.
Without parameters saying otherwise, os-image-builder builds a minimal image. You can add individual packages by adding -p packagename, or bigger sets of packages (e.g. whole desktop environments) with -P packageset.
For a list of available packagesets, simply look at the contents of the packagesets directory.
e.g. to build a minimal image for generic UEFI compliant aarch64 boards, do
./build aarch64-uefi
or to build a Raspberry Pi 4B image with KDE and audio support and vim-enhanced, use
./build -P kde -P audio -p vim-enhanced pi4b
Unless -W is given, weak dependencies (Suggests:/Recommends:) are installed automatically.
If you wish to include packages from repositories other than main (such as unsupported, restricted or non-free), use -r to enable those repositories. For example, to build an image that has x264 included, use
./build -P kde -r restricted -p x264 rockpi4c
If you want to use a custom desktop, add -d desktop to the command line, where
desktop is the name of a desktop file found in /usr/share/xsessions
or
/usr/share/wayland-sessions
.
By default, os-image-builder checks what desktops are installed, and uses, in that order, kde, lxqt, openbox, failsafe, plasmamobile, kdewayland, weston.
For example, to build a Raspberry Pi 4B image that launches lxqt even if KDE is installed as well, use
./build -d lxqt pi4b
Note that -d desktop only changes the default setting. It doesn't replace adding the package set(s) needed to use the desktop.
If you wish to start extra systemd services (or disable standard services), you can pass -s service to enable a service or -S service to disable a service that would otherwise be enabled by default.
For example, when building an image for running inside openstack, it may make sense to use
./build -p cloud-init -s cloud-init aarch64-uefi-iso
By default, os-image-builder builds from cooker, the development repositories.
If you wish to use the rolling repository or a released version, add -v _version_
Generated images are put into the results
directory.
Simply create a new file in the packagesets directory. The format is just a list of
package names; in addition, it is run through the C preprocessor, so you can use e.g.
#include "xyz.pkgs"
to include another package set.
LIB(xyz) expands to the package name for the xyz library (libxyz or lib64xyz,
depending on the CPU architecture).
There are also defines for the target architecture and the included packagesets.
For example,
./build -p kde synquacer
Would result in ARCH_aarch64
, TARGET_synquacer
and PACKAGESET_kde
being defined,
allowing for a packageset to say e.g.
libreoffice
#ifdef PACKAGESET_kde
libreoffice-kde
#endif
to add libreoffice and if (and only if) the kde packageset is included, its kde integration extensions.
You can add support for new target devices by creating a new directory in the
device/_maker_/_device_
directory structure.
It is recommended to copy the files from a directory describing a similar device and making modifications as needed, but here's how to add a device from scratch:
The only required file in the new directory is a file called config
, specifying
some of the following options:
ARCH=_arch_
specifies which CPU architecture the target device uses. This must
(obviously) correspond to a CPU architecture supported by the OpenMandriva version
you're building. This is the only required option.
KERNELRPM=_package name_
Package name of the kernel to be installed (typically
kernel-desktop or kernel-server). This can also be multiple packages separated
by spaces, e.g. KERNELRPM="kernel-server kernel-server-modules-infiniband"
Alternatively, if your target device uses a custom kernel, set the parameters below:
KERNEL=_url of kernel git repository_
URL of the git repository for the kernel
to be used. Optionally, a branch can be specified by appending #branch. For
example, to pull in the Raspberry Pi 5.10 kernel, use
KERNEL=https://github.com/raspberrypi/linux.git#rpi-5.10.y
If no kernel is specified, the binary package specified by KERNELRPM
(default: kernel-desktop) will be pulled from OpenMandriva repositories instead.
KERNEL_CONFIG=_kernel-config_
Kernel configuration (as in ls arch/*/configs
inside the kernel source tree). If not specified, defconfig
is used.
KERNEL_EXTRACONFIG=_extra-config_
Extra configuration options to override
KERNEL_CONFIG. Use --enable _option_
, --disable _option_
,
--module _option_
, --set-val _option_ _value_
.
DTB=_dtb_
DeviceTree file to be used (If not specified, DeviceTree isn't used)
CMDLINE=_cmdline_
Command line options passed to the kernel
USE_UEFI=_yes_|_no_
Define whether or not the device uses UEFI
NEED_INITRD=_yes_|_no_
Define whether or not an initrd/initramfs is needed
to boot
KERNEL_GCC=_yes_|_no_
Define whether or not to build the kernel with the
gcc toolchain (default: use clang)
CREATE_DEFAULT_USER=_yes_|_no_
Define whether or not the default user (username
omv with password omv) is created. Since you need a user, this is enabled by default
(but it can make sense to turn it off if the user is created by other means, such
as cloud-init)
HWPACKAGES="package1 package2 ..."
Define packages that are added to all builds for this target
HWPACKAGESETS="packageset1 packageset2 ..."
Define package sets that are added to all builds for this target
HWPACKAGES_packageset="package1 package2 ..."
Define packages that are added to builds for this target that include the packageset
package set (this is useful, for example, for adding a graphics driver if and only if the gui packageset is installed - HWPACKAGES_gui="my-gpu-driver"
)
In addition to the config
file, you can override the default behavior by creating
scriptlets called generate-initrd
, generate-rootfs
, generate-bootimg
,
setup-system-files
, download_kernel_extras
and postprocess
.
Please refer to existing target devices to see what goes into those scripts.
You can also add a write2sd.in
or write2device.in
script that will be sent to
the output directory, containing the instructions needed to write the generated image
to an SD card or device (typically dd
-ing the image to the target device, potentially
plus enlarging the root filesystem to fill the disk etc.)
You can also create a directory called kernel-patches
inside the device directory.
Any patch files in this directory will be applied to the kernel after checking them
out. Some patches that are useful to multiple boards can be found in the top level
kernel-patches
directory. To pull those in, symlink them into your device
kernel-patches
directory. Add board specific kernel patches directly as files in
the device kernel-patches
directory.
Patches are applied in shell order - if you need to make sure B is applied
before A, try renaming the files to e.g. 00-B.patch and 01-A.patch.
Please submit any additional boards you're adding to the OpenMandriva project.
(c) 2020 Bernhard "bero" Rosenkränzer Released under the GPLv3.