From 9a6ba2b46cef9797ea1bc5c7ac0d94b8f489d007 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Sun, 28 Jul 2024 23:34:58 +0200 Subject: bin: add a script to ease up linux cross compiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miquel Sabaté Solà --- bin/kbuild | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 bin/kbuild 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à +# +# 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 . + +##### +# 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 <