diff options
Diffstat (limited to 'meta/classes/kernel.bbclass')
| -rw-r--r-- | meta/classes/kernel.bbclass | 918 |
1 files changed, 539 insertions, 379 deletions
diff --git a/meta/classes/kernel.bbclass b/meta/classes/kernel.bbclass index 059f787eb8..8954b28b2c 100644 --- a/meta/classes/kernel.bbclass +++ b/meta/classes/kernel.bbclass @@ -1,61 +1,152 @@ -inherit linux-kernel-base module_strip +inherit linux-kernel-base kernel-module-split PROVIDES += "virtual/kernel" -DEPENDS += "virtual/${TARGET_PREFIX}gcc virtual/${TARGET_PREFIX}depmod-${@get_kernelmajorversion('${PV}')} virtual/${TARGET_PREFIX}gcc${KERNEL_CCSUFFIX} update-modules" +DEPENDS += "virtual/${TARGET_PREFIX}binutils virtual/${TARGET_PREFIX}gcc kmod-native bc-native lzop-native" +PACKAGE_WRITE_DEPS += "depmodwrapper-cross virtual/update-alternatives-native" + +do_deploy[depends] += "depmodwrapper-cross:do_populate_sysroot" + +S = "${STAGING_KERNEL_DIR}" +B = "${WORKDIR}/build" +KBUILD_OUTPUT = "${B}" +OE_TERMINAL_EXPORTS += "KBUILD_OUTPUT" # we include gcc above, we dont need virtual/libc INHIBIT_DEFAULT_DEPS = "1" KERNEL_IMAGETYPE ?= "zImage" +INITRAMFS_IMAGE ?= "" +INITRAMFS_IMAGE_NAME ?= "${@['${INITRAMFS_IMAGE}-${MACHINE}', ''][d.getVar('INITRAMFS_IMAGE') == '']}" +INITRAMFS_TASK ?= "" +INITRAMFS_IMAGE_BUNDLE ?= "" + +# KERNEL_VERSION is extracted from source code. It is evaluated as +# None for the first parsing, since the code has not been fetched. +# After the code is fetched, it will be evaluated as real version +# number and cause kernel to be rebuilt. To avoid this, make +# KERNEL_VERSION_NAME and KERNEL_VERSION_PKG_NAME depend on +# LINUX_VERSION which is a constant. +KERNEL_VERSION_NAME = "${@d.getVar('KERNEL_VERSION') or ""}" +KERNEL_VERSION_NAME[vardepvalue] = "${LINUX_VERSION}" +KERNEL_VERSION_PKG_NAME = "${@legitimize_package_name(d.getVar('KERNEL_VERSION'))}" +KERNEL_VERSION_PKG_NAME[vardepvalue] = "${LINUX_VERSION}" python __anonymous () { + import re + + # Merge KERNEL_IMAGETYPE and KERNEL_ALT_IMAGETYPE into KERNEL_IMAGETYPES + type = d.getVar('KERNEL_IMAGETYPE') or "" + alttype = d.getVar('KERNEL_ALT_IMAGETYPE') or "" + types = d.getVar('KERNEL_IMAGETYPES') or "" + if type not in types.split(): + types = (type + ' ' + types).strip() + if alttype not in types.split(): + types = (alttype + ' ' + types).strip() + d.setVar('KERNEL_IMAGETYPES', types) + + typeformake = re.sub(r'\.gz', '', types) + d.setVar('KERNEL_IMAGETYPE_FOR_MAKE', typeformake) + + for type in types.split(): + typelower = type.lower() + imagedest = d.getVar('KERNEL_IMAGEDEST') + + d.appendVar('PACKAGES', ' ' + 'kernel-image-' + typelower) + + d.setVar('FILES_kernel-image-' + typelower, '/' + imagedest + '/' + type + '-${KERNEL_VERSION_NAME}') + + d.appendVar('RDEPENDS_kernel-image', ' ' + 'kernel-image-' + typelower) + + d.setVar('PKG_kernel-image-' + typelower, 'kernel-image-' + typelower + '-${KERNEL_VERSION_PKG_NAME}') + + d.setVar('ALLOW_EMPTY_kernel-image-' + typelower, '1') + + priority = d.getVar('KERNEL_PRIORITY') + postinst = '#!/bin/sh\n' + 'update-alternatives --install /' + imagedest + '/' + type + ' ' + type + ' ' + type + '-${KERNEL_VERSION_NAME} ' + priority + ' || true' + '\n' + d.setVar('pkg_postinst_kernel-image-' + typelower, postinst) + + postrm = '#!/bin/sh\n' + 'update-alternatives --remove' + ' ' + type + ' ' + type + '-${KERNEL_VERSION_NAME} || true' + '\n' + d.setVar('pkg_postrm_kernel-image-' + typelower, postrm) + + image = d.getVar('INITRAMFS_IMAGE') + if image: + d.appendVarFlag('do_bundle_initramfs', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete') - import bb - - kerneltype = bb.data.getVar('KERNEL_IMAGETYPE', d, 1) or '' - if kerneltype == 'uImage': - depends = bb.data.getVar("DEPENDS", d, 1) - depends = "%s u-boot-mkimage-native" % depends - bb.data.setVar("DEPENDS", depends, d) + # NOTE: setting INITRAMFS_TASK is for backward compatibility + # The preferred method is to set INITRAMFS_IMAGE, because + # this INITRAMFS_TASK has circular dependency problems + # if the initramfs requires kernel modules + image_task = d.getVar('INITRAMFS_TASK') + if image_task: + d.appendVarFlag('do_configure', 'depends', ' ${INITRAMFS_TASK}') } -inherit kernel-arch +# Here we pull in all various kernel image types which we support. +# +# In case you're wondering why kernel.bbclass inherits the other image +# types instead of the other way around, the reason for that is to +# maintain compatibility with various currently existing meta-layers. +# By pulling in the various kernel image types here, we retain the +# original behavior of kernel.bbclass, so no meta-layers should get +# broken. +# +# KERNEL_CLASSES by default pulls in kernel-uimage.bbclass, since this +# used to be the default behavior when only uImage was supported. This +# variable can be appended by users who implement support for new kernel +# image types. + +KERNEL_CLASSES ?= " kernel-uimage " +inherit ${KERNEL_CLASSES} + +# Old style kernels may set ${S} = ${WORKDIR}/git for example +# We need to move these over to STAGING_KERNEL_DIR. We can't just +# create the symlink in advance as the git fetcher can't cope with +# the symlink. +do_unpack[cleandirs] += " ${S} ${STAGING_KERNEL_DIR} ${B} ${STAGING_KERNEL_BUILDDIR}" +do_clean[cleandirs] += " ${S} ${STAGING_KERNEL_DIR} ${B} ${STAGING_KERNEL_BUILDDIR}" +base_do_unpack_append () { + s = d.getVar("S") + if s[-1] == '/': + # drop trailing slash, so that os.symlink(kernsrc, s) doesn't use s as directory name and fail + s=s[:-1] + kernsrc = d.getVar("STAGING_KERNEL_DIR") + if s != kernsrc: + bb.utils.mkdirhier(kernsrc) + bb.utils.remove(kernsrc, recurse=True) + if d.getVar("EXTERNALSRC"): + # With EXTERNALSRC S will not be wiped so we can symlink to it + os.symlink(s, kernsrc) + else: + import shutil + shutil.move(s, kernsrc) + os.symlink(kernsrc, s) +} -PACKAGES_DYNAMIC += "kernel-module-*" -PACKAGES_DYNAMIC += "kernel-image-*" +inherit kernel-arch deploy + +PACKAGES_DYNAMIC += "^kernel-module-.*" +PACKAGES_DYNAMIC += "^kernel-image-.*" +PACKAGES_DYNAMIC += "^kernel-firmware-.*" export OS = "${TARGET_OS}" export CROSS_COMPILE = "${TARGET_PREFIX}" -KERNEL_PRIORITY = "${@bb.data.getVar('PV',d,1).split('-')[0].split('.')[-1]}" +KERNEL_PRIORITY ?= "${@int(d.getVar('PV').split('-')[0].split('+')[0].split('.')[0]) * 10000 + \ + int(d.getVar('PV').split('-')[0].split('+')[0].split('.')[1]) * 100 + \ + int(d.getVar('PV').split('-')[0].split('+')[0].split('.')[-1])}" KERNEL_RELEASE ?= "${KERNEL_VERSION}" -KERNEL_CCSUFFIX ?= "" -KERNEL_LDSUFFIX ?= "" - -# Set TARGET_??_KERNEL_ARCH in the machine .conf to set architecture -# specific options necessary for building the kernel and modules. -#FIXME: should be this: TARGET_CC_KERNEL_ARCH ?= "${TARGET_CC_ARCH}" -TARGET_CC_KERNEL_ARCH ?= "" -HOST_CC_KERNEL_ARCH ?= "${TARGET_CC_KERNEL_ARCH}" -TARGET_LD_KERNEL_ARCH ?= "" -HOST_LD_KERNEL_ARCH ?= "${TARGET_LD_KERNEL_ARCH}" - -KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc${KERNEL_CCSUFFIX} ${HOST_CC_KERNEL_ARCH}" -KERNEL_LD = "${LD}${KERNEL_LDSUFFIX} ${HOST_LD_KERNEL_ARCH}" - -# Where built kernel lies in the kernel tree -KERNEL_OUTPUT = "arch/${ARCH}/boot/${KERNEL_IMAGETYPE}" +# The directory where built kernel lies in the kernel tree +KERNEL_OUTPUT_DIR ?= "arch/${ARCH}/boot" KERNEL_IMAGEDEST = "boot" # # configuration # -export CMDLINE_CONSOLE = "console=${@bb.data.getVar("KERNEL_CONSOLE",d,1) or "ttyS0"}" +export CMDLINE_CONSOLE = "console=${@d.getVar("KERNEL_CONSOLE") or "ttyS0"}" -KERNEL_VERSION = "${@get_kernelversion('${S}')}" -KERNEL_MAJOR_VERSION = "${@get_kernelmajorversion('${KERNEL_VERSION}')}" +KERNEL_VERSION = "${@get_kernelversion_headers('${B}')}" KERNEL_LOCALVERSION ?= "" @@ -66,415 +157,484 @@ PACKAGE_ARCH = "${MACHINE_ARCH}" UBOOT_ENTRYPOINT ?= "20008000" UBOOT_LOADADDRESS ?= "${UBOOT_ENTRYPOINT}" -kernel_do_compile() { - unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE - oe_runmake include/linux/version.h CC="${KERNEL_CC}" LD="${KERNEL_LD}" - if [ "${KERNEL_MAJOR_VERSION}" != "2.6" ]; then - oe_runmake dep CC="${KERNEL_CC}" LD="${KERNEL_LD}" - fi - oe_runmake ${KERNEL_IMAGETYPE} CC="${KERNEL_CC}" LD="${KERNEL_LD}" - if (grep -q -i -e '^CONFIG_MODULES=y$' .config); then - oe_runmake modules CC="${KERNEL_CC}" LD="${KERNEL_LD}" - else - oenote "no modules to compile" - fi +# Some Linux kernel configurations need additional parameters on the command line +KERNEL_EXTRA_ARGS ?= "" + +EXTRA_OEMAKE = " HOSTCC="${BUILD_CC}" HOSTCPP="${BUILD_CPP}"" +KERNEL_ALT_IMAGETYPE ??= "" + +copy_initramfs() { + echo "Copying initramfs into ./usr ..." + # In case the directory is not created yet from the first pass compile: + mkdir -p ${B}/usr + # Find and use the first initramfs image archive type we find + rm -f ${B}/usr/${INITRAMFS_IMAGE_NAME}.cpio + for img in cpio cpio.gz cpio.lz4 cpio.lzo cpio.lzma cpio.xz; do + if [ -e "${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img" ]; then + cp ${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img ${B}/usr/. + case $img in + *gz) + echo "gzip decompressing image" + gunzip -f ${B}/usr/${INITRAMFS_IMAGE_NAME}.$img + break + ;; + *lz4) + echo "lz4 decompressing image" + lz4 -df ${B}/usr/${INITRAMFS_IMAGE_NAME}.$img + break + ;; + *lzo) + echo "lzo decompressing image" + lzop -df ${B}/usr/${INITRAMFS_IMAGE_NAME}.$img + break + ;; + *lzma) + echo "lzma decompressing image" + lzma -df ${B}/usr/${INITRAMFS_IMAGE_NAME}.$img + break + ;; + *xz) + echo "xz decompressing image" + xz -df ${B}/usr/${INITRAMFS_IMAGE_NAME}.$img + break + ;; + esac + fi + done + echo "Finished copy of initramfs into ./usr" } -kernel_do_stage() { - ASMDIR=`readlink include/asm` - - mkdir -p ${STAGING_KERNEL_DIR}/include/$ASMDIR - cp -fR include/$ASMDIR/* ${STAGING_KERNEL_DIR}/include/$ASMDIR/ - rm -f $ASMDIR ${STAGING_KERNEL_DIR}/include/asm - ln -sf $ASMDIR ${STAGING_KERNEL_DIR}/include/asm - - mkdir -p ${STAGING_KERNEL_DIR}/include/asm-generic - cp -fR include/asm-generic/* ${STAGING_KERNEL_DIR}/include/asm-generic/ - - mkdir -p ${STAGING_KERNEL_DIR}/include/linux - cp -fR include/linux/* ${STAGING_KERNEL_DIR}/include/linux/ - - mkdir -p ${STAGING_KERNEL_DIR}/include/net - cp -fR include/net/* ${STAGING_KERNEL_DIR}/include/net/ +INITRAMFS_BASE_NAME ?= "initramfs-${PV}-${PR}-${MACHINE}-${DATETIME}" +INITRAMFS_BASE_NAME[vardepsexclude] = "DATETIME" +do_bundle_initramfs () { + if [ ! -z "${INITRAMFS_IMAGE}" -a x"${INITRAMFS_IMAGE_BUNDLE}" = x1 ]; then + echo "Creating a kernel image with a bundled initramfs..." + copy_initramfs + # Backing up kernel image relies on its type(regular file or symbolic link) + tmp_path="" + for type in ${KERNEL_IMAGETYPES} ; do + if [ -h ${KERNEL_OUTPUT_DIR}/$type ] ; then + linkpath=`readlink -n ${KERNEL_OUTPUT_DIR}/$type` + realpath=`readlink -fn ${KERNEL_OUTPUT_DIR}/$type` + mv -f $realpath $realpath.bak + tmp_path=$tmp_path" "$type"#"$linkpath"#"$realpath + elif [ -f ${KERNEL_OUTPUT_DIR}/$type ]; then + mv -f ${KERNEL_OUTPUT_DIR}/$type ${KERNEL_OUTPUT_DIR}/$type.bak + tmp_path=$tmp_path" "$type"##" + fi + done + use_alternate_initrd=CONFIG_INITRAMFS_SOURCE=${B}/usr/${INITRAMFS_IMAGE_NAME}.cpio + kernel_do_compile + # Restoring kernel image + for tp in $tmp_path ; do + type=`echo $tp|cut -d "#" -f 1` + linkpath=`echo $tp|cut -d "#" -f 2` + realpath=`echo $tp|cut -d "#" -f 3` + if [ -n "$realpath" ]; then + mv -f $realpath $realpath.initramfs + mv -f $realpath.bak $realpath + ln -sf $linkpath.initramfs ${B}/${KERNEL_OUTPUT_DIR}/$type.initramfs + else + mv -f ${KERNEL_OUTPUT_DIR}/$type ${KERNEL_OUTPUT_DIR}/$type.initramfs + mv -f ${KERNEL_OUTPUT_DIR}/$type.bak ${KERNEL_OUTPUT_DIR}/$type + fi + done + fi +} +do_bundle_initramfs[dirs] = "${B}" - mkdir -p ${STAGING_KERNEL_DIR}/include/pcmcia - cp -fR include/pcmcia/* ${STAGING_KERNEL_DIR}/include/pcmcia/ +python do_devshell_prepend () { + os.environ["LDFLAGS"] = '' +} - for entry in drivers/crypto include/media include/acpi include/sound include/video; do - if [ -d $entry ]; then - mkdir -p ${STAGING_KERNEL_DIR}/$entry - cp -fR $entry/* ${STAGING_KERNEL_DIR}/$entry/ - fi - done +addtask bundle_initramfs after do_install before do_deploy - if [ -d drivers/sound ]; then - # 2.4 alsa needs some headers from this directory - mkdir -p ${STAGING_KERNEL_DIR}/include/drivers/sound - cp -fR drivers/sound/*.h ${STAGING_KERNEL_DIR}/include/drivers/sound/ +kernel_do_compile() { + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE + # The $use_alternate_initrd is only set from + # do_bundle_initramfs() This variable is specifically for the + # case where we are making a second pass at the kernel + # compilation and we want to force the kernel build to use a + # different initramfs image. The way to do that in the kernel + # is to specify: + # make ...args... CONFIG_INITRAMFS_SOURCE=some_other_initramfs.cpio + if [ "$use_alternate_initrd" = "" ] && [ "${INITRAMFS_TASK}" != "" ] ; then + # The old style way of copying an prebuilt image and building it + # is turned on via INTIRAMFS_TASK != "" + copy_initramfs + use_alternate_initrd=CONFIG_INITRAMFS_SOURCE=${B}/usr/${INITRAMFS_IMAGE_NAME}.cpio fi + for typeformake in ${KERNEL_IMAGETYPE_FOR_MAKE} ; do + oe_runmake ${typeformake} CC="${KERNEL_CC}" LD="${KERNEL_LD}" ${KERNEL_EXTRA_ARGS} $use_alternate_initrd + for type in ${KERNEL_IMAGETYPES} ; do + if test "${typeformake}.gz" = "${type}"; then + mkdir -p "${KERNEL_OUTPUT_DIR}" + gzip -9c < "${typeformake}" > "${KERNEL_OUTPUT_DIR}/${type}" + break; + fi + done + done +} - install -m 0644 .config ${STAGING_KERNEL_DIR}/config-${KERNEL_VERSION} - ln -sf config-${KERNEL_VERSION} ${STAGING_KERNEL_DIR}/.config - ln -sf config-${KERNEL_VERSION} ${STAGING_KERNEL_DIR}/kernel-config - echo "${KERNEL_VERSION}" >${STAGING_KERNEL_DIR}/kernel-abiversion - echo "${S}" >${STAGING_KERNEL_DIR}/kernel-source - echo "${KERNEL_CCSUFFIX}" >${STAGING_KERNEL_DIR}/kernel-ccsuffix - echo "${KERNEL_LDSUFFIX}" >${STAGING_KERNEL_DIR}/kernel-ldsuffix - [ -e Rules.make ] && install -m 0644 Rules.make ${STAGING_KERNEL_DIR}/ - [ -e Makefile ] && install -m 0644 Makefile ${STAGING_KERNEL_DIR}/ - - # Check if arch/${ARCH}/Makefile exists and install it - if [ -e arch/${ARCH}/Makefile ]; then - install -d ${STAGING_KERNEL_DIR}/arch/${ARCH} - install -m 0644 arch/${ARCH}/Makefile* ${STAGING_KERNEL_DIR}/arch/${ARCH} - # Otherwise check arch/x86/Makefile for i386 and x86_64 on kernels >= 2.6.24 - elif [ -e arch/x86/Makefile ]; then - install -d ${STAGING_KERNEL_DIR}/arch/x86 - install -m 0644 arch/x86/Makefile* ${STAGING_KERNEL_DIR}/arch/x86 +do_compile_kernelmodules() { + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE + if (grep -q -i -e '^CONFIG_MODULES=y$' ${B}/.config); then + oe_runmake -C ${B} ${PARALLEL_MAKE} modules CC="${KERNEL_CC}" LD="${KERNEL_LD}" ${KERNEL_EXTRA_ARGS} + + # Module.symvers gets updated during the + # building of the kernel modules. We need to + # update this in the shared workdir since some + # external kernel modules has a dependency on + # other kernel modules and will look at this + # file to do symbol lookups + cp ${B}/Module.symvers ${STAGING_KERNEL_BUILDDIR}/ + else + bbnote "no modules to compile" fi - cp -fR include/config* ${STAGING_KERNEL_DIR}/include/ - # Install kernel images and system.map to staging - [ -e vmlinux ] && install -m 0644 vmlinux ${STAGING_KERNEL_DIR}/ - install -m 0644 ${KERNEL_OUTPUT} ${STAGING_KERNEL_DIR}/${KERNEL_IMAGETYPE} - install -m 0644 System.map ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} - [ -e Module.symvers ] && install -m 0644 Module.symvers ${STAGING_KERNEL_DIR}/ - - cp -fR scripts ${STAGING_KERNEL_DIR}/ } +addtask compile_kernelmodules after do_compile before do_strip kernel_do_install() { + # + # First install the modules + # unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE if (grep -q -i -e '^CONFIG_MODULES=y$' .config); then - oe_runmake DEPMOD=echo INSTALL_MOD_PATH="${D}" modules_install + oe_runmake DEPMOD=echo MODLIB=${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION} INSTALL_FW_PATH=${D}${nonarch_base_libdir}/firmware modules_install + rm "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/build" + rm "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/source" + # If the kernel/ directory is empty remove it to prevent QA issues + rmdir --ignore-fail-on-non-empty "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel" else - oenote "no modules to install" + bbnote "no modules to install" fi - + + # + # Install various kernel output (zImage, map file, config, module support files) + # install -d ${D}/${KERNEL_IMAGEDEST} install -d ${D}/boot - install -m 0644 ${KERNEL_OUTPUT} ${D}/${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE}-${KERNEL_VERSION} + for type in ${KERNEL_IMAGETYPES} ; do + install -m 0644 ${KERNEL_OUTPUT_DIR}/${type} ${D}/${KERNEL_IMAGEDEST}/${type}-${KERNEL_VERSION} + done install -m 0644 System.map ${D}/boot/System.map-${KERNEL_VERSION} install -m 0644 .config ${D}/boot/config-${KERNEL_VERSION} install -m 0644 vmlinux ${D}/boot/vmlinux-${KERNEL_VERSION} - install -d ${D}/etc/modutils - if [ "${KERNEL_MAJOR_VERSION}" = "2.6" ]; then - install -d ${D}/etc/modprobe.d + [ -e Module.symvers ] && install -m 0644 Module.symvers ${D}/boot/Module.symvers-${KERNEL_VERSION} + install -d ${D}${sysconfdir}/modules-load.d + install -d ${D}${sysconfdir}/modprobe.d +} +do_install[prefuncs] += "package_get_auto_pr" + +# Must be ran no earlier than after do_kernel_checkout or else Makefile won't be in ${S}/Makefile +do_kernel_version_sanity_check() { + if [ "x${KERNEL_VERSION_SANITY_SKIP}" = "x1" ]; then + exit 0 + fi + + # The Makefile determines the kernel version shown at runtime + # Don't use KERNEL_VERSION because the headers it grabs the version from aren't generated until do_compile + VERSION=$(grep "^VERSION =" ${S}/Makefile | sed s/.*=\ *//) + PATCHLEVEL=$(grep "^PATCHLEVEL =" ${S}/Makefile | sed s/.*=\ *//) + SUBLEVEL=$(grep "^SUBLEVEL =" ${S}/Makefile | sed s/.*=\ *//) + EXTRAVERSION=$(grep "^EXTRAVERSION =" ${S}/Makefile | sed s/.*=\ *//) + + # Build a string for regex and a plain version string + reg="^${VERSION}\.${PATCHLEVEL}" + vers="${VERSION}.${PATCHLEVEL}" + if [ -n "${SUBLEVEL}" ]; then + # Ignoring a SUBLEVEL of zero is fine + if [ "${SUBLEVEL}" = "0" ]; then + reg="${reg}(\.${SUBLEVEL})?" + else + reg="${reg}\.${SUBLEVEL}" + vers="${vers}.${SUBLEVEL}" + fi + fi + vers="${vers}${EXTRAVERSION}" + reg="${reg}${EXTRAVERSION}" + + if [ -z `echo ${PV} | grep -E "${reg}"` ]; then + bbfatal "Package Version (${PV}) does not match of kernel being built (${vers}). Please update the PV variable to match the kernel source or set KERNEL_VERSION_SANITY_SKIP=\"1\" in your recipe." fi - - # Check if scripts/genksyms exists and if so, build it - if [ -e scripts/genksyms/ ]; then - oe_runmake SUBDIRS="scripts/genksyms" - fi - - install -d ${STAGING_KERNEL_DIR} - cp -fR scripts ${STAGING_KERNEL_DIR}/ + exit 0 } -kernel_do_configure() { - yes '' | oe_runmake oldconfig +addtask shared_workdir after do_compile before do_compile_kernelmodules +addtask shared_workdir_setscene + +do_shared_workdir_setscene () { + exit 1 } -do_menuconfig() { - export TERMWINDOWTITLE="${PN} Kernel Configuration" - export SHELLCMDS="make menuconfig" - ${TERMCMDRUN} - if [ $? -ne 0 ]; then - echo "Fatal: '${TERMCMD}' not found. Check TERMCMD variable." - exit 1 +emit_depmod_pkgdata() { + # Stash data for depmod + install -d ${PKGDESTWORK}/kernel-depmod/ + echo "${KERNEL_VERSION}" > ${PKGDESTWORK}/kernel-depmod/kernel-abiversion + cp ${B}/System.map ${PKGDESTWORK}/kernel-depmod/System.map-${KERNEL_VERSION} +} + +PACKAGEFUNCS += "emit_depmod_pkgdata" + +do_shared_workdir () { + cd ${B} + + kerneldir=${STAGING_KERNEL_BUILDDIR} + install -d $kerneldir + + # + # Store the kernel version in sysroots for module-base.bbclass + # + + echo "${KERNEL_VERSION}" > $kerneldir/kernel-abiversion + + # Copy files required for module builds + cp System.map $kerneldir/System.map-${KERNEL_VERSION} + cp Module.symvers $kerneldir/ + cp .config $kerneldir/ + mkdir -p $kerneldir/include/config + cp include/config/kernel.release $kerneldir/include/config/kernel.release + if [ -e certs/signing_key.pem ]; then + # The signing_key.* files are stored in the certs/ dir in + # newer Linux kernels + mkdir -p $kerneldir/certs + cp certs/signing_key.* $kerneldir/certs/ + elif [ -e signing_key.priv ]; then + cp signing_key.* $kerneldir/ + fi + + # We can also copy over all the generated files and avoid special cases + # like version.h, but we've opted to keep this small until file creep starts + # to happen + if [ -e include/linux/version.h ]; then + mkdir -p $kerneldir/include/linux + cp include/linux/version.h $kerneldir/include/linux/version.h + fi + + # As of Linux kernel version 3.0.1, the clean target removes + # arch/powerpc/lib/crtsavres.o which is present in + # KBUILD_LDFLAGS_MODULE, making it required to build external modules. + if [ ${ARCH} = "powerpc" ]; then + mkdir -p $kerneldir/arch/powerpc/lib/ + cp arch/powerpc/lib/crtsavres.o $kerneldir/arch/powerpc/lib/crtsavres.o + fi + + if [ -d include/generated ]; then + mkdir -p $kerneldir/include/generated/ + cp -fR include/generated/* $kerneldir/include/generated/ + fi + + if [ -d arch/${ARCH}/include/generated ]; then + mkdir -p $kerneldir/arch/${ARCH}/include/generated/ + cp -fR arch/${ARCH}/include/generated/* $kerneldir/arch/${ARCH}/include/generated/ fi } -do_menuconfig[nostamp] = "1" -addtask menuconfig after do_patch -pkg_postinst_kernel () { - cd /${KERNEL_IMAGEDEST}; update-alternatives --install /${KERNEL_IMAGEDEST}/${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE}-${KERNEL_VERSION} ${KERNEL_PRIORITY} || true +# We don't need to stage anything, not the modules/firmware since those would clash with linux-firmware +sysroot_stage_all () { + : } -pkg_postrm_kernel () { - cd /${KERNEL_IMAGEDEST}; update-alternatives --remove ${KERNEL_IMAGETYPE} ${KERNEL_IMAGETYPE}-${KERNEL_VERSION} || true +KERNEL_CONFIG_COMMAND ?= "oe_runmake_call -C ${S} O=${B} oldnoconfig || yes '' | oe_runmake -C ${S} O=${B} oldconfig" + +python check_oldest_kernel() { + oldest_kernel = d.getVar('OLDEST_KERNEL') + kernel_version = d.getVar('KERNEL_VERSION') + tclibc = d.getVar('TCLIBC') + if tclibc == 'glibc': + kernel_version = kernel_version.split('-', 1)[0] + if oldest_kernel and kernel_version: + if bb.utils.vercmp_string(kernel_version, oldest_kernel) < 0: + bb.warn('%s: OLDEST_KERNEL is "%s" but the version of the kernel you are building is "%s" - therefore %s as built may not be compatible with this kernel. Either set OLDEST_KERNEL to an older version, or build a newer kernel.' % (d.getVar('PN'), oldest_kernel, kernel_version, tclibc)) +} + +check_oldest_kernel[vardepsexclude] += "OLDEST_KERNEL KERNEL_VERSION" +do_configure[prefuncs] += "check_oldest_kernel" + +kernel_do_configure() { + # fixes extra + in /lib/modules/2.6.37+ + # $ scripts/setlocalversion . => + + # $ make kernelversion => 2.6.37 + # $ make kernelrelease => 2.6.37+ + touch ${B}/.scmversion ${S}/.scmversion + + if [ "${S}" != "${B}" ] && [ -f "${S}/.config" ] && [ ! -f "${B}/.config" ]; then + mv "${S}/.config" "${B}/.config" + fi + + # Copy defconfig to .config if .config does not exist. This allows + # recipes to manage the .config themselves in do_configure_prepend(). + if [ -f "${WORKDIR}/defconfig" ] && [ ! -f "${B}/.config" ]; then + cp "${WORKDIR}/defconfig" "${B}/.config" + fi + + ${KERNEL_CONFIG_COMMAND} } +do_savedefconfig() { + bbplain "Saving defconfig to:\n${B}/defconfig" + oe_runmake -C ${B} savedefconfig +} +do_savedefconfig[nostamp] = "1" +addtask savedefconfig after do_configure + inherit cml1 -EXPORT_FUNCTIONS do_compile do_install do_stage do_configure +EXPORT_FUNCTIONS do_compile do_install do_configure # kernel-base becomes kernel-${KERNEL_VERSION} -# kernel-image becomes kernel-image-${KERNEL_VERISON} -PACKAGES = "kernel kernel-base kernel-image kernel-dev kernel-vmlinux" -FILES = "" -FILES_kernel-image = "/boot/${KERNEL_IMAGETYPE}*" -FILES_kernel-dev = "/boot/System.map* /boot/config*" -FILES_kernel-vmlinux = "/boot/vmlinux*" +# kernel-image becomes kernel-image-${KERNEL_VERSION} +PACKAGES = "kernel kernel-base kernel-vmlinux kernel-image kernel-dev kernel-modules" +FILES_${PN} = "" +FILES_kernel-base = "${nonarch_base_libdir}/modules/${KERNEL_VERSION}/modules.order ${nonarch_base_libdir}/modules/${KERNEL_VERSION}/modules.builtin" +FILES_kernel-image = "" +FILES_kernel-dev = "/boot/System.map* /boot/Module.symvers* /boot/config* ${KERNEL_SRC_PATH} ${nonarch_base_libdir}/modules/${KERNEL_VERSION}/build" +FILES_kernel-vmlinux = "/boot/vmlinux-${KERNEL_VERSION_NAME}" +FILES_kernel-modules = "" RDEPENDS_kernel = "kernel-base" -# Allow machines to override this dependency if kernel image files are +# Allow machines to override this dependency if kernel image files are # not wanted in images as standard RDEPENDS_kernel-base ?= "kernel-image" -PKG_kernel-image = "kernel-image-${KERNEL_VERSION}" -PKG_kernel-base = "kernel-${KERNEL_VERSION}" +PKG_kernel-image = "kernel-image-${@legitimize_package_name('${KERNEL_VERSION}')}" +RDEPENDS_kernel-image += "${@base_conditional('KERNEL_IMAGETYPE', 'vmlinux', 'kernel-vmlinux', '', d)}" +PKG_kernel-base = "kernel-${@legitimize_package_name('${KERNEL_VERSION}')}" +RPROVIDES_kernel-base += "kernel-${KERNEL_VERSION}" ALLOW_EMPTY_kernel = "1" ALLOW_EMPTY_kernel-base = "1" ALLOW_EMPTY_kernel-image = "1" +ALLOW_EMPTY_kernel-modules = "1" +DESCRIPTION_kernel-modules = "Kernel modules meta package" -# Userspace workarounds for kernel modules issues -# This is shame, fix the kernel instead! -DEPENDS_kernel-module-dtl1-cs = "bluez-dtl1-workaround" -RDEPENDS_kernel-module-dtl1-cs = "bluez-dtl1-workaround" - -pkg_postinst_kernel-image () { -if [ ! -e "$D/lib/modules/${KERNEL_VERSION}" ]; then - mkdir -p $D/lib/modules/${KERNEL_VERSION} -fi -if [ -n "$D" ]; then - ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} ${KERNEL_VERSION} -else - depmod -a -fi +pkg_postinst_kernel-base () { + if [ ! -e "$D/lib/modules/${KERNEL_VERSION}" ]; then + mkdir -p $D/lib/modules/${KERNEL_VERSION} + fi + if [ -n "$D" ]; then + depmodwrapper -a -b $D ${KERNEL_VERSION} + else + depmod -a ${KERNEL_VERSION} + fi } -pkg_postinst_modules () { -if [ -n "$D" ]; then - ${HOST_PREFIX}depmod-${KERNEL_MAJOR_VERSION} -A -b $D -F ${STAGING_KERNEL_DIR}/System.map-${KERNEL_VERSION} ${KERNEL_VERSION} -else - depmod -a - update-modules || true -fi -} +PACKAGESPLITFUNCS_prepend = "split_kernel_packages " -pkg_postrm_modules () { -update-modules || true +python split_kernel_packages () { + do_split_packages(d, root='${nonarch_base_libdir}/firmware', file_regex='^(.*)\.(bin|fw|cis|csp|dsp)$', output_pattern='kernel-firmware-%s', description='Firmware for %s', recursive=True, extra_depends='') } -autoload_postinst_fragment() { -if [ x"$D" = "x" ]; then - modprobe %s || true -fi +# Many scripts want to look in arch/$arch/boot for the bootable +# image. This poses a problem for vmlinux and vmlinuz based +# booting. This task arranges to have vmlinux and vmlinuz appear +# in the normalized directory location. +do_kernel_link_images() { + if [ ! -d "${B}/arch/${ARCH}/boot" ]; then + mkdir ${B}/arch/${ARCH}/boot + fi + cd ${B}/arch/${ARCH}/boot + ln -sf ../../../vmlinux + if [ -f ../../../vmlinuz ]; then + ln -sf ../../../vmlinuz + fi + if [ -f ../../../vmlinuz.bin ]; then + ln -sf ../../../vmlinuz.bin + fi } +addtask kernel_link_images after do_compile before do_strip -# autoload defaults (alphabetically sorted) -module_autoload_hidp = "hidp" -module_autoload_ipv6 = "ipv6" -module_autoload_ipsec = "ipsec" -module_autoload_ircomm-tty = "ircomm-tty" -module_autoload_rfcomm = "rfcomm" -module_autoload_sa1100-rtc = "sa1100-rtc" -# sa1100-rtc was renamed in 2.6.23 onwards -module_autoload_rtc-sa1100 = "rtc-sa1100" - -# alias defaults (alphabetically sorted) -module_conf_af_packet = "alias net-pf-17 af_packet" -module_conf_bluez = "alias net-pf-31 bluez" -module_conf_bnep = "alias bt-proto-4 bnep" -module_conf_hci_uart = "alias tty-ldisc-15 hci_uart" -module_conf_l2cap = "alias bt-proto-0 l2cap" -module_conf_sco = "alias bt-proto-2 sco" -module_conf_rfcomm = "alias bt-proto-3 rfcomm" - -python populate_packages_prepend () { - def extract_modinfo(file): - import os, re - tmpfile = os.tmpnam() - cmd = "PATH=\"%s\" %sobjcopy -j .modinfo -O binary %s %s" % (bb.data.getVar("PATH", d, 1), bb.data.getVar("HOST_PREFIX", d, 1) or "", file, tmpfile) - os.system(cmd) - f = open(tmpfile) - l = f.read().split("\000") - f.close() - os.unlink(tmpfile) - exp = re.compile("([^=]+)=(.*)") - vals = {} - for i in l: - m = exp.match(i) - if not m: - continue - vals[m.group(1)] = m.group(2) - return vals - - def parse_depmod(): - import os, re - - dvar = bb.data.getVar('D', d, 1) - if not dvar: - bb.error("D not defined") +do_strip() { + if [ -n "${KERNEL_IMAGE_STRIP_EXTRA_SECTIONS}" ]; then + if ! (echo "${KERNEL_IMAGETYPES}" | grep -wq "vmlinux"); then + bbwarn "image type(s) will not be stripped (not supported): ${KERNEL_IMAGETYPES}" return + fi + + cd ${B} + headers=`"$CROSS_COMPILE"readelf -S ${KERNEL_OUTPUT_DIR}/vmlinux | \ + grep "^ \{1,\}\[[0-9 ]\{1,\}\] [^ ]" | \ + sed "s/^ \{1,\}\[[0-9 ]\{1,\}\] //" | \ + gawk '{print $1}'` + + for str in ${KERNEL_IMAGE_STRIP_EXTRA_SECTIONS}; do { + if ! (echo "$headers" | grep -q "^$str$"); then + bbwarn "Section not found: $str"; + fi + + "$CROSS_COMPILE"strip -s -R $str ${KERNEL_OUTPUT_DIR}/vmlinux + }; done - kernelver = bb.data.getVar('KERNEL_VERSION', d, 1) - kernelver_stripped = kernelver - m = re.match('^(.*-hh.*)[\.\+].*$', kernelver) - if m: - kernelver_stripped = m.group(1) - path = bb.data.getVar("PATH", d, 1) - host_prefix = bb.data.getVar("HOST_PREFIX", d, 1) or "" - major_version = bb.data.getVar('KERNEL_MAJOR_VERSION', d, 1) - - cmd = "PATH=\"%s\" %sdepmod-%s -n -a -r -b %s -F %s/boot/System.map-%s %s" % (path, host_prefix, major_version, dvar, dvar, kernelver, kernelver_stripped) - f = os.popen(cmd, 'r') - - deps = {} - pattern0 = "^(.*\.k?o):..*$" - pattern1 = "^(.*\.k?o):\s*(.*\.k?o)\s*$" - pattern2 = "^(.*\.k?o):\s*(.*\.k?o)\s*\\\$" - pattern3 = "^\t(.*\.k?o)\s*\\\$" - pattern4 = "^\t(.*\.k?o)\s*$" - - line = f.readline() - while line: - if not re.match(pattern0, line): - line = f.readline() - continue - m1 = re.match(pattern1, line) - if m1: - deps[m1.group(1)] = m1.group(2).split() - else: - m2 = re.match(pattern2, line) - if m2: - deps[m2.group(1)] = m2.group(2).split() - line = f.readline() - m3 = re.match(pattern3, line) - while m3: - deps[m2.group(1)].extend(m3.group(1).split()) - line = f.readline() - m3 = re.match(pattern3, line) - m4 = re.match(pattern4, line) - deps[m2.group(1)].extend(m4.group(1).split()) - line = f.readline() - f.close() - return deps - - def get_dependencies(file, pattern, format): - file = file.replace(bb.data.getVar('D', d, 1) or '', '', 1) - - if module_deps.has_key(file): - import os.path, re - dependencies = [] - for i in module_deps[file]: - m = re.match(pattern, os.path.basename(i)) - if not m: - continue - on = legitimize_package_name(m.group(1)) - dependency_pkg = format % on - dependencies.append(dependency_pkg) - return dependencies - return [] - - def frob_metadata(file, pkg, pattern, format, basename): - import re - vals = extract_modinfo(file) - - dvar = bb.data.getVar('D', d, 1) - - # If autoloading is requested, output /etc/modutils/<name> and append - # appropriate modprobe commands to the postinst - autoload = bb.data.getVar('module_autoload_%s' % basename, d, 1) - if autoload: - name = '%s/etc/modutils/%s' % (dvar, basename) - f = open(name, 'w') - for m in autoload.split(): - f.write('%s\n' % m) - f.close() - postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) - if not postinst: - bb.fatal("pkg_postinst_%s not defined" % pkg) - postinst += bb.data.getVar('autoload_postinst_fragment', d, 1) % autoload - bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d) - - # Write out any modconf fragment - modconf = bb.data.getVar('module_conf_%s' % basename, d, 1) - if modconf: - if bb.data.getVar("KERNEL_MAJOR_VERSION", d, 1) == "2.6": - name = '%s/etc/modprobe.d/%s.conf' % (dvar, basename) - else: - name = '%s/etc/modutils/%s.conf' % (dvar, basename) - f = open(name, 'w') - f.write("%s\n" % modconf) - f.close() - - files = bb.data.getVar('FILES_%s' % pkg, d, 1) - files = "%s /etc/modutils/%s /etc/modutils/%s.conf /etc/modprobe.d/%s.conf" % (files, basename, basename, basename) - bb.data.setVar('FILES_%s' % pkg, files, d) - - if vals.has_key("description"): - old_desc = bb.data.getVar('DESCRIPTION_' + pkg, d, 1) or "" - bb.data.setVar('DESCRIPTION_' + pkg, old_desc + "; " + vals["description"], d) - - rdepends_str = bb.data.getVar('RDEPENDS_' + pkg, d, 1) - if rdepends_str: - rdepends = rdepends_str.split() - else: - rdepends = [] - rdepends.extend(get_dependencies(file, pattern, format)) - bb.data.setVar('RDEPENDS_' + pkg, ' '.join(rdepends), d) - - module_deps = parse_depmod() - module_regex = '^(.*)\.k?o$' - module_pattern = 'kernel-module-%s' - - postinst = bb.data.getVar('pkg_postinst_modules', d, 1) - postrm = bb.data.getVar('pkg_postrm_modules', d, 1) - do_split_packages(d, root='/lib/modules', file_regex=module_regex, output_pattern=module_pattern, description='%s kernel module', postinst=postinst, postrm=postrm, recursive=True, hook=frob_metadata, extra_depends='update-modules kernel-%s' % bb.data.getVar("KERNEL_VERSION", d, 1)) - - import re, os - metapkg = "kernel-modules" - bb.data.setVar('ALLOW_EMPTY_' + metapkg, "1", d) - bb.data.setVar('FILES_' + metapkg, "", d) - blacklist = [ 'kernel-dev', 'kernel-image', 'kernel-base', 'kernel-vmlinux' ] - for l in module_deps.values(): - for i in l: - pkg = module_pattern % legitimize_package_name(re.match(module_regex, os.path.basename(i)).group(1)) - blacklist.append(pkg) - metapkg_rdepends = [] - packages = bb.data.getVar('PACKAGES', d, 1).split() - for pkg in packages[1:]: - if not pkg in blacklist and not pkg in metapkg_rdepends: - metapkg_rdepends.append(pkg) - bb.data.setVar('RDEPENDS_' + metapkg, ' '.join(metapkg_rdepends), d) - bb.data.setVar('DESCRIPTION_' + metapkg, 'Kernel modules meta package', d) - packages.append(metapkg) - bb.data.setVar('PACKAGES', ' '.join(packages), d) + bbnote "KERNEL_IMAGE_STRIP_EXTRA_SECTIONS is set, stripping sections:" \ + "${KERNEL_IMAGE_STRIP_EXTRA_SECTIONS}" + fi; } +do_strip[dirs] = "${B}" + +addtask strip before do_sizecheck after do_kernel_link_images # Support checking the kernel size since some kernels need to reside in partitions # with a fixed length or there is a limit in transferring the kernel to memory do_sizecheck() { if [ ! -z "${KERNEL_IMAGE_MAXSIZE}" ]; then - size=`ls -l arch/${ARCH}/boot/${KERNEL_IMAGETYPE} | awk '{ print $5}'` - if [ $size -ge ${KERNEL_IMAGE_MAXSIZE} ]; then - rm arch/${ARCH}/boot/${KERNEL_IMAGETYPE} - die "This kernel (size=$size > ${KERNEL_IMAGE_MAXSIZE}) is too big for your device. Please reduce the size of the kernel by making more of it modular." - fi - fi + invalid=`echo ${KERNEL_IMAGE_MAXSIZE} | sed 's/[0-9]//g'` + if [ -n "$invalid" ]; then + die "Invalid KERNEL_IMAGE_MAXSIZE: ${KERNEL_IMAGE_MAXSIZE}, should be an integerx (The unit is Kbytes)" + fi + for type in ${KERNEL_IMAGETYPES} ; do + size=`du -ks ${B}/${KERNEL_OUTPUT_DIR}/$type | awk '{print $1}'` + if [ $size -ge ${KERNEL_IMAGE_MAXSIZE} ]; then + warn "This kernel $type (size=$size(K) > ${KERNEL_IMAGE_MAXSIZE}(K)) is too big for your device. Please reduce the size of the kernel by making more of it modular." + fi + done + fi } +do_sizecheck[dirs] = "${B}" + +addtask sizecheck before do_install after do_strip + +KERNEL_IMAGE_BASE_NAME ?= "${PKGE}-${PKGV}-${PKGR}-${MACHINE}-${DATETIME}" +# Don't include the DATETIME variable in the sstate package signatures +KERNEL_IMAGE_BASE_NAME[vardepsexclude] = "DATETIME" +KERNEL_IMAGE_SYMLINK_NAME ?= "${MACHINE}" +MODULE_IMAGE_BASE_NAME ?= "modules-${PKGE}-${PKGV}-${PKGR}-${MACHINE}-${DATETIME}" +MODULE_IMAGE_BASE_NAME[vardepsexclude] = "DATETIME" +MODULE_TARBALL_BASE_NAME ?= "${MODULE_IMAGE_BASE_NAME}.tgz" +# Don't include the DATETIME variable in the sstate package signatures +MODULE_TARBALL_SYMLINK_NAME ?= "modules-${MACHINE}.tgz" +MODULE_TARBALL_DEPLOY ?= "1" + +kernel_do_deploy() { + for type in ${KERNEL_IMAGETYPES} ; do + base_name=${type}-${KERNEL_IMAGE_BASE_NAME} + install -m 0644 ${KERNEL_OUTPUT_DIR}/${type} ${DEPLOYDIR}/${base_name}.bin + done + if [ ${MODULE_TARBALL_DEPLOY} = "1" ] && (grep -q -i -e '^CONFIG_MODULES=y$' .config); then + mkdir -p ${D}/lib + tar -cvzf ${DEPLOYDIR}/${MODULE_TARBALL_BASE_NAME} -C ${D} lib + ln -sf ${MODULE_TARBALL_BASE_NAME} ${DEPLOYDIR}/${MODULE_TARBALL_SYMLINK_NAME} + fi -addtask sizecheck before do_install after do_compile - -KERNEL_IMAGE_BASE_NAME ?= "${KERNEL_IMAGETYPE}-${PV}-${PR}-${MACHINE}-${DATETIME}" -KERNEL_IMAGE_SYMLINK_NAME ?= "${KERNEL_IMAGETYPE}-${MACHINE}" - -do_deploy() { - install -d ${DEPLOY_DIR_IMAGE} - install -m 0644 arch/${ARCH}/boot/ |
