#!/bin/bash # Create packages for the kernel(s) used on a specific platform. # Inspiration taken from Slackware and ARMedslack. # Written by Eric Hameleers , Eindhoven, The Netherlands PLATFORM=${1:-tegra} KVER=${KVER:-3.8.4} BUILD=${BUILD:-1} case "$PLATFORM" in generic*|huge*) ARCH=${ARCH:-x86_64} KARCH=${ARCH} HEADERS_ARCH=${x86} MODULES=${MODULES:-ext4} ;; tegra|beagleboard|exynos5) ARCH=${ARCH:-armv7hl} KARCH=arm HEADERS_ARCH=arm MODULES=${MODULES:-ext4} ;; *) ARCH=${ARCH:-arm} KARCH=arm HEADERS_ARCH=arm MODULES=${MODULES:-ext4} ;; esac KCONF=${KCONF:-oldconfig} CWD=$(pwd) TMP=${TMP:-/tmp} TMPBUILD=$TMP/tmpbuild-$KVER-$PLATFORM NUMJOBS=7 OUTPUT=/tmp/$ARCH rm -rf $OUTPUT mkdir -p $OUTPUT # Only meant for the "prep" stage which can be run by a non-root user: if [ $(/bin/id -u) -eq 0 ]; then SRC="/usr/src" else SRC=$TMP mkdir -p $SRC fi # Determine patch level required & apply the patch (taken from armedslack): function auto_apply_patch () { patchfile=$1 # Decompress the patch if it's compressed with a known method: FTYPE=$( file $patchfile ) case "$FTYPE" in *xz*compressed*) xz -dc $patchfile > $TMP/$(basename $patchfile).unpacked patchfile=$TMP/$(basename $patchfile).unpacked ;; *bzip2*compressed*) bzcat -f $patchfile > $TMP/$(basename $patchfile).unpacked patchfile=$TMP/$(basename $patchfile).unpacked ;; *gzip*compressed*) zcat -f $patchfile > $TMP/$(basename $patchfile).unpacked patchfile=$TMP/$(basename $patchfile).unpacked ;; esac # By now the patch is decompressed or wasn't compressed originally. # Most patches should not require more levels than this: success=0 for (( pl=0 ; pl<=5 ; pl++ )) ; do echo "Patch : $patchfile , trying patch level $pl" patch -N --fuzz=20 -t --dry-run -p$pl < $patchfile > /dev/null 2>&1 && success=1 && break done if [ $success = 1 ]; then echo "Patch: $patchfile will apply at level $pl" patch -N --fuzz=20 --verbose --backup --suffix=.orig -p$pl < $patchfile return 0 else echo "Patch: $patchfile failed to apply at levels 0-5" return 1 fi } patch_kernel() { if [ -d $CWD/sources/patches/$PLATFORM/$KVER ]; then PATCHDIR=$CWD/sources/patches/$PLATFORM/$KVER elif [ -d $CWD/sources/patches/$PLATFORM ]; then PATCHDIR=$CWD/sources/patches/$PLATFORM elif [ -d $CWD/sources/patches/generic ]; then PATCHDIR=$CWD/sources/patches/generic else return 0 fi ( cd $SRC/linux-${KVER} for PATCHFILE in $(find $PATCHDIR -type f); do auto_apply_patch $PATCHFILE || exit 1 done ) || exit 1 } echo "Extracting kernel source to $SRC/linux-${KVER} ..." # This will delete your current source tree for this kernel! rm -rf $SRC/linux-${KVER} ( cd $SRC for EXT in xz bz2 ; do if [ -f $CWD/sources/kernel/$PLATFORM/linux-${KVER}.tar.$EXT ]; then tar xf $CWD/sources/kernel/$PLATFORM/linux-${KVER}.tar.$EXT continue elif [ -f $CWD/sources/kernel/linux-${KVER}.tar.$EXT ]; then tar xf $CWD/sources/kernel/linux-${KVER}.tar.$EXT continue fi done if [ ! $? = 0 ]; then echo "FATAL: Error unpacking the kernel archive... aborting." exit 1 elif [ ! -d linux-${KVER} ]; then echo "FATAL: Kernel directory was not found... aborting." exit 1 else cd linux-${KVER} # Apply patches to the kernel source: patch_kernel || exit 1 # Add firmware files: find $CWD/sources/firmware/$PLATFORM -type f \ -exec tar -C $SRC/linux-${KVER}/firmware -xvf {} \; case "$PLATFORM" in tegra) # Build fix for compiling Tegra USB support as modules: sed -i '/obj-$(CONFIG_USB_COMMON).*+= phy\// a\obj-$(CONFIG_USB_EHCI_TEGRA) += phy\/' drivers/usb/Makefile || exit 1 ;; esac chown -R root:root . echo "Fixing permissions... takes a long time in a VM or on ARM..." find . -perm 666 -exec chmod 644 {} \; find . -perm 664 -exec chmod 644 {} \; find . -perm 600 -exec chmod 644 {} \; find . -perm 444 -exec chmod 644 {} \; find . -perm 400 -exec chmod 644 {} \; find . -perm 440 -exec chmod 644 {} \; find . -perm 777 -exec chmod 755 {} \; find . -perm 775 -exec chmod 755 {} \; find . -perm 511 -exec chmod 755 {} \; find . -perm 711 -exec chmod 755 {} \; find . -perm 555 -exec chmod 755 {} \; fi ) # Patched kernel source is ready to configure now: if [ -f $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} ]; then if ! grep -q "CONFIG_LOCALVERSION=\"-$PLATFORM\"" $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} ; then echo "*******************************************************************" echo "WARNING:" echo "CONFIG_LOCALVERSION not set to '-$PLATFORM'" echo "in $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER}" echo "Are you certain you want to continue? Else press Ctrl-C now!" echo "*******************************************************************" read JUNK fi echo "Using $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} ..." install -m0644 $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} \ $SRC/linux-${KVER}/.config fi # Add our patches to the kernel source directory: unset PATCHDIR if [ -d $CWD/sources/patches/$PLATFORM/$KVER ]; then PATCHDIR=$CWD/sources/patches/$PLATFORM/$KVER elif [ -d $CWD/sources/patches/$KVER ]; then PATCHDIR=$CWD/sources/patches/$KVER elif [ -d $CWD/sources/patches/generic ]; then PATCHDIR=$CWD/sources/patches/generic fi if [ -n "$PATCHDIR" ]; then for file in $(find $PATCHDIR -type f) ; do install -m0644 $file $SRC/linux-${KVER}/$(basename $file) done fi # End of preparations if echo "$*" | grep -qw -- --prep ; then exit 0 fi # Everything below this line must be executed by root user (SRC no longer used): # Prepare the kernel source for packaging: ( cd /usr/src/linux-${KVER} # This is where you optionally create a new kernel configuration: ARCH=$KARCH make $KCONF ARCH=$KARCH make oldconfig 1>/dev/null 2>&1 # Run a test build, and clean up after: ARCH=$KARCH make -j ${NUMJOBS} || exit 1 ARCH=$KARCH make clean # This makes sure that bounds.h is included: ARCH=$KARCH make prepare find . -name ".*tmp*" -exec rm "{}" \; find . -name *zImage -exec rm "{}" \; find . -name *.o -exec rm "{}" \; #find . -name modules.builtin -exec rm "{}" \; #find . -name modules.order -exec rm "{}" \; rm -f .config.old rm .version ) # Make kernel-source package: mkdir -p $OUTPUT/package-kernel-source/usr/src ( cd $OUTPUT/package-kernel-source/usr/src mv /usr/src/linux-${KVER} . ln -sf linux-${KVER} linux cd $OUTPUT/package-kernel-source mkdir -p install cat $CWD/slack-desc/slack-desc.kernel-source > install/slack-desc /sbin/makepkg -l y -c n ../kernel-source-$(echo ${KVER}-${PLATFORM} | tr - _)-noarch-$BUILD.txz rm -rf $OUTPUT/package-kernel-source ) mkdir -p $OUTPUT/packages/linux-${KVER} mv $OUTPUT/kernel-source*txz $OUTPUT/packages/linux-${KVER} # Install the kernel-source package we just created: rm -rf /usr/src/linux-$KVER installpkg $OUTPUT/packages/linux-${KVER}/kernel-source-$(echo ${KVER}-${PLATFORM} | tr - _)-noarch-$BUILD.txz # If we did just create a new .config file, secure it: if [ ! -e $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} ]; then install -m0644 /usr/src/linux-${KVER}/.config $CWD/configs-${ARCH}/config-${PLATFORM}-${KVER} fi # Copy the config file to the source directory as well: mkdir -p $OUTPUT/source/linux-${KVER} cp -a /usr/src/linux-${KVER}/.config $OUTPUT/source/linux-${KVER}/config-${PLATFORM}-${KVER} # Create the kernel-headers package: rm -rf $OUTPUT/package-kernel-headers mkdir -p $OUTPUT/package-kernel-headers/usr ( cd /usr/src/linux-${KVER} make headers_install ARCH=${HEADERS_ARCH} INSTALL_HDR_PATH=$OUTPUT/package-kernel-headers/usr cd $OUTPUT/package-kernel-headers/usr/include || exit 1 # Remove the kernel-headers version of /usr/include/scsi/scsi.h # - we use the file included with glibc. rm -f scsi/scsi.h mv asm asm-${HEADERS_ARCH} ln -sf asm-${HEADERS_ARCH} asm find . -name ".??*" -exec rm -f {} \; cd $OUTPUT/package-kernel-headers mkdir -p install cat $CWD/slack-desc/slack-desc.kernel-headers > install/slack-desc makepkg -l y -c n ../kernel-headers-$(echo ${KVER}-${PLATFORM} | tr - _)-$HEADERS_ARCH-$BUILD.txz ) rm -rf $OUTPUT/package-kernel-headers mv $OUTPUT/kernel-headers*txz $OUTPUT/packages/linux-${KVER} echo "Compiling the kernel..." # Next step, compile the kernel: ( cd /usr/src/linux-${KVER} ARCH=$KARCH make -j ${NUMJOBS} || exit 1 case "$HEADERS_ARCH" in arm) #ARCH=$KARCH make zImage || exit 1 # Build the U-Boot image: ARCH=$KARCH make uImage || exit 1 case "$PLATFORM" in exynos5) # Create .dtb files ARCH=$KARCH make dtbs # Create FIT image for nv-U-boot: cp $CWD/its/${PLATFORM}.its arch/${HEADERS_ARCH}/boot/kernel.its cd arch/${HEADERS_ARCH}/boot mkimage -f kernel.its zImage cp -v zImage zImage.uimg ;; esac mkdir -p $OUTPUT/kernels/$PLATFORM cp -a /usr/src/linux-${KVER}/System.map $OUTPUT/kernels/$PLATFORM/System.map gzip -9 $OUTPUT/kernels/$PLATFORM/System.map cp -a /usr/src/linux-${KVER}/.config $OUTPUT/kernels/$PLATFORM/config # One or more of these kernel images may not exist for your platform: cp -a /usr/src/linux-${KVER}/arch/${HEADERS_ARCH}/boot/zImage $OUTPUT/kernels/$PLATFORM/zImage cp -a /usr/src/linux-${KVER}/arch/${HEADERS_ARCH}/boot/zImage.uimg $OUTPUT/kernels/$PLATFORM/zImage.uimg cp -a /usr/src/linux-${KVER}/arch/${HEADERS_ARCH}/boot/uImage $OUTPUT/kernels/$PLATFORM/uImage ;; *) ARCH=$KARCH make bzImage || exit 1 mkdir -p $OUTPUT/kernels/$PLATFORM cp -a /usr/src/linux-${KVER}/System.map $OUTPUT/kernels/$PLATFORM/System.map gzip -9 $OUTPUT/kernels/$PLATFORM/System.map cp -a /usr/src/linux-${KVER}/.config $OUTPUT/kernels/$PLATFORM/config cp -a /usr/src/linux-${KVER}/arch/${HEADERS_ARCH}/boot/bzImage $OUTPUT/kernels/$PLATFORM/bzImage ;; esac ) || exit 1 # We will package the kernel later. # At this point, we need to check the actual kernel release. It may be different # than the version of the source tarball (3.4 -> 3.4.0 for instance): # The value $KREL will be used in module directory etc. KREL=$(cat /usr/src/linux-${KVER}/include/config/kernel.release) echo "Building modules for ${KREL}..." # Note: this deletes your existing module directory! rm -rf /lib/modules/${KREL} ( cd /usr/src/linux-${KVER} ARCH=$KARCH make -j ${NUMJOBS} modules || exit 1 echo "Installing kernel modules..." ARCH=$KARCH make modules_install || exit 1 ) || exit 1 # Calculate module dependencies now, so that we can run mkinitrd later: echo "Calculating module dependencies for $KREL..." rm -f /lib/modules/$KREL/modules.* /sbin/depmod -a -e -b / -F /usr/src/linux-${KVER}/System.map $KREL echo "Building the kernel-modules package..." mkdir -p $OUTPUT/package-kernel-modules-$PLATFORM ( cd $OUTPUT/package-kernel-modules-$PLATFORM mkdir -p lib/modules cp -a /lib/modules/${KREL} lib/modules/ mkdir -p etc/rc.d cat $CWD/sources/modules/rc.modules.new > etc/rc.d/rc.modules-${KREL}.new chmod 755 etc/rc.d/rc.modules-${KREL}.new mkdir -p install cat $CWD/slack-desc/slack-desc.kernel-modules > install/slack-desc makepkg -l y -c n ../kernel-modules-$PLATFORM-$(echo ${KVER}-${PLATFORM} | tr - _)-$ARCH-$BUILD.txz ) rm -rf $OUTPUT/package-kernel-modules-$PLATFORM mkdir -p $OUTPUT/packages/linux-${KVER} mv $OUTPUT/kernel-modules-$PLATFORM*txz $OUTPUT/packages/linux-${KVER} installpkg $OUTPUT/packages/linux-${KVER}/kernel-modules-$PLATFORM-$(echo ${KVER}-${PLATFORM} | tr - _)-${ARCH}-${BUILD}.txz # For the arm kernels, we use a U-Boot "generic" kernel plus initrd: # Generic requirements: # Filesystems: INITRDFS="vfat:jbd:jbd2:nls:exportfs:binfmt_misc:md:dm-mod:mbcache:ext2:ext3:ext4:reiserfs:jfs:xfs:fscache" # Generic SCSI drivers & low-level drivers for discs/media: INITRDSCSI="sg:scsi_mod:sd_mod:cdrom:sr_mod:scsi_tgt:mmc_block" # Network filesystems: INITRDNETFS="nfs:lockd:nfs_common" # USB hubs & support mods, including interface devices (USB keyboards etc) # followed by some specific device drivers. INITRDUSB="ehci-hcd:uhci_hcd:usbhid:ohci_hcd:hid:usbcore:usb-storage:ums-cypress:ums-usbat:ums-freecom:ums-isd200:ums-sddr09:ums-sddr55:ums-alauda:ums-jumpshot:ums-onetouch" # For SDHC cards: INITRDCARDS="mvsdio" # Additional stuff such as Netconsole (useful for debugging on machines without a serial cable) # Note: ':' at the beginning is on purpose! # INITRDADDITIONS=":netconsole" case "$PLATFORM" in tegra) # Network interface card: # This one needs a binary blob, which we patch into the kernel. INITRDNETDEV="r8169" # SATA support: # The Trimslice's SATA is on an internal USB host. INITRDSATA="libata" # Console video: # The Trimslice uses the Tegra module, # which we need to compile into the Kernel. #INITRDVIDEO="xgifb" # Subsystems for System on Chip - SoC: # (Some of these may not be required) INITRDSOC="i2c-tegra:rtc-em3027:spi-tegra" # Wait 6 seconds for the USB discs to spin up. mkinitrd \ -R \ -L \ -u \ -w 6 \ -k $KREL \ -s $TMPBUILD/initrd-tree \ -m $INITRDSOC:$INITRDSCSI:$INITRDSATA:$INITRDUSB:$INITRDFS:$INITRDNETDEV:$INITRDNETFS:$INITRDCARDS${INITRDADDITIONS} \ -o /initrd-$PLATFORM.gz #-o $OUTPUT/kernels/$PLATFORM/initrd-$PLATFORM.gz # Creating it in / avoids an ugly bit of output at boot that contains # the path where it was built. It just looks nicer this way :-) mkdir -p $OUTPUT/kernels/$PLATFORM mv -fv /initrd-$PLATFORM.gz $OUTPUT/kernels/$PLATFORM/ # Create a uInitrd for U-boot: cd $TMPBUILD mkimage \ -A arm \ -O linux \ -T ramdisk \ -C gzip \ -n "Slackware ARM-$PLATFORM Initial RAM disk" \ -d $OUTPUT/kernels/$PLATFORM/initrd-$PLATFORM.gz \ $OUTPUT/kernels/$PLATFORM/uinitrd-$PLATFORM ;; exynos5) # Network interface card: #INITRDNETDEV="" # SATA support: #INITRDSATA="" # Console video: #INITRDVIDEO="" # Subsystems for System on Chip - SoC: # (Some of these may not be required) INITRDSOC="i2c-tegra:rtc-em3027:spi-tegra" mkinitrd \ -R \ -L \ -u \ -k $KREL \ -s $TMPBUILD/initrd-tree \ -m $INITRDSOC:$INITRDSCSI:$INITRDSATA:$INITRDUSB:$INITRDFS:$INITRDNETDEV:$INITRDNETFS:$INITRDCARDS${INITRDADDITIONS} \ -o /initrd-$PLATFORM.gz #-o $OUTPUT/kernels/$PLATFORM/initrd-$PLATFORM.gz # Creating it in / avoids an ugly bit of output at boot that contains # the path where it was built. It just looks nicer this way :-) mkdir -p $OUTPUT/kernels/$PLATFORM mv -fv /initrd-$PLATFORM.gz $OUTPUT/kernels/$PLATFORM/ # Create a uInitrd for U-boot: cd $TMPBUILD mkimage \ -A arm \ -O linux \ -T ramdisk \ -C gzip \ -n "Slackware ARM-$PLATFORM Initial RAM disk" \ -d $OUTPUT/kernels/$PLATFORM/initrd-$PLATFORM.gz \ $OUTPUT/kernels/$PLATFORM/uinitrd-$PLATFORM ;; *) ;; esac # Make kernel package: echo "Building the kernel-$PLATFORM package..." mkdir -p $OUTPUT/package-kernel-$PLATFORM ( cd $OUTPUT/package-kernel-$PLATFORM if [ -f $OUTPUT/kernels/$PLATFORM/uImage ]; then KERNEL=$OUTPUT/kernels/$PLATFORM/uImage elif [ -f $OUTPUT/kernels/$PLATFORM/zImage ]; then KERNEL=$OUTPUT/kernels/$PLATFORM/zImage else KERNEL=$OUTPUT/kernels/$PLATFORM/bzImage fi mkdir -p boot cp $KERNEL boot/uImage-$PLATFORM-${KVER} ( cd boot ; ln -sf uImage-$PLATFORM-${KVER} uImage-$PLATFORM ) gunzip -cd $OUTPUT/kernels/$PLATFORM/System.map.gz > boot/System.map-$PLATFORM-${KVER} ( cd boot ; ln -sf System.map-$PLATFORM-${KVER} System.map-$PLATFORM ) cp $OUTPUT/kernels/$PLATFORM/config boot/config-$PLATFORM-${KVER} ( cd boot ; ln -sf config-$PLATFORM-${KVER} config-$PLATFORM ) # Put a copy of the initial RAM disk into the $PKG's /boot # This allows devices whose boot loader can read the partition where # /boot resides can have a generic initrd to boot into after installation. # This 'uinitrd' is for devices using the 'Das U-Boot' Linux loader. install -pm644 $OUTPUT/kernels/$PLATFORM/uinitrd-$PLATFORM boot/uinitrd-$PLATFORM-$KVER ( cd boot ; ln -sf uinitrd-$PLATFORM-$KVER uinitrd-$PLATFORM ) mkdir -p install cat $CWD/slack-desc/slack-desc.kernel-$PLATFORM > install/slack-desc /sbin/makepkg -l y -c n ../kernel-$PLATFORM-$(echo ${KVER}-${PLATFORM} | tr - _)-$ARCH-$BUILD.txz ) rm -rf $OUTPUT/package-kernel-$PLATFORM mkdir -p $OUTPUT/packages/linux-${KVER} mv $OUTPUT/kernel-$PLATFORM*txz $OUTPUT/packages/linux-${KVER} installpkg $OUTPUT/packages/linux-${KVER}/kernel-$PLATFORM-$(echo ${KVER}-${PLATFORM} | tr - _)-${ARCH}-${BUILD}.txz # The end.