1
0
Fork 0

init commit

This commit is contained in:
Pratham Patel 2024-03-08 09:10:36 +05:30
commit accf7e685f
Signed by: thefossguy
SSH Key Fingerprint: SHA256:/B3wAg7jnMEBQ2JwkebbS/eXVZANDmqRfnd9QkIhxMI
7 changed files with 336 additions and 0 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.direnv/*
code/*
linux*.tar*
linux*/

25
flake.lock Normal file
View File

@ -0,0 +1,25 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1709677081,
"narHash": "sha256-tix36Y7u0rkn6mTm0lA45b45oab2cFLqAzDbJxeXS+c=",
"rev": "880992dcc006a5e00dd0591446fdf723e6a51a64",
"revCount": 556459,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2311.556459%2Brev-880992dcc006a5e00dd0591446fdf723e6a51a64/018e17b1-5573-70b6-b970-a1348ee66a5b/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/NixOS/nixpkgs/%2A.tar.gz"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

96
flake.nix Normal file
View File

@ -0,0 +1,96 @@
{
inputs = {
# a better way of using the latest stable version of nixpkgs
# without specifying specific release
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/*.tar.gz";
};
outputs = { self, nixpkgs, ... }:
let
# helpers for producing system-specific outputs
supportedSystems = [
"aarch64-linux"
"riscv64-linux"
"x86_64-linux"
];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f rec {
pkgs = import nixpkgs {
inherit system;
overlays = [( final: prev: {
linux_latest_with_llvm = prev.linux_latest.override {
stdenv = llvmPkgs.stdenv;
};
})];
};
llvmPkgs = pkgs.llvmPackages;
# this gets the "major version" of LLVM, eg "16" or "17"
llvmVersion = builtins.elemAt (builtins.splitVersion llvmPkgs.clang.version) 0;
});
in
{
devShells = forEachSupportedSystem ({ pkgs, llvmPkgs, llvmVersion, ... }: {
default = (pkgs.mkShell.override { stdenv = llvmPkgs.stdenv; }) {
inputsFrom = with pkgs; [ linux_latest_with_llvm ];
packages = with pkgs; [
# for a better kernel developer workflow
b4
neovim
# rust ofc
rustup
# for "make menuconfig"
pkg-config
ncurses
# testing the built kernel in a VM using QEMU
debootstrap # fur creating ze rootfs
gdb
qemu_kvm
# extra utilities _I_ find useful
bat
broot
choose
fd
ripgrep
# formatting this flake
nixpkgs-fmt
]
# for some reason, `llvmPkgs.stdenv` does not have `lld` or actually `bintools`
++ [ llvmPkgs.bintools ];
# Disable '-fno-strict-overflow' compiler flag because it causes the build to fail with the following error:
# clang-16: error: argument unused during compilation: '-fno-strict-overflow' [-Werror,-Wunused-command-line-argument]
hardeningDisable = [ "strictoverflow" ];
env = rec {
# just in case you want to disable building with the LLVM toolchain
# **DO NOT SET THIS TO '0'**
# **COMMENT IT OUT INSTEAD**
# because, for some reason, setting `LLVM` to '0' still counts... :/
LLVM = 1;
# build related flags (for the script)
BUILD_WITH_RUST = 0;
CLEAN_BUILD = 0;
INSTALL_ZE_KERNEL = 0;
REMOVE_KERNEL = 0;
# needed by Rust bindgen
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ llvmPkgs.libclang.lib ];
# because `grep gcc "$(nix-store -r $(command -v clang))/nix-support/libcxx-cxxflags"` matches
# but `grep clang "$(nix-store -r $(command -v clang))/nix-support/libcxx-cxxflags"` **DOES NOT MATCH**
KCFLAGS = "-isystem ${LIBCLANG_PATH}/clang/${llvmVersion}/include";
};
# **ONLY UNCOMMENT THIS IF YOU ARE _NOT_ USING HOME-MANAGER AND GET LOCALE ERRORS/WARNINGS**
# If you are using home-manager, then add the following to your ~/.bashrc
# `source $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh`
#LOCALE_ARCHIVE_2_27 = "${pkgs.glibcLocales}/lib/locale/locale-archive";
};
});
};
}

6
scripts/build.sh Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env dash
set -x
KERNEL_LOCALVERSION="-$(date +%Y.%m.%d.%H%M)"
export KERNEL_LOCALVERSION
"$(dirname "$0")/unwrapped-build-kernel-and-install.sh" "$@" 2>&1 | tee "build-$(make -s kernelversion)${KERNEL_LOCALVERSION}.log"

16
scripts/qemu-boot-kernel.sh Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -xeuf
qemu-kvm \
-machine virt \
-cpu host \
-smp 2 \
-m 2048 \
-accel kvm \
-nographic \
-kernel "$1" \
-hda "$2" \
-netdev user,id=mynet0,hostfwd=tcp::6902-:22 \
-device virtio-net-pci,netdev=mynet0 \
-append 'root=/dev/vda rw systemd.show_status=false'

View File

@ -0,0 +1,188 @@
#!/usr/bin/env bash
# **DON'T DISABLE PATHNAME EXPANSION WITH `set -f`**
set -xeu -o pipefail
# TODO
# 1. Verify options' state(s)
# 2. UKI
# Exit codes:
# 1: $KERNEL_LOCALVERSION unset
# 2: unsupported arch
# 3: couldn't find a config to base the current build off off
# 4: building with rust not possible
BUILD_WITH_RUST="${BUILD_WITH_RUST:-0}"
CLEAN_BUILD="${CLEAN_BUILD:-0}"
INSTALL_ZE_KERNEL="${INSTALL_ZE_KERNEL:-0}"
KERNEL_CONFIG="${KERNEL_CONFIG:-}"
KERNEL_LOCALVERSION="${KERNEL_LOCALVERSION:-}"
MAX_PARALLEL_JOBS="-j ${MAX_PARALLEL_JOBS:-$(( $(nproc) + 2 ))}"
SUDO_ALIAS='sudo --preserve-env=PATH env' # use this alias for su-do-ing binaries provided by Nix
REMOVE_KERNEL="${REMOVE_KERNEL:-0}"
# could be done with the case statement but I don't like the syntax
# feels _wrong_
machine_uname="$(uname -m)"
if [[ "${machine_uname}" == 'aarch64' ]]; then
kernel_arch='arm64'
elif [[ "${machine_uname}" == 'riscv64' ]]; then
kernel_arch='riscv'
elif [[ "${machine_uname}" == 'x86_64' ]]; then
kernel_arch='x86'
else
echo 'ERROR: unsupported arch'
exit 2
fi
if grep 'debian' /etc/os-release > /dev/null; then
if command -v update-grub > /dev/null; then
UPDATE_BOOTLOADER='sudo update-grub'
else
UPDATE_BOOTLOADER='sudo grub-mkconfig -o /boot/grub/grub.cfg'
fi
elif grep 'fedora' /etc/os-release > /dev/null; then
if command -v grubby > /dev/null; then
UPDATE_BOOTLOADER='sudo grubby --update-kernel=ALL'
else
UPDATE_BOOTLOADER='sudo grub2-mkconfig -o /boot/grub2/grub.cfg'
fi
fi
function remove_kernel() {
kernel_version="${1:-$(make -s kernelrelease)}"
sudo rm -rvf {/boot/loader/entries,/boot,/lib/modules,/usr}/"*$kernel_version*"
$UPDATE_BOOTLOADER
}
function setup_rust_toolchain() {
rustup override set "$(scripts/min-tool-version.sh rustc)"
rustup component add rust-src rustfmt clippy
cargo install --locked --version "$(scripts/min-tool-version.sh bindgen)" bindgen-cli
export RUST_LIB_SRC="$(rustc --print sysroot)/lib/rustlib/src/rust/library"
}
function enable_rust_config() {
if [[ "${BUILD_WITH_RUST}" == '1' ]] && [[ "${LLVM:-0}" == '1' ]]; then
setup_rust_toolchain
make rustavailable
make rust.config
if ! grep 'CONFIG_RUST=y' .config > /dev/null; then
echo 'ERROR: building with Rust does not seem to be possible'
exit 4
fi
else
# shellcheck disable=SC2016
echo 'WARNING: $BUILD_WITH_RUST or $LLVM is unset, not building with Rust'
fi
}
function modify_kernel_config() {
# start with a "useful" base config
make olddefconfig
# built-in kernel config
./scripts/config --enable CONFIG_IKCONFIG
./scripts/config --enable CONFIG_IKCONFIG_PROC
# built-in kernel headers
./scripts/config --enable CONFIG_IKHEADERS
# "de-branding" and "re-branding"
./scripts/config --set-str CONFIG_BUILD_SALT ''
./scripts/config --set-str CONFIG_LOCALVERSION "${KERNEL_LOCALVERSION}"
# no need to have these keys, not a prod kernel
./scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ''
./scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ''
# disable AEGIS-128 (ARM{,64} NEON})
# https://github.com/NixOS/nixpkgs/issues/74744
# plus, this kernel won't run in "prod", so this isn't even a "nice to have"
./scripts/config --disable CONFIG_CRYPTO_AEGIS128_SIMD
# sched_ext
./scripts/config --disable CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
./scripts/config --enable CONFIG_DEBUG_INFO_DWARF5
./scripts/config --enable CONFIG_PAHOLE_HAS_BTF_TAG
./scripts/config --enable CONFIG_SCHED_CLASS_EXT
# enable Rust, conditionally
enable_rust_config
# final config rebuild before kernel build
make olddefconfig
}
function configure_kernel() {
if [[ "${CLEAN_BUILD}" == '1' ]]; then
rm -vf .config*
$SUDO_ALIAS make distclean
fi
if [[ -z "${KERNEL_CONFIG}" ]]; then
# $KERNEL_CONFIG is empty, meaning, use the current kernel's config
# in-built kernel config is always the trusted source
# remember, /boot/config-$(uname -r) can be modified by the root user
if [[ -f '/proc/config.gz' ]]; then
zcat /proc/config.gz > .config
elif [[ -f "/boot/config-$(uname -r)" ]]; then
cp "/boot/config-$(uname -r)" .config
else
echo 'ERROR: could not find the config for the current kernel'
exit 3
fi
# maybe the user has a specific kernel config to use
elif [[ -f "${KERNEL_CONFIG}" ]]; then
cp "${KERNEL_CONFIG}" .config
else
# **build** a kernel config
# e.g. `make defconfig`
make "${KERNEL_CONFIG}"
fi
# add my own modifications
modify_kernel_config
}
function build_kernel() {
# shellcheck disable=SC2086
make $MAX_PARALLEL_JOBS all
}
function install_kernel() {
if [[ "${INSTALL_ZE_KERNEL}" == '1' ]]; then
if find "arch/$kernel_arch/boot/dts" -name "*.dtb" -print -quit > /dev/null; then
DTB_INSTALL='dtbs_install'
else
DTB_INSTALL=''
fi
sudo cp .config "/boot/config-$(make -s kernelrelease)"
# shellcheck disable=SC2086
$SUDO_ALIAS make $MAX_PARALLEL_JOBS headers_install $DTB_INSTALL modules_install || remove_kernel
$SUDO_ALIAS make install || remove_kernel
fi
}
if [[ "${REMOVE_KERNEL}" == '1' ]]; then
remove_kernel "${1:-}"
exit 0
fi
if [[ -z "${KERNEL_LOCALVERSION}" ]]; then
# shellcheck disable=SC2016
echo 'ERROR: cannot proceed without a $KERNEL_LOCALVERSION'
exit 1
fi
configure_kernel
build_kernel
install_kernel