diff --git a/README.md b/README.md index d80722b..f2da0f4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Build dependencies The following list of Debian packages must be installed on the build system because they are essentially required for the bootstrapping process. The script will check if all required packages are installed and missing packages will be installed automatically if confirmed by the user. - ```debootstrap debian-archive-keyring qemu-user-static dosfstools rsync bmap-tools whois git-core``` + ```debootstrap debian-archive-keyring qemu-user-static binfmt-support dosfstools rsync bmap-tools whois git-core``` ## Command-line parameters The script accepts certain command-line parameters to enable or disable specific OS features, services and configuration settings. These parameters are passed to the `rpi2-gen-image.sh` script via (simple) shell-variables. Unlike environment shell-variables (simple) shell-variables are defined at the beginning of the command-line call of the `rpi2-gen-image.sh` script. @@ -19,6 +19,7 @@ ENABLE_HARDNET=true ENABLE_IPTABLES=true /rpi2-gen-image.sh APT_SERVER=ftp.de.debian.org APT_PROXY="http://127.0.0.1:3142/" ./rpi2-gen-image.sh ENABLE_MINBASE=true ./rpi2-gen-image.sh BUILD_KERNEL=true ENABLE_MINBASE=true ENABLE_IPV6=false ./rpi2-gen-image.sh +BUILD_KERNEL=true KERNEL_SRCDIR=/tmp/linux ./rpi2-gen-image.sh ``` #### APT settings: @@ -158,7 +159,10 @@ Path to a directory with scripts that should be run in the chroot before the ima #### Kernel compilation: ##### `BUILD_KERNEL`=false -Build and install the latest RPi2 linux kernel. Currently only the default RPi2 kernel configuration is used. Detailed configuration parameters for customizing the kernel and minor bug fixes still need to get implemented. feel free to help. +Build and install the latest RPi2 Linux kernel. Currently only the default RPi2 kernel configuration is used. Detailed configuration parameters for customizing the kernel and minor bug fixes still need to get implemented. feel free to help. + +##### `KERNEL_SRCDIR`="" +Path to a directory of [RaspberryPi Linux kernel] sources (https://github.com/raspberrypi/linux) that will be copied, configured, build and installed inside the chroot. ##### `KERNEL_THREADS`=1 Number of parallel kernel building threads. If the parameter is left untouched the script will automatically determine the number of CPU cores to set the number of parallel threads to speed the kernel compilation. @@ -169,8 +173,14 @@ Install kernel headers with built kernel. ##### `KERNEL_MENUCONFIG`=false Start `make menuconfig` interactive menu-driven kernel configuration. The script will continue after `make menuconfig` was terminated. +##### `KERNEL_CONFIGSRC`=true +Run `make bcm2709_defconfig` (and optional `make menuconfig`) to configure the kernel sources before building. This setting is automatically set to `true` if no existing kernel sources directory was specified using `KERNEL_SRCDIR`. + +##### `KERNEL_CLEANSRC`=false +Clean the existing kernel sources directory `KERNEL_SRCDIR` (using `make mrproper`) after it was copied to the chroot and before the compilation of the kernel has started. This setting will be ignored if no `KERNEL_SRCDIR` was specified. + ##### `KERNEL_RMSRC`=true -Remove all kernel sources from the generated OS image after building. +Remove all kernel sources from the generated OS image after it was built and installed. ## Understanding the script The functions of this script that are required for the different stages of the bootstrapping are split up into single files located inside the `bootstrap.d` directory. During the bootstrapping every script in this directory gets executed in lexicographical order: diff --git a/bootstrap.d/11-apt.sh b/bootstrap.d/11-apt.sh index 3ee51d8..f3a642e 100644 --- a/bootstrap.d/11-apt.sh +++ b/bootstrap.d/11-apt.sh @@ -27,3 +27,4 @@ sed -i "s/ jessie/ ${RELEASE}/" $R/etc/apt/sources.list # Upgrade package index and update all installed packages and changed dependencies chroot_exec apt-get -qq -y update chroot_exec apt-get -qq -y -u dist-upgrade +chroot_exec apt-get -qq -y check diff --git a/bootstrap.d/13-kernel.sh b/bootstrap.d/13-kernel.sh index 8ec8856..5163f0d 100644 --- a/bootstrap.d/13-kernel.sh +++ b/bootstrap.d/13-kernel.sh @@ -7,32 +7,55 @@ # Fetch and build latest raspberry kernel if [ "$BUILD_KERNEL" = true ] ; then - # Fetch current raspberrypi kernel sources - git -C $R/usr/src clone --depth=1 https://github.com/raspberrypi/linux + # Setup source directory + mkdir -p $R/usr/src - # Load default raspberry kernel configuration - make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} bcm2709_defconfig + # Copy existing kernel sources into chroot directory + if [ -n "$KERNEL_SRCDIR" ] && [ -d "$KERNEL_SRCDIR" ] ; then + # Copy kernel sources + cp -r "${KERNEL_SRCDIR}" "${R}/usr/src" + + # Clean the kernel sources + if [ "$KERNEL_CLEANSRC" = true ] ; then + make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} mrproper + fi + else # KERNEL_SRCDIR="" + # Fetch current raspberrypi kernel sources + git -C $R/usr/src clone --depth=1 https://github.com/raspberrypi/linux + fi # Calculate optimal number of kernel building threads - if [ "$KERNEL_THREADS" = 1 ] ; then - if [ -f /proc/cpuinfo ] ; then + if [ "$KERNEL_THREADS" = "1" ] ; then + if [ -r /proc/cpuinfo ] ; then KERNEL_THREADS=$(grep -c processor /proc/cpuinfo) fi fi - # Start menu-driven kernel configuration (interactive) - if [ "$KERNEL_MENUCONFIG" = true ] ; then - make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} menuconfig + if [ "$KERNEL_CONFIGSRC" = true ] ; then + # Load default raspberry kernel configuration + make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} ${KERNEL_DEFCONFIG} + + # Start menu-driven kernel configuration (interactive) + if [ "$KERNEL_MENUCONFIG" = true ] ; then + make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} menuconfig + fi fi # Cross compile kernel and modules make -C $R/usr/src/linux -j${KERNEL_THREADS} ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} zImage modules dtbs + # Check if kernel compilation was successful + if [ ! -r $R/usr/src/linux/arch/${KERNEL_ARCH}/boot/zImage ] ; then + echo "error: kernel compilation failed!" + cleanup + exit 1 + fi + # Install kernel modules make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} INSTALL_MOD_PATH=../../.. modules_install # Install kernel headers - if [ "$KERNEL_HEADERS" = true ]; then + if [ "$KERNEL_HEADERS" = true ] ; then make -C $R/usr/src/linux ARCH=${KERNEL_ARCH} CROSS_COMPILE=${CROSS_COMPILE} INSTALL_HDR_PATH=../.. headers_install fi @@ -47,7 +70,7 @@ if [ "$BUILD_KERNEL" = true ] ; then cp $R/usr/src/linux/arch/${KERNEL_ARCH}/boot/dts/overlays/README $R/boot/firmware/overlays/ # Remove kernel sources - if [ "$KERNEL_RMSRC" = true ]; then + if [ "$KERNEL_RMSRC" = true ] ; then rm -fr $R/usr/src/linux fi diff --git a/bootstrap.d/30-security.sh b/bootstrap.d/30-security.sh index 3f25e4e..2bdacd9 100644 --- a/bootstrap.d/30-security.sh +++ b/bootstrap.d/30-security.sh @@ -15,10 +15,10 @@ if [ "$ENABLE_USER" = true ] ; then fi # Setup root password or not -if [ "$ENABLE_ROOT" = true ]; then +if [ "$ENABLE_ROOT" = true ] ; then chroot_exec usermod -p "${ENCRYPTED_PASSWORD}" root - if [ "$ENABLE_ROOT_SSH" = true ]; then + if [ "$ENABLE_ROOT_SSH" = true ] ; then sed -i "s|[#]*PermitRootLogin.*|PermitRootLogin yes|g" $R/etc/ssh/sshd_config fi else diff --git a/bootstrap.d/31-logging.sh b/bootstrap.d/31-logging.sh index cfb99a2..740161b 100644 --- a/bootstrap.d/31-logging.sh +++ b/bootstrap.d/31-logging.sh @@ -6,8 +6,8 @@ . ./functions.sh # Disable rsyslog -if [ "$ENABLE_RSYSLOG" = false ]; then +if [ "$ENABLE_RSYSLOG" = false ] ; then sed -i "s|[#]*ForwardToSyslog=yes|ForwardToSyslog=no|g" $R/etc/systemd/journald.conf chroot_exec systemctl disable rsyslog - chroot_exec apt-get purge -q -y --force-yes rsyslog + chroot_exec apt-get -qq -y --force-yes purge rsyslog fi diff --git a/bootstrap.d/41-uboot.sh b/bootstrap.d/41-uboot.sh index 0767452..4968bdd 100644 --- a/bootstrap.d/41-uboot.sh +++ b/bootstrap.d/41-uboot.sh @@ -6,8 +6,8 @@ . ./functions.sh # Install gcc/c++ build environment inside the chroot -if [ "$ENABLE_UBOOT" = true ] || [ "$ENABLE_FBTURBO" = true ]; then - chroot_exec apt-get install -q -y --force-yes --no-install-recommends linux-compiler-gcc-4.9-arm g++ make bc +if [ "$ENABLE_UBOOT" = true ] || [ "$ENABLE_FBTURBO" = true ] ; then + chroot_exec apt-get -q -y --force-yes --no-install-recommends install linux-compiler-gcc-4.9-arm g++ make bc fi # Fetch and build U-Boot bootloader diff --git a/bootstrap.d/42-fbturbo.sh b/bootstrap.d/42-fbturbo.sh index 2ed523b..c02b38f 100644 --- a/bootstrap.d/42-fbturbo.sh +++ b/bootstrap.d/42-fbturbo.sh @@ -10,7 +10,7 @@ if [ "$ENABLE_FBTURBO" = true ] ; then git -C $R/tmp clone https://github.com/ssvb/xf86-video-fbturbo.git # Install Xorg build dependencies - chroot_exec apt-get install -q -y --no-install-recommends xorg-dev xutils-dev x11proto-dri2-dev libltdl-dev libtool automake libdrm-dev + chroot_exec apt-get -q -y --no-install-recommends install xorg-dev xutils-dev x11proto-dri2-dev libltdl-dev libtool automake libdrm-dev # Build and install fbturbo driver inside chroot chroot_exec /bin/bash -x <<'EOF' @@ -25,10 +25,10 @@ EOF install_readonly files/xorg/99-fbturbo.conf $R/usr/share/X11/xorg.conf.d/99-fbturbo.conf # Remove Xorg build dependencies - chroot_exec apt-get -q -y purge --auto-remove xorg-dev xutils-dev x11proto-dri2-dev libltdl-dev libtool automake libdrm-dev + chroot_exec apt-get -qq -y --auto-remove purge xorg-dev xutils-dev x11proto-dri2-dev libltdl-dev libtool automake libdrm-dev fi # Remove gcc/c++ build environment from the chroot -if [ "$ENABLE_UBOOT" = true ] || [ "$ENABLE_FBTURBO" = true ]; then - chroot_exec apt-get -y -q purge --auto-remove bc binutils cpp cpp-4.9 g++ g++-4.9 gcc gcc-4.9 libasan1 libatomic1 libc-dev-bin libc6-dev libcloog-isl4 libgcc-4.9-dev libgomp1 libisl10 libmpc3 libmpfr4 libstdc++-4.9-dev libubsan0 linux-compiler-gcc-4.9-arm linux-libc-dev make +if [ "$ENABLE_UBOOT" = true ] || [ "$ENABLE_FBTURBO" = true ] ; then + chroot_exec apt-get -qq -y --auto-remove purge bc binutils cpp cpp-4.9 g++ g++-4.9 gcc gcc-4.9 libasan1 libatomic1 libc-dev-bin libc6-dev libcloog-isl4 libgcc-4.9-dev libgomp1 libisl10 libmpc3 libmpfr4 libstdc++-4.9-dev libubsan0 linux-compiler-gcc-4.9-arm linux-libc-dev make fi diff --git a/rpi2-gen-image.sh b/rpi2-gen-image.sh index 57fea7c..ec14e25 100755 --- a/rpi2-gen-image.sh +++ b/rpi2-gen-image.sh @@ -15,6 +15,12 @@ # Copyright (C) 2015 Luca Falavigna ######################################################################## +# Check if ./functions.sh script exists +if [ ! -r "./functions.sh" ] ; then + echo "error: './functions.sh' required script not found. please reinstall the latest script version!" + exit 1 +fi + # Load utility functions . ./functions.sh @@ -29,6 +35,7 @@ KERNEL_ARCH=${KERNEL_ARCH:=arm} RELEASE_ARCH=${RELEASE_ARCH:=armhf} CROSS_COMPILE=${CROSS_COMPILE:=arm-linux-gnueabihf-} COLLABORA_KERNEL=${COLLABORA_KERNEL:=3.18.0-trunk-rpi2} +KERNEL_DEFCONFIG=${KERNEL_DEFCONFIG:=bcm2709_defconfig} QEMU_BINARY=${QEMU_BINARY:=/usr/bin/qemu-arm-static} # Build settings @@ -90,9 +97,12 @@ ENABLE_SPLITFS=${ENABLE_SPLITFS:=false} # Kernel compilation settings BUILD_KERNEL=${BUILD_KERNEL:=false} +KERNEL_SRCDIR=${KERNEL_SRCDIR:=""} KERNEL_THREADS=${KERNEL_THREADS:=1} KERNEL_HEADERS=${KERNEL_HEADERS:=true} KERNEL_MENUCONFIG=${KERNEL_MENUCONFIG:=false} +KERNEL_CLEANSRC=${KERNEL_CLEANSRC:=false} +KERNEL_CONFIGSRC=${KERNEL_CONFIGSRC:=true} KERNEL_RMSRC=${KERNEL_RMSRC:=true} # Image chroot path @@ -107,16 +117,40 @@ MISSING_PACKAGES="" # Packages required in the chroot build environment APT_INCLUDES=${APT_INCLUDES:=""} -APT_INCLUDES="${APT_INCLUDES},apt-transport-https,ca-certificates,debian-archive-keyring,dialog,sudo" +APT_INCLUDES="${APT_INCLUDES},apt-transport-https,apt-utils,ca-certificates,debian-archive-keyring,dialog,sudo" set +x # Are we running as root? if [ "$(id -u)" -ne "0" ] ; then - echo "this script must be executed with root privileges" + echo "error: this script must be executed with root privileges!" exit 1 fi +# Check if ./bootstrap.d directory exists +if [ ! -d "./bootstrap.d/" ] ; then + echo "error: './bootstrap.d' required directory not found. please reinstall the latest script version!" + exit 1 +fi + +# Check if ./files directory exists +if [ ! -d "./files/" ] ; then + echo "error: './files' required directory not found. please reinstall the latest script version!" + exit 1 +fi + +# Check if specified KERNEL_SRCDIR directory exists +if [ -n "$KERNEL_SRCDIR" ] && [ ! -d "$KERNEL_SRCDIR" ] ; then + echo "error: ${KERNEL_SRCDIR} (KERNEL_SRCDIR) specified directory not found!" + exit 1 +fi + +# Check if specified CHROOT_SCRIPTS directory exists +if [ -n "$CHROOT_SCRIPTS" ] && [ ! -d "$CHROOT_SCRIPTS" ] ; then + echo "error: ${CHROOT_SCRIPTS} (CHROOT_SCRIPTS) specified directory not found!" + exit 1 +fi + # Add packages required for kernel cross compilation if [ "$BUILD_KERNEL" = true ] ; then REQUIRED_PACKAGES="${REQUIRED_PACKAGES} crossbuild-essential-armhf" @@ -148,11 +182,22 @@ fi apt-get -qq -y install ${REQUIRED_PACKAGES} # Don't clobber an old build -if [ -e "$BUILDDIR" ]; then - echo "directory $BUILDDIR already exists, not proceeding" +if [ -e "$BUILDDIR" ] ; then + echo "error: directory ${BUILDDIR} already exists, not proceeding" + exit 1 +fi + +# Check if build directory has enough of free disk space >512MB +if [ "$(df --output=avail ${BUILDDIR} | sed "1d")" -le "524288" ] ; then + echo "error: ${BUILDDIR} not enough space left on this partition to generate the output image!" exit 1 fi +# Warn if build directory has low free disk space <1024MB +if [ "$(df --output=avail ${BUILDDIR} | sed "1d")" -le "1048576" ] ; then + echo `df -h --output=avail ${BUILDDIR} | sed "1 s|.*Avail|warning: $partition is low on free space:|"` +fi + set -x # Call "cleanup" function on various signals and errors @@ -198,10 +243,6 @@ if [ "$ENABLE_HWRANDOM" = true ] ; then APT_INCLUDES="${APT_INCLUDES},rng-tools" fi -if [ "$ENABLE_USER" = true ]; then - APT_INCLUDES="${APT_INCLUDES},sudo" -fi - # Add fbturbo video driver if [ "$ENABLE_FBTURBO" = true ] ; then # Enable xorg package dependencies @@ -221,27 +262,42 @@ if [ "$ENABLE_XORG" = true ] ; then APT_INCLUDES="${APT_INCLUDES},xorg" fi -## Main bootstrap -for i in bootstrap.d/*.sh; do - head -n 3 $i - . $i +# Set KERNEL_CONFIGSRC=true +if [ "$BUILD_KERNEL" = true ] && [ -z "$KERNEL_SRCDIR" ] ; then + KERNEL_CONFIGSRC=true +fi + +## MAIN bootstrap +for SCRIPT in bootstrap.d/*.sh; do + # Execute bootstrap scripts (lexicographical order) + head -n 3 $SCRIPT + . $SCRIPT done ## Custom bootstrap scripts -if [ -d "custom.d" ]; then - for i in custom.d/*.sh; do - . $i +if [ -d "custom.d" ] ; then + # Execute custom bootstrap scripts (lexicographical order) + for SCRIPT in custom.d/*.sh; do + . $SCRIPT done fi # Invoke custom scripts -if [ -n "${CHROOT_SCRIPTS}" ]; then +if [ -n "$CHROOT_SCRIPTS" ] && [ -d "$CHROOT_SCRIPTS" ] ; then cp -r "${CHROOT_SCRIPTS}" "${R}/chroot_scripts" - LANG=C chroot $R bash -c 'for SCRIPT in /chroot_scripts/*; do if [ -f $SCRIPT -a -x $SCRIPT ]; then $SCRIPT; fi done;' + # Execute scripts inside the chroot (lexicographical order) + chroot_exec /bin/bash -x <<'EOF' +for SCRIPT in /chroot_scripts/* ; do + if [ -f $SCRIPT -a -x $SCRIPT ] ; then + $SCRIPT + fi +done +EOF rm -rf "${R}/chroot_scripts" fi ## Cleanup +chroot_exec apt-get purge -q -y --force-yes apt-utils chroot_exec apt-get -y clean chroot_exec apt-get -y autoclean chroot_exec apt-get -y autoremove