]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
Add documentation and Yocto examples
authorBöszörményi Zoltán <zboszor@pr.hu>
Fri, 25 Oct 2019 09:42:10 +0000 (11:42 +0200)
committerHarald Hoyer <harald@hoyer.xyz>
Fri, 25 Oct 2019 09:58:58 +0000 (11:58 +0200)
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
README.cross [new file with mode: 0644]
dracut.8.asc
examples/yocto/classes/dracut.bbclass [new file with mode: 0644]
examples/yocto/postinst-intercepts/execute_dracut [new file with mode: 0755]
examples/yocto/recipes/cross-compiler-ldd/cross-compile-ldd-fix-infinite-loop.patch [new file with mode: 0644]
examples/yocto/recipes/cross-compiler-ldd_git.bb [new file with mode: 0644]

diff --git a/README.cross b/README.cross
new file mode 100644 (file)
index 0000000..809ccd7
--- /dev/null
@@ -0,0 +1,70 @@
+Dracut supports running against a sysroot directory that is different
+from the actual root (/) directory of the running system. It is most
+useful for creating/bootstrapping a new system that may or may not be
+using the same CPU architecture as the host system, i.e. building a
+whole Linux system with a cross-compiler framework like Yocto.
+
+The user-visible frontend change is the introduction of a new option
+called "-r" or "--sysroot". It expects a directory that contains the
+complete Linux system that has all the files (kernel drivers, firmware,
+executables, libraries and others) necessary to construct the initramfs.
+
+E.g: dracut --sysroot /path/to/sysroot initramfs.img kernelversion
+
+To support this, a new global variable was introduced inside dracut.
+This variable is called "dracutsysrootdir" and all the files installed
+into the initramfs image is searched relative to the sysroot directory.
+This variable can also be set externally to dracut without using option
+-r/--sysroot.
+
+There are other details that are necessary to tweak to be able to
+run on cross-compiled (a.k.a. foreign) binaries.
+
+dracut uses these crucial utilities during its operation:
+
+ldd
+===
+It lists dynamic library dependencies for executables or libraries
+
+ldconfig
+========
+It creates /etc/ld.so.cache, i.e. the cached information about libraries
+known to the system.
+
+These utilities the way they exist on the host system only work on
+the host system.
+
+To support cross-compiled binaries, a different ldd variant is needed that
+works on those binaries. One such ldd script is found at
+https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
+
+ldconfig in GLIBC as is does support a sysroot with its -r option.
+
+Extra environment variables needed to run dracut on the sysroot are
+documented in the dracut(8) man page.
+
+For the Plymouth boot splash to be added to the initramfs image,
+this gitlab PR is needed for Plymouth:
+https://gitlab.freedesktop.org/plymouth/plymouth/merge_requests/72
+
+Extensions to be used with Yocto
+================================
+
+examples/yocto/classes/dracut.bbclass:
+  Bitbake class for running dracut during the "do_rootfs" stage of
+  creating a distribution image and from the postinstall script of
+  a package. A kernel recipe needs this line to activate it:
+
+  inherit dracut
+
+examples/yocto/postinst-intercepts/execute_dracut
+  The "intercept" script used during "do_rootfs" mentioned above.
+
+examples/yocto/recipes/cross-compiler-ldd_git.bb
+  Package recipe for the cross-compiler-ldd script from the above link.
+
+All the above three need to be added to a Yocto layer to their
+proper locations.
+
+They were tested on Yocto 2.7 with MACHINE="intel-core2-32" and
+MACHINE="genericx86-64".
index 2e974fb0b632680494146d56f962def6515a9745..f1737f7ffa16f189049ee61cc1ab3a2297423891 100644 (file)
@@ -284,6 +284,15 @@ Default:
 Default:
    _/var/tmp_
 
+**-r, --sysroot** _<sysroot directory>_::
+    specify the sysroot directory to collect files from.
+    This is useful to create the initramfs image from
+    a cross-compiled sysroot directory. For the extra helper
+    variables, see *ENVIRONMENT* below.
++
+Default:
+    _empty_
+
 **--sshkey** _<sshkey file>_:: ssh key file used with ssh-client module.
 
 **--logfile** _<logfile>_:: logfile to use; overrides any setting from
@@ -517,6 +526,91 @@ ENVIRONMENT
 _INITRD_COMPRESS_::
     sets the default compression program. See **--compress**.
 
+_DRACUT_LDCONFIG_::
+    sets the _ldconfig_ program path and options. Optional.
+    Used for **--sysroot**.
++
+Default:
+    _ldconfig_
+
+_DRACUT_LDD_::
+    sets the _ldd_ program path and options. Optional.
+    Used for **--sysroot**.
++
+Default:
+    _ldd_
+
+_DRACUT_TESTBIN_::
+    sets the initially tested binary for detecting library paths.
+    Optional. Used for **--sysroot**. In the cross-compiled sysroot,
+    the default value (_/bin/sh_) is unusable, as it is an absolute
+    symlink and points outside the sysroot directory.
++
+Default:
+    _/bin/sh_
+
+_DRACUT_INSTALL_::
+    overrides path and options for executing _dracut-install_ internally.
+    Optional. Can be used to debug _dracut-install_ while running the
+    main dracut script.
++
+Default:
+    _dracut-install_
++
+Example:
+    DRACUT_INSTALL="valgrind dracut-install"
+
+_DRACUT_COMPRESS_BZIP2_::
+_DRACUT_COMPRESS_BZIP2_::
+_DRACUT_COMPRESS_LBZIP2_::
+_DRACUT_COMPRESS_LZMA_::
+_DRACUT_COMPRESS_XZ_::
+_DRACUT_COMPRESS_GZIP_::
+_DRACUT_COMPRESS_PIGZ_::
+_DRACUT_COMPRESS_LZOP_::
+_DRACUT_COMPRESS_ZSTD_::
+_DRACUT_COMPRESS_LZ4_::
+_DRACUT_COMPRESS_CAT_::
+    overrides for compression utilities to support using them from
+    non-standard paths.
++
+Default values are the default compression utility names to be found in **PATH**.
+
+_DRACUT_ARCH_::
+    overrides the value of **uname -m**. Used for **--sysroot**.
++
+Default:
+    _empty_ (the value of **uname -m** on the host system)
+
+_SYSTEMD_VERSION_::
+    overrides systemd version. Used for **--sysroot**.
+
+_DRACUT_INSTALL_PATH_::
+    overrides **PATH** environment for **dracut-install** to look for
+    binaries relative to **--sysroot**. In a cross-compiled environment
+    (e.g. Yocto), PATH points to natively built binaries that are not
+    in the host's /bin, /usr/bin, etc. **dracut-install** still needs plain
+    /bin and /usr/bin that are relative to the cross-compiled sysroot.
++
+Default:
+    _PATH_
+
+_DRACUT_INSTALL_LOG_TARGET_::
+    overrides **DRACUT_LOG_TARGET** for **dracut-install**. It allows
+    running **dracut-install* to run with different log target that
+    **dracut** runs with.
++
+Default:
+    _DRACUT_LOG_TARGET_
+
+_DRACUT_INSTALL_LOG_LEVEL_::
+    overrides **DRACUT_LOG_LEVEL** for **dracut-install**. It allows
+    running **dracut-install* to run with different log level that
+    **dracut** runs with.
++
+Default:
+    _DRACUT_LOG_LEVEL_
+
 FILES
 -----
 _/var/log/dracut.log_::
diff --git a/examples/yocto/classes/dracut.bbclass b/examples/yocto/classes/dracut.bbclass
new file mode 100644 (file)
index 0000000..5c49b3f
--- /dev/null
@@ -0,0 +1,116 @@
+DRACUT_PN ??= "${PN}"
+
+def dracut_compression_type(d):
+    rdtype = d.getVar("INITRAMFS_FSTYPES", True).split('.')
+    if len(rdtype) != 2:
+        return ['','','']
+    if rdtype[0] != 'cpio':
+        return ['','','']
+    cmptypes = [['gz','--gzip','gzip'],['bz2', '--bzip2','bzip2'],['lzma','--lzma','xz'],['xz','--xz','xz'],['lzo','--lzo','lzo'],['lz4','--lz4','lz4'],['zstd','--zstd','zstd']]
+    for cmp in cmptypes:
+        if rdtype[1] == cmp[0]:
+            return cmp
+    return ['','','']
+
+def dracut_compression_opt(d):
+    cmp = dracut_compression_type(d)
+    return cmp[1]
+
+def dracut_compression_pkg(d):
+    cmp = dracut_compression_type(d)
+    return cmp[2]
+
+def dracut_compression_pkg_native(d):
+    cmp = dracut_compression_type(d)
+    if cmp[2] == '':
+        return ''
+    return cmp[2] + '-native'
+
+DRACUT_COMPRESS_OPT ??= "${@dracut_compression_opt(d)}"
+DRACUT_COMPRESS_PKG ??= "${@dracut_compression_pkg(d)}"
+DRACUT_COMPRESS_PKG_NATIVE ??= "${@dracut_compression_pkg_native(d)}"
+
+DRACUT_OPTS ??= "--early-microcode ${DRACUT_COMPRESS_OPT}"
+
+python __anonymous () {
+    pkg = d.getVar("DRACUT_PN", True)
+    if pkg != 'dracut':
+        d.appendVar("RDEPENDS_%s" % pkg, " dracut %s " % d.getVar("DRACUT_COMPRESS_PKG", True))
+    if not pkg.startswith('kernel'):
+        d.appendVarFlag("do_configure", "depends", "virtual/kernel:do_shared_workdir")
+        d.appendVarFlag("do_compile", "depends", "virtual/kernel:do_compile_kernelmodules")
+}
+
+export BUILD_TIME_KERNEL_VERSION = "${@oe.utils.read_file('${STAGING_KERNEL_BUILDDIR}/kernel-abiversion')}"
+
+dracut_postinst () {
+       MY_KERNEL_VERSION=$(readlink $D/boot/bzimage | sed 's,^.*bzImage-,,')
+       if [[ -z "$MY_KERNEL_VERSION" ]]; then
+               MY_KERNEL_VERSION="${KERNEL_VERSION}"
+       fi
+       if [[ -z "$MY_KERNEL_VERSION" ]]; then
+               MY_KERNEL_VERSION="${BUILD_TIME_KERNEL_VERSION}"
+       fi
+       if [[ -z "$MY_KERNEL_VERSION" ]]; then
+               exit 1
+       fi
+
+       if [ -n "$D" ]; then
+               #DEBUGOPTS="--debug --keep"
+               DEBUGOPTS="--keep"
+
+               $INTERCEPT_DIR/postinst_intercept execute_dracut ${PKG} mlprefix=${MLPREFIX} \
+                       prefix= \
+                       MY_KERNEL_VERSION=$MY_KERNEL_VERSION \
+                       DEBUGOPTS="\"$DEBUGOPTS\"" \
+                       DRACUT_OPTS="\"${DRACUT_OPTS}\"" \
+                       systemdutildir=${systemd_unitdir} \
+                       systemdsystemunitdir=${systemd_system_unitdir} \
+                       systemdsystemconfdir=${sysconfdir}/systemd/system \
+                       udevdir=${libdir}/udev \
+                       DRACUT_TMPDIR=${WORKDIR}/dracut-tmpdir \
+                       DRACUT_ARCH="${TUNE_ARCH}" \
+                       DRACUT_COMPRESS_GZIP=$NATIVE_ROOT${bindir}/gzip \
+                       DRACUT_COMPRESS_BZIP2=$NATIVE_ROOT${bindir}/bzip2 \
+                       DRACUT_COMPRESS_LZMA=$NATIVE_ROOT${bindir}/lzma \
+                       DRACUT_LDD="\"PATH='$PATH' ${STAGING_BINDIR_CROSS}/ldd --root $D\"" \
+                       DRACUT_LDCONFIG=$NATIVE_ROOT${bindir}/ldconfig \
+                       DRACUT_INSTALL="\"$NATIVE_ROOT${libdir}/dracut/dracut-install\"" \
+                       PLYMOUTH_LDD="\"${STAGING_BINDIR_CROSS}/ldd --root $D\"" \
+                       PLYMOUTH_LDD_PATH="'$PATH'" \
+                       PLYMOUTH_PLUGIN_PATH=${libdir}/plymouth \
+                       PLYMOUTH_THEME_NAME=${PLYMOUTH_THEME_NAME:-spinner} \
+                       PLYMOUTH_THEME=${PLYMOUTH_THEME_NAME:-spinner}
+       else
+               depmod -a $MY_KERNEL_VERSION
+               echo RUNNING: dracut -f ${DRACUT_OPTS} /boot/initramfs.img $MY_KERNEL_VERSION
+               echo "dracut: $(dracut --help | grep 'Version:')"
+               dracut -f ${DRACUT_OPTS} /boot/initramfs.img $MY_KERNEL_VERSION
+       fi
+}
+
+dracut_populate_packages[vardeps] += "dracut_postinst"
+
+python dracut_populate_packages() {
+    localdata = d.createCopy()
+
+    pkg = d.getVar('DRACUT_PN', True)
+
+    postinst = d.getVar('pkg_postinst_%s' % pkg, True)
+    if not postinst:
+        postinst = '#!/bin/sh\n'
+    postinst += localdata.getVar('dracut_postinst', True)
+    d.setVar('pkg_postinst_%s' % pkg, postinst)
+}
+
+PACKAGESPLITFUNCS_prepend = "dracut_populate_packages "
+
+DRACUT_DEPENDS = " \
+                       binutils-cross-${TUNE_ARCH} gcc-cross-${TUNE_ARCH} \
+                       ldconfig-native coreutils-native findutils-native \
+                       cpio-native util-linux-native kmod-native ${DRACUT_COMPRESS_PKG_NATIVE} \
+                       dracut-native pkgconfig-native cross-compiler-ldd \
+                       ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)} \
+               "
+DEPENDS_append_class-target = " ${DRACUT_DEPENDS}"
+PACKAGE_WRITE_DEPS_append = " ${DRACUT_DEPENDS}"
diff --git a/examples/yocto/postinst-intercepts/execute_dracut b/examples/yocto/postinst-intercepts/execute_dracut
new file mode 100755 (executable)
index 0000000..f9c51af
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+set -e
+
+if [[ -z "$DRACUT_TMPDIR" ]]; then
+       echo "DRACUT_TMPDIR is unset, exiting"
+       exit 0
+fi
+
+# We have to unset "prefix" as dracut uses it to move files around.
+# Yocto has it set as part of the build environment.
+export prefix=
+
+# DRACUT settings
+export UDEVVERSION=241
+export SYSTEMD_VERSION=241
+export DRACUT_TESTBIN=/bin/bash.bash
+export DRACUT_INSTALL_PATH="/usr/sbin:/usr/bin:/sbin:/bin"
+
+# PLYMOUTH settings
+export PLYMOUTH_SYSROOT=$D
+
+export \
+       systemdutildir systemdsystemunitdir systemdsystemconfdir udevdir \
+       DRACUT_ARCH DRACUT_TESTBIN DRACUT_LDD DRACUT_LDCONFIG DRACUT_INSTALL \
+       DRACUT_COMPRESS_GZIP DRACUT_COMPRESS_BZIP2 DRACUT_COMPRESS_LZMA \
+       PLYMOUTH_LDD PLYMOUTH_LDD_PATH PLYMOUTH_PLUGIN_PATH \
+       PLYMOUTH_THEME_NAME PLYMOUTH_THEME
+
+# List environment for debugging
+echo ROOTFS-POSTINST-ENVIRONMENT
+echo -----------
+env
+echo -----------
+
+[[ -d $DRACUT_TMPDIR ]] || mkdir -p $DRACUT_TMPDIR
+
+# Execute depmod and dracut
+echo "$(date) - RUNNING: depmod -b $D -a $MY_KERNEL_VERSION"
+depmod -b $D -a $MY_KERNEL_VERSION
+echo "dracut: $(dracut --sysroot $D --help | grep 'Version:')"
+echo "$(date) - RUNNING: dracut -f --sysroot $D --tmpdir $DRACUT_TMPDIR $DRACUT_OPTS $DEBUGOPTS -k $D/lib/modules/$MY_KERNEL_VERSION $D/boot/initramfs.img $MY_KERNEL_VERSION"
+dracut -f --sysroot $D --tmpdir $DRACUT_TMPDIR $DRACUT_OPTS $DEBUGOPTS -k $D/lib/modules/$MY_KERNEL_VERSION $D/boot/initramfs.img $MY_KERNEL_VERSION
+echo "$(date) - DONE: dracut"
diff --git a/examples/yocto/recipes/cross-compiler-ldd/cross-compile-ldd-fix-infinite-loop.patch b/examples/yocto/recipes/cross-compiler-ldd/cross-compile-ldd-fix-infinite-loop.patch
new file mode 100644 (file)
index 0000000..4aae731
--- /dev/null
@@ -0,0 +1,19 @@
+diff --git a/cross-compile-ldd b/cross-compile-ldd
+index ef2ca20..332d57f 100644
+--- a/cross-compile-ldd
++++ b/cross-compile-ldd
+@@ -337,13 +337,13 @@ do_scan_etc_ldsoconf() {
+ # Build up the full list of search directories
+ declare -a needed_search_path
+ do_trace "Adding basic lib dirs\n"
+-ld_library_path="${ld_library_path}:"
+ while [ -n "${ld_library_path}" ]; do
+     d="${ld_library_path%%:*}"
+     if [ -n "${d}" ]; then
+         do_trace "-> adding search dir '%s'\n" "${d}"
+         needed_search_path+=( "${d}" )
+     fi
++    [[ "$ld_library_path" == "${ld_library_path#*:}" ]] && break
+     ld_library_path="${ld_library_path#*:}"
+ done
+ do_trace "Done adding basic lib dirs\n"
diff --git a/examples/yocto/recipes/cross-compiler-ldd_git.bb b/examples/yocto/recipes/cross-compiler-ldd_git.bb
new file mode 100644 (file)
index 0000000..f8b7906
--- /dev/null
@@ -0,0 +1,33 @@
+SUMMARY = "Cross-compiler LDD"
+HOMEPAGE = "https://gist.github.com/c403786c1394f53f44a3b61214489e6f"
+BUGTRACKER = ""
+LICENSE = "GPLv2"
+
+LIC_FILES_CHKSUM = "file://cross-compile-ldd;beginline=53;endline=57;md5=2b29d19d18a430b931dda3750e865c84"
+
+SRCBRANCH = "master"
+SRCREV = "eb44581caf7dd60b149a6691abef46264c46e866"
+SRC_URI = " \
+                       git://gist.github.com/c403786c1394f53f44a3b61214489e6f.git;protocol=https;branch=${SRCBRANCH} \
+                       file://cross-compile-ldd-fix-infinite-loop.patch \
+               "
+
+S = "${WORKDIR}/git"
+
+inherit siteinfo
+
+SYSROOT_PREPROCESS_FUNCS += " cross_ldd_populate_sysroot "
+
+cross_ldd_populate_sysroot() {
+       mkdir -p ${SYSROOT_DESTDIR}${bindir_crossscripts}
+       cat ${S}/cross-compile-ldd | \
+               sed \
+                       -e "s,^prefix=.*$,prefix=${TARGET_SYS}," \
+                       -e "s,^bits=.*$,bits=${SITEINFO_BITS}," \
+                       -e "s,^ld_library_path=.*$,ld_library_path=${LD_LIBRARY_PATH:-/lib:/usr/lib}," \
+               >${SYSROOT_DESTDIR}${bindir_crossscripts}/ldd
+       chmod +x ${SYSROOT_DESTDIR}${bindir_crossscripts}/ldd
+}
+
+DEPENDS = "coreutils-native sed-native binutils-cross-${TARGET_ARCH} gcc-cross-${TARGET_ARCH}"
+PACKAGE_WRITE_DEPS = "coreutils-native sed-native binutils-cross-${TARGET_ARCH} gcc-cross-${TARGET_ARCH}"