#!/bin/bash source /etc/make.conf progname=cl-kernel SHORTOPTS="k:c:t:n:v:e:rh" LONGOPTS="help,no-install,kerneldir:,kernel-config:,make-tarball:,kernel-name:,kernel-version:,kernel-extraversion:,remove-splash,no-clean,menuconfig" print_help() { cat <<'EOF' Usage: ${progname} [options] [DESTINATION] Make kernel. Options: -h, --help Print this help message -k, --kerneldir DIR Location of the kernel sources -c, --kernel-config FILE Kernel configuration file to use for compilation -t, --make-tarball FILE Make archive containing kernel,initramfs and modules. -n, --kernel-name NAME Tag the kernel and ramdisk with a name: If not defined the option defaults to 'calculate' -e, --extraversion VER Specify extraversion for kernel -v, --kernel-version VER Specify version for kernel -r, --remove-splash Remove splash images from initramfs. --no-clean Do not run make clean before compilation --menuconfig Run menuconfig after oldconfig Examples: The most common use is to run it like this, which build and install current kernel. $ makekernel EOF } parse_kernel_version() { if [[ ${KERNEL_VERSION} =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)([-.].+)?$ ]] then # version kernel KV_MAJOR=${BASH_REMATCH[1]} KV_MINOR=${BASH_REMATCH[2]} KV_PATCH=${BASH_REMATCH[3]} [[ -z $1 ]] && KV_TYPE=${BASH_REMATCH[4]} || KV_TYPE=$1 KERNEL_VERSION=${KV_MAJOR}.${KV_MINOR}.${KV_PATCH}${KV_TYPE} else echo "Wrong kernel version: ${KERNEL_VERSION}" exit 0 fi } warning() { echo "Warning:"$1 1>&2 } die() { echo 1>&2 echo "Error:"$1 1>&2 exit 1 } set_kernel_version() { sed -ri "s/^VERSION = .*$/VERSION = $KV_MAJOR/" ${KERNEL_DIR}/Makefile sed -ri "s/^PATCHLEVEL = .*$/PATCHLEVEL = $KV_MINOR/" ${KERNEL_DIR}/Makefile sed -ri "s/^SUBLEVEL = .*$/SUBLEVEL = $KV_PATCH/" ${KERNEL_DIR}/Makefile sed -ri "s/^EXTRAVERSION = .*$/EXTRAVERSION = $KV_TYPE/" ${KERNEL_DIR}/Makefile } initramfs_unpack() { mkdir -p tmp/initramfs || die "Catn't create temporary directory for initramfs" pushd tmp/initramfs >/dev/null # unpack initramfs gzip -dc ${BOOT_DIR}/initramfs-${KERNEL_NAME}-*-${KERNEL_VERSION} | cpio -di &>/dev/null || die "Cann't unpack initramfs" # remove old initramfs rm ${BOOT_DIR}/initramfs-${KERNEL_NAME}-*-${KERNEL_VERSION} || warning "Cann't remove old initramfs" } initramfs_clean() { # remove sound moudles find -name sound -exec rm -rf {} \; &>/dev/null # remove splash images if need [[ ${REMOVE_SPLASH} == 'true' ]] && rm etc/splash/tty1/images/* >/dev/null } initramfs_pack() { # pack new initramfs find * | cpio -o --quiet -H newc | gzip -9 >${BOOT_DIR}/initramfs-${KERNEL_NAME}-${KERNEL_VERSION} || die "Cann't pack initramfs" popd &>/dev/null rm -rf tmp/initramfs || warning "Cann't remove temporary directory with contents of initramfs" } rename_kernel_systemmap() { # rename kernel mv ${BOOT_DIR}/kernel-${KERNEL_NAME}-*-${KERNEL_VERSION} ${BOOT_DIR}/linux-${KERNEL_NAME}-${KERNEL_VERSION} || die "Cann't rename kernel" # change System.map [[ -e ${BOOT_DIR}/System.map-${KERNEL_NAME}-${KERNEL_VERSION} ]] && mv ${BOOT_DIR}/System.map-${KERNEL_NAME}-${KERNEL_VERSION} ${BOOT_DIR}/System.map-${KERNEL_NAME}-${KERNEL_VERSION}.old mv ${BOOT_DIR}/System.map-${KERNEL_NAME}-*-${KERNEL_VERSION} ${BOOT_DIR}/System.map-${KERNEL_NAME}-${KERNEL_VERSION} || die "Cann't rename System.map" } install_kernel() { # change kernel rm -f ${BOOT_DIR}/vmlinuz.old [[ -e ${BOOT_DIR}/vmlinuz ]] && mv ${BOOT_DIR}/vmlinuz ${BOOT_DIR}/vmlinuz.old ln -sf linux-${KERNEL_NAME}-${KERNEL_VERSION} ${BOOT_DIR}/vmlinuz # change initramfs [[ -e ${BOOT_DIR}/initrd ]] && mv ${BOOT_DIR}/initrd ${BOOT_DIR}/initrd.old [[ -e ${BOOT_DIR}/initrd-install ]] && mv ${BOOT_DIR}/initrd-install ${BOOT_DIR}/initrd-install.old mv ${BOOT_DIR}/initramfs-${KERNEL_NAME}-${KERNEL_VERSION} ${BOOT_DIR}/initrd cp ${BOOT_DIR}/initrd ${BOOT_DIR}/initrd-install # copy config [[ -e ${BOOT_DIR}/config-${KERNEL_NAME}-${KERNEL_VERSION} ]] && \ mv ${BOOT_DIR}/config-${KERNEL_NAME}-${KERNEL_VERSION} ${BOOT_DIR}/config-${KERNEL_NAME}-${KERNEL_VERSION}.old cp ${KERNEL_CONFIG} ${BOOT_DIR}/config-${KERNEL_NAME}-${KERNEL_VERSION} # set new current kernel if [[ ${KERNEL_DIR} != '/usr/src/linux' ]] then # if source place in /usr/src if [[ ${KERNEL_DIR} =~ ^/usr/src/([^/]+)$ ]] then rm /usr/src/linux && ln -sf ${BASH_REMATCH[1]} /usr/src/linux else # is specifed absolutly path if [[ ${KERNEL_DIR:0:1} == '/' ]] then rm /usr/src/linux && ln -sf ${KERNEL_DIR} /usr/src/linux fi fi fi } make_tarball() { # remove symlink for tarball find lib -type l -delete || warning "Cann't delete symbolic links" tar cjf ${KERNEL_TARBALL} boot lib || die "Cann't create kernel tarbal" } OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "$progname" -- "$@") if [ $? -ne 0 ]; then echo "'$progname --help' for more information" 1>&2 exit 1 fi eval set -- "$OPTS" KERNEL_DIR= KERNEL_CONFIG= KERNEL_TARBALL= KERNEL_NAME=calculate KERNEL_VERSION= DESTINATION= KERNEL_EXTRAVERSION= REMOVE_SPLASH=false ARCH=`arch` NO_INSTALL=false NOCLEAN="" MENUCONFIG="" while [ $# -gt 0 ]; do case $1 in -h|--help) print_help exit 0 ;; --menuconfig) MENUCONFIG="--menuconfig" shift ;; --no-clean) NOCLEAN="--no-clean" shift ;; -k|--kerneldir) KERNEL_DIR=$2 shift 2 ;; -c|--kernel-config) KERNEL_CONFIG=$2 shift 2 ;; -t|--make-tarball) KERNEL_TARBALL=$2 shift 2 ;; -r|--remove-splash) REMOVE_SPLASH=true shift ;; -n|--kernel-name) KERNEL_NAME=$2 shift 2 ;; -v|--kernel-version) KERNEL_VERSION=$2 shift 2 ;; -e|--extraversion) KERNEL_EXTRAVERSION=$2 shift 2 ;; --no-install) NO_INSTALL=true shift ;; --) shift ;; *) if [[ -z ${DESTINATION} ]] then DESTINATION=$1 shift else echo "Error: unknown second option: $1" 1>&2 exit 1 fi ;; esac done [[ -z ${KERNEL_DIR} ]] && KERNEL_DIR="/usr/src/linux" [[ -e ${KERNEL_DIR}/Makefile ]] || die "Wrong kernel sources directory: ${KERNEL_DIR}" [[ -z ${KERNEL_CONFIG} ]] && KERNEL_CONFIG="${KERNEL_DIR}/.config.bak" [[ -z ${DESTINATION} ]] && DESTINATION="/" # if kernel_version not defined get it from Makefile of sources [[ -z ${KERNEL_VERSION} ]] && \ KERNEL_VERSION=`grep -e ^VERSION -e ^PATCHLEVEL -e ^SUBLEVEL -e ^EXTRAVERSION \ ${KERNEL_DIR}/Makefile \ | sed -rn "{N;N;N;s/PATCHLEVEL = |SUBLEVEL = /./g;s/EXTRAVERSION = |VERSION = |\n//g;p}"` MODULE_INS_PATH=${DESTINATION} mkdir -p ${DESTINATION} # tarball should be created in empty directory if [[ -n ${KERNEL_TARBALL} ]] && [[ $(ls $DESTINATION | wc -l ) -gt 2 ]]; then die "tarball should be created in empty directory" fi BOOT_DIR=${DESTINATION%/}/boot parse_kernel_version ${KERNEL_EXTRAVERSION} set_kernel_version mkdir -p ${BOOT_DIR} # run generating kernel genkernel --splash=tty1 --unionfs --all-ramdisk-modules --disklabel --slowusb --kerneldir=${KERNEL_DIR} --module-prefix=${MODULE_INS_PATH} --makeopts=${MAKEOPTS} ${NOCLEAN} ${MENUCONFIG} --no-save-config --kernel-config=${KERNEL_CONFIG} --kernname=${KERNEL_NAME} --bootdir=${BOOT_DIR} all [[ $? -ne 0 ]] && die "kernel was not builded" pushd ${DESTINATION} &>/dev/null initramfs_unpack initramfs_clean initramfs_pack rename_kernel_systemmap [[ -n ${KERNEL_TARBALL} ]] && make_tarball || install_kernel