rewrite preinit as very small C program

By using the kernel "nolibc" header to avoid requiring a C library, we
can bring the initramfs size to around 4k

This does involve a tiny bit of inline mips assembly which I'm not
sure about. gcc seems unwilling to generate the code to load $gp at
function entry of main(), so we do it by hand - but I'd rather find
out why gcc doesn't.
This commit is contained in:
Daniel Barlow
2023-04-15 17:35:02 +01:00
parent b1a89ae8c3
commit 5dd0c6e3c0
4 changed files with 126 additions and 68 deletions

30
pkgs/preinit/default.nix Normal file
View File

@@ -0,0 +1,30 @@
{
stdenv
, fetchzip
, gdb
}:
let kernel = fetchzip {
name = "linux";
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
hash = "sha256-pq6QNa0PJVeheaZkuvAPD0rLuEeKrViKk65dz+y4kqo=";
};
in
stdenv.mkDerivation {
name = "preinit";
src = ./.;
# NIX_DEBUG=2;
hardeningDisable = [ "all" ];
CFLAGS = "-Os -nostartfiles -nostdlib -fno-stack-protector -fpic -fPIC -I ./ -I ${kernel}/tools/include/nolibc";
postBuild = ''
$STRIP --remove-section=.note --remove-section=.comment preinit
'';
makeFlags = ["preinit"];
stripAllList = ["bin"];
installPhase = ''
mkdir -p $out/bin
cp preinit $out/bin
'';
}