Compiling New Kernel For Raspberry Pi

From Nearline Storage
Jump to: navigation, search
#!/usr/bin/env sh

#  Cross compiling a new Raspberry Pi kernel following instructions at:
#  http://elinux.org/RPi_Kernel_Compilation

BASE="/storage/pi"
PI_HOST="dlk-rspi"

if [ ! -d "$BASE" ]; then
	mkdir "$BASE"
fi

cd "$BASE"

#  "if true;" then run this command block, "if false;" then don't
if true; then
	#  Clean up from previous run
	rm -fr .git &>/dev/null
	rm -fr kernel &>/dev/null
	rm -fr tools &>/dev/null
	rm -fr modules &>/dev/null
	rm -fr firmware &>/dev/null

	#  Setup git environment
	git init
	[ 0 -ne $? ] && exit $?

	#  Get patched kernel that was supposed to fix TEAC USB DAC audio problems per
	#  http://volumio.org/forum/fixes-for-common-usb-dac-problems-with-rpi-t328.html
	#  Didn't work
	#git clone --depth 1 git://github.com/petli/linux.git -b rpi-3.10-usb-sound-backport

	#  Get the latest stable kernel source
	git clone --depth 1 git://github.com/raspberrypi/linux.git
	[ 0 -ne $? ] && exit $?
fi

KERNEL_SRC="${BASE}/linux"

#  "if true;" then download the compiler, "if false;" then don't
if true; then
	git clone git://github.com/raspberrypi/tools.git
	[ 0 -ne $? ] && exit $?
fi

if [ -d "${BASE}/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin" ]; then
	CCPREFIX="${BASE}/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-"
else
	echo "CCPREFIX directory we expected does not exist, please edit script."
	exit
fi

#  "if true;" then copy .config from $PI_HOST, "if false;" then use the default .config 
if true; then
	echo "Getting /proc/config.gz from $PI_HOST"
	scp ${PI_HOST}:/proc/config.gz .
	[ 0 -ne $? ] && exit $?
	cd "$KERNEL_SRC"
	make mrproper
	[ 0 -ne $? ] && exit $?
	zcat "${BASE}/config.gz" >.config
	[ 0 -ne $? ] && exit $?
	rm -f "${BASE}/config.gz"
else
	echo "Using default config from ${KERNEL_SRC}/arch/arm/configs/bcmrpi_defconfig"
	cd "$KERNEL_SRC"
	make mrproper
	[ 0 -ne $? ] && exit $?
	cp "${KERNEL_SRC}/arch/arm/configs/bcmrpi_defconfig" .config
	[ 0 -ne $? ] && exit $?
fi

#  Configure
yes '' | ARCH=arm CROSS_COMPILE="$CCPREFIX" make oldconfig
[ 0 -ne $? ] && exit $?

#  Compile
CPU_COUNT=$(cat /proc/cpuinfo | grep -m 1 siblings | awk '{ print $3 }')
CPU_COUNT=$(( $CPU_COUNT + 1 ))
ARCH=arm CROSS_COMPILE="$CCPREFIX" make -j$CPU_COUNT 
[ 0 -ne $? ] && exit $?

#  Bundle kernel firmward and modules
mkdir "${BASE}/modules"
[ 0 -ne $? ] && exit $?
ARCH=arm CROSS_COMPILE="$CCPREFIX" INSTALL_MOD_PATH="${BASE}/modules" make -j$CPU_COUNT modules_install
cd "${BASE}/modules/lib"
[ 0 -ne $? ] && exit $?
tar -zcvf modules.gz *
[ 0 -ne $? ] && exit $?

#  Create boot image
cd "${BASE}/tools/mkimage"
[ 0 -ne $? ] && exit $?
./imagetool-uncompressed.py "${KERNEL_SRC}/arch/arm/boot/zImage"

#  Get latest boot firmware
cd "$BASE"
git clone git://github.com/raspberrypi/firmware.git
[ 0 -ne $? ] && exit $?

#  Install everything on the target
while [ -z PSW ]; do
    read -sp "root password for ${PI_HOST}: " PSW
done
scp "${BASE}/tools/mkimage/kernel.img" root:${PSW}@${PI_HOST}:/boot/
[ 0 -ne $? ] && exit $?
scp "${BASE}/modules/lib/modules.gz" root:${PSW}@${PI_HOST}:/var/tmp/
[ 0 -ne $? ] && exit $?
ssh root:${PSW}@${PI_HOST} tar -C /lib -zxvf /var/tmp/modules.gz
[ 0 -ne $? ] && exit $?
ssh root:${PSW}@${PI_HOST} rm /var/tmp/modules.gz
scp firmware/boot/bootcode.bin root:${PSW}@${PI_HOST}:/boot/
[ 0 -ne $? ] && exit $?
scp firmware/boot/fixup.dat root:${PSW}@${PI_HOST}:/boot/
[ 0 -ne $? ] && exit $?
scp firmware/boot/start.elf root:${PSW}@${PI_HOST}:/boot/
[ 0 -ne $? ] && exit $?
if $(${CCPREFIX}-gcc -v 2>&1 | grep -qe "--with-float=soft"); then
    scp -r firmware/opt/* root:${PSW}@${PI_HOST}:/opt/
elif $(${CCPREFIX}-gcc -v 2>&1 | grep -qe "--with-float=hard"); then
    scp -r firmware/hardfp/opt/* root@${PSW}:${PI_HOST}:/opt/
else
    echo "Cannot figure out which version of /opt/vc to copy over"
fi