Last active
May 12, 2021 06:45
-
-
Save MartyMacGyver/2ed99ec1e56d60c22519 to your computer and use it in GitHub Desktop.
Building the kernel for the Raspberry Pi/Pi2/Pi3 using a cross-compiler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
# | |
# | |
# | |
# | |
# Bottom line: Because ultimately the tools don't get built for the target arch, | |
# it may be easier to build the headers on the RPi itself. | |
# | |
# | |
# | |
# | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
############################################################################### | |
# Compiling the RPi kernel using a cross-compiler | |
# | |
# Updates http://www.raspberrypi.org/documentation/linux/kernel/building.md | |
# Eventually merge into https://github.com/raspberrypi/documentation/blob/master/linux/kernel/building.md | |
# Inputs from https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=57401 | |
# Especially https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=90276 | |
############################################################################### | |
# Install Ubuntu 14.04 server (I did this in a VM with 2 vCPUs) | |
# Create a local admin (e.g., 'localadmin') | |
sudo apt-get update # Fetches the list of available updates | |
sudo apt-get dist-upgrade -y # Installs updates | |
sudo apt-get install -y build-essential git bc | |
alias dir="ls -alF" # Optional but handy | |
MYBASE=~/pibuild | |
KERNEL_SRC=${MYBASE}/linux | |
PI_LOGIN=pi@192.168.1.176 # Whatever your RPi's login and IP are | |
PI_CMD_PREFIX='' # Works if you are building on the Pi or remotely | |
mkdir -p ${MYBASE} | |
# Jobs should be 1.5x the number of CPUs. My VM has 2 CPUs allocated to it. | |
# Took me 15 minutes to build the kernel | |
CPUS=`grep 'processor\s*:' /proc/cpuinfo | wc -l` # A decent approximation | |
JOBS=`echo $CPUS*1.5/1 | bc` | |
echo Running $JOBS jobs over $CPUS cpus | |
#VERSION=CUSTOM-`git rev-parse --short=16 HEAD` | |
VERSION=99002 # Your choice... you might want to use what you already have | |
echo Custom kernel version ${VERSION} | |
#=== METHOD 1: Determine the kernel you have now via the RPi! | |
# This will depend on how you maintain your RPi (e.g., Raspbian, Hexxeh's firmware, etc.) | |
# If you are based on the regular Raspberry Pi firmware, get the commit ID as follows: | |
FIRMWARE_HASH=$(ssh ${PI_LOGIN} 'zgrep "* firmware as of" /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz' | head -1 | awk '{ print $5 }') ; \ | |
KERNEL_HASH=$(wget -nv https://raw.github.com/raspberrypi/firmware/${FIRMWARE_HASH}/extra/git_hash -O -) ; \ | |
echo FIRMWARE_HASH = $FIRMWARE_HASH ; \ | |
echo KERNEL_HASH = $KERNEL_HASH | |
# If you are based on Hexxeh's firmware, get the commit ID as follows: | |
FIRMWARE_HASH=$(ssh ${PI_LOGIN} 'cat /boot/.firmware_revision') ; \ | |
KERNEL_HASH=$(wget -nv https://raw.githubusercontent.com/Hexxeh/rpi-firmware/${FIRMWARE_HASH}/git_hash -O -) ; \ | |
echo FIRMWARE_HASH = $FIRMWARE_HASH ; \ | |
echo KERNEL_HASH = $KERNEL_HASH | |
# Clone the kernel sources | |
# You cannot clone a specific commit only: you will need to clone a lot of data! | |
# git clone --branch rpi-4.1.y ... # Get only this branch of the kernel - doesn't save space either. | |
# git clone --depth=1 ... # Get only the latest commit on the default branch | |
cd ${MYBASE} | |
git clone https://github.com/raspberrypi/linux ${KERNEL_SRC} | |
cd ${KERNEL_SRC} | |
git clean -f | |
git pull --ff-only | |
git checkout ${KERNEL_HASH} | |
# Get the current kernel config from the RPi | |
ssh ${PI_LOGIN} sudo modprobe configs # Or run this directly on the RPi | |
scp ${PI_LOGIN}:/proc/config.gz ${MYBASE}/. | |
#=== METHOD 2: ON THE RPI: use rpi-source to get the kernel sources for your kernel | |
# More info at https://github.com/notro/rpi-source/wiki | |
sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && \ | |
sudo chmod +x /usr/bin/rpi-source && \ | |
/usr/bin/rpi-source -q --tag-update | |
rpi-source --skip-gcc | |
#=== Clone the tools | |
cd ${MYBASE} | |
git clone https://github.com/raspberrypi/tools | |
cd ${MYBASE}/tools | |
git clean -f | |
git pull --ff-only | |
# Tools for building the RPi1 kernel: | |
export CCPREFIX=${MYBASE}/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi- | |
# Tools for building the RPi2 kernel via 32-bit host: | |
export CCPREFIX=${MYBASE}/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- | |
# Tools for building the RPi2 kernel via 64-bit host: | |
export CCPREFIX=${MYBASE}/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- | |
# For consistency add to the path (the x64 CC works without this step, but the others don't for some reason) | |
#PATH=`dirname ${CCPREFIX}`:$PATH | |
#export PATH | |
#echo $PATH | |
#`basename ${CCPREFIX}`gcc # For some reason this only works for the x64 CCs. | |
#=== Ready to build | |
cd ${KERNEL_SRC} | |
make help # Shows us all the targets | |
make mrproper # Clean | |
# OBSOLETE | |
# Create the config (all configs are found in arch/arm/configs) | |
# # For the Pi: | |
# make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig | |
# # For the Pi2: | |
# make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig | |
zcat ${MYBASE}/config.gz > .config | |
echo ${VERSION} > .version | |
make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig | |
# OPTIONAL tweaks (this shouldn't be needed unless you did't have config.gz) | |
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf menuconfig | |
# Build the kernel and the modules (V=1 is verbose per https://www.kernel.org/doc/makehelp.txt) | |
make V=1 -j${JOBS} ARCH=arm CROSS_COMPILE=${CCPREFIX} | tee build_main.log | |
# ??????? | |
make V=1 -j${JOBS} ARCH=arm CROSS_COMPILE=${CCPREFIX} zImage modules dtbs | tee build_alt.log | |
# Directly on the Pi: make headers_install | |
# Build the kernel debians | |
KBUILD_DEBARCH=armhf make V=1 ARCH=arm CROSS_COMPILE=${CCPREFIX} deb-pkg | tee build_pkg.log | |
VERSION=`cat ${KERNEL_SRC}/.version` | |
cp .version ../linux-buildversion | |
#scp -p ../linux-buildversion ../linux-*${VERSION}*.deb ${PI_LOGIN}:. | |
scp -p ../linux-headers-*${VERSION}*.deb ${PI_LOGIN}:. | |
#=== On the Pi | |
# At this point you can just install the headers package on the RPi: | |
sudo dpkg --purge linux-headers-4.1.15-v7+ | |
sudo dpkg -i linux-headers-*${VERSION}*.deb | |
#=== On the Pi | |
#=============================================================================================================# | |
# # ###### ###### ##### #### ##### ###### # # # #### # #### # # | |
## # # # # # # # # # # # # # # # # ## # | |
# # # ##### ##### # # #### # # ##### # # # #### # # # # # # | |
# # # # # # # # ##### # # # # # # # # # # # | |
# ## # # # # # # # # # # # # # # # # # # ## | |
# # ###### ###### ##### #### # # ###### ## # #### # #### # # | |
#=============================================================================================================# | |
# BEFORE installing make a backup! | |
VERSION=`cat linux-buildversion` | |
sudo dpkg --purge linux-image-4.1.15-v7+ # Otherwise we may get "unable to make backup link" errors | |
sudo dpkg -i linux-image-4.1.15-v7+_4.1.15-v7+-${VERSION}_armhf.deb | |
sudo dpkg -i linux-firmware-image-4.1.15-v7+_4.1.15-v7+-${VERSION}_armhf.deb | |
sudo dpkg -i linux-libc-dev_4.1.15-v7+-${VERSION}_armhf.deb | |
sudo dpkg -i linux-headers-4.1.15-v7+_4.1.15-v7+-${VERSION}_armhf.deb | |
dpkg -c foo.deb # To see contents | |
dpkg -l *linux-headers* | |
# If it's not already in there: | |
sudo bash -c "echo 'kernel=vmlinuz-4.1.15-v7+' >> /boot/config.txt" | |
sudo reboot # Reboot the Pi | |
exit | |
# It boots and works, but the binaries in the scripts folder are "ELF 64-bit LSB executable" | |
# (Any scripts used during the header build end up being the native version, not cross-compiled) | |
# This is pretty much why: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=563376 | |
# https://bugs.launchpad.net/ubuntu/+source/linux-ti-omap4/+bug/666267 | |
# | |
# No workaround is available. | |
cd /usr/src/linux-headers-4.1.15-v7+/scripts | |
find . -type f -exec file '{}' \; | grep ELF | |
find . -type f -exec file '{}' \; | grep x86-64 | |
~/pibuild/linux$ find . -type f -exec file '{}' \; | grep x86-64 | |
./usr/gen_init_cpio: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=22d7fcb6e747f8a3d215d2d70b81ee2844eddc0c, not stripped | |
./firmware/ihex2fw: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=35bb9cd2776e23a5b3be74db9b0d7138373dfc0d, not stripped | |
./lib/raid6/mktables: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9e89c9c002ebb8e468b1e2a73d131be4c792e743, not stripped | |
./lib/gen_crc32table: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=28c5b5c8eb12e5e41c003f637809b2cc95739954, not stripped | |
./scripts/recordmcount: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=e899c0b15e7032d77b28f8a466ed95b19208805a, not stripped | |
./scripts/mod/file2alias.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/mod/modpost.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/mod/sumversion.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/mod/modpost: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=3cc94cef6e8632c4dd2c7d8571d46b9fb3a8aeb1, not stripped | |
./scripts/mod/mk_elfconfig: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=a751faa912ed6a50043ad6a90912ac2c898b5b81, not stripped | |
./scripts/pnmtologo: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9755b51958a5a74753b0376a23cbab356fe2184c, not stripped | |
./scripts/genksyms/parse.tab.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/genksyms/genksyms: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=93a713d766faa4dc98ed76e19b34eabb86a1759b, not stripped | |
./scripts/genksyms/lex.lex.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/genksyms/genksyms.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/kallsyms: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=19d6d1db123870773395432366d7edef2d5db286, not stripped | |
./scripts/conmakehash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=a622a9c7938f06b31c2f15cf53877404ef739104, not stripped | |
./scripts/basic/fixdep: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=f3bbd37d59004620fe42f02aa00faf3bda3107c5, not stripped | |
./scripts/basic/bin2c: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=bd022e6ac54d63b3dac7d0ce77230a5a4227ac94, not stripped | |
./scripts/sortextable: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=dcdb50ffafb2a0f9f8ee7993842da7648da4f481, not stripped | |
./scripts/kconfig/conf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=acffeb12b0914bc83c85efad7424dadadf2fc938, not stripped | |
./scripts/kconfig/zconf.tab.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/kconfig/conf.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/fstree.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/dtc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/dtc-parser.tab.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/flattree.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/dtc-lexer.lex.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/treesource.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/util.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/data.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/checks.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/livetree.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
./scripts/dtc/dtc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=953078812a77ac923e532b346d4460af99eab40c, not stripped | |
./scripts/dtc/srcpos.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | |
# Testing this out | |
sudo apt-get install build-essential bc ncurses-dev tmux git | |
git clone https://github.com/xxorde/librekinect | |
cd librekinect | |
make | |
#! Doesn't work on the RPI2! | |
git clone https://github.com/lwfinger/rtl8723bu | |
cd rtl8723bu | |
make | |
#! Doesn't work on the RPI2 either... because the toolchain problem above | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've learned that gist has a major old bug wherein you don't get notifications for comments to gists.
If you leave a comment, it would be appreciated if you ping me elsewhere so I know to find it!