diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-07-28 23:34:58 +0200 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-07-28 23:34:58 +0200 |
| commit | 9a6ba2b46cef9797ea1bc5c7ac0d94b8f489d007 (patch) | |
| tree | 31de0ee8752b3e6d6ff5c6d4c773869747fea840 /bin | |
| parent | 5701f2c18bee02941d61658f9c1260e14ffb2b94 (diff) | |
| download | dotfiles-9a6ba2b46cef9797ea1bc5c7ac0d94b8f489d007.tar.gz dotfiles-9a6ba2b46cef9797ea1bc5c7ac0d94b8f489d007.zip | |
bin: add a script to ease up linux cross compiling
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/kbuild | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/bin/kbuild b/bin/kbuild new file mode 100755 index 0000000..af9ec6c --- /dev/null +++ b/bin/kbuild @@ -0,0 +1,176 @@ +#!/usr/bin/env bash +# Copyright (C) 2024-Ω Miquel Sabaté Solà <mikisabate@gmail.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +##### +# Build the Linux Kernel and bundle it into a tarball that can then be used on +# another machine. After you call this script it will: +# 1. Either call `defconfig` or re-use an existing .config as per user request. +# 2. Call `menuconfig` so the user can double check the configuration. +# 3. Build the Kernel. +# 4. Copy into a tarball the resulting image, modules, dtbs, and headers. An +# install.sh script is also bundled in. +# +# After that just send the resulting tarball to the machine where you want to +# install this kernel. In there you just need to untar the given bundle and then +# run the `install.sh` script from within the resulting directory. This will: +# 1. Copy recursively all the files into their proper paths. +# 2. Make an initramfs for the new image. +# 3. Run your $EDITOR to update the /boot/extlinux/extlinux.conf file. +# +# *NOTE*: this script expects the `ARCH` environment variable to be set, and if +# that doesn't match the current architecture, then it will expect to have +# `CROSS_COMPILE` set as well. +# *NOTE*: because of the funny machines I'm testing this in, only Debian was +# tested. Hence, we assume tools such as `update-initramfs` exist instead of +# using `dracut`. +##### + +set -e + +## +# Initial checks. + +# Most of the times, we are safer if we just set the `ARCH` env. variable. +if [ -z "$ARCH" ]; then + echo "kbuild (error): \$ARCH has to be defined." + exit 1 +fi + +# Is cross compilation the thing we want? +if [ "$ARCH" != "$(uname -m)" ]; then + # Confusingly enough, riscv64 is supposed to be passed as 'riscv' to the + # kernel. Hence, don't take that as being different. + if [ "$(uname -m)" != "riscv64" ] || [ "$ARCH" != "riscv" ]; then + # We are indeed cross compiling. If `CROSS_COMPILE` is not set at this + # point we should raise an error. + if [ -z "$CROSS_COMPILE" ]; then + echo "kbuild (error): \$CROSS_COMPILE has to be defined." + exit 1 + fi + fi +fi + +# To avoid embarrassing moments, let's make sure that we are in the Linux repo. +if [ ! -f "Kbuild" ]; then + echo "kbuild (error): we are not in the Linux Kernel." + exit 1 +fi + +## +# .config + +if [ ! -f ".config" ]; then + echo "kbuild (info): no '.config' file found" + make defconfig +fi + +config_options=("From a default configuration (defconfig)" "From an existing .config file") +echo "kconfig (info): how do you want to configure the build?" +PS3="> " +select _opt in "${config_options[@]}" "Quit"; do + case "$REPLY" in + 1) + make defconfig + echo "kbuild (info): running 'menuconfig' to double check." + make menuconfig + break + ;; + 2) + echo "kbuild (info): running 'menuconfig' to double check." + make menuconfig + break + ;; + 3) + echo "kbuild (info): bye!" + exit 0 + ;; + *) + echo "kbuild (info): not an option. Try again..." + continue + ;; + esac +done + +## +# Build the kernel. + +echo "kbuild (info): building the Linux kernel..." +make -j "$(nproc)" + +## +# Installing into a local bundle. + +name=$(cat include/config/kernel.release) + +if [ -z "$INSTALL_PATH" ]; then + INSTALL_PATH="buildroot-$name" +fi +mkdir -p "$INSTALL_PATH/usr/lib/modules/$name" +pushd "$INSTALL_PATH" > /dev/null +ln -s usr/lib lib +popd > /dev/null + +make modules_install INSTALL_MOD_PATH="$INSTALL_PATH" +make dtbs_install INSTALL_DTBS_PATH="$INSTALL_PATH/boot/dtbs/$name" +make headers_install INSTALL_HDR_PATH="$INSTALL_PATH/usr" + +unlink "$INSTALL_PATH/lib" + +cp "arch/$ARCH/boot/Image.gz" "$INSTALL_PATH/boot/vmlinuz-$name" +cp .config "$INSTALL_PATH/boot/config-$name" + +## +# Setup install.sh script. + +cat <<SCRIPT > "$INSTALL_PATH/install.sh" +#!/usr/bin/env bash + +set -ex + +if [ "\$EUID" -ne 0 ];then + echo "kbuild (error): run this as root." + exit 1 +fi + +if [ ! -f /sbin/update-initramfs ] && [ ! -f /usr/bin/dracut ]; then + echo "kbuild (error): you need either 'dracut' or 'update-initramfs'." + exit 1 +fi + +cp -rv usr / +cp -rv boot / + +export PATH=/sbin:\$PATH +if command -v dracut &> /dev/null +then + dracut --kver=$name -f +else + update-initramfs -k $name -u +fi + +if [ -z "\$EDITOR" ]; then + EDITOR=vi +fi +\$EDITOR /boot/extlinux/extlinux.conf +SCRIPT + +## +# Create tarball. + +tar czf "$INSTALL_PATH.tar.gz" "$INSTALL_PATH" +rm -r "$INSTALL_PATH" + +echo "kbuild (info): your build is now ready at '$INSTALL_PATH.tar.gz'." |
