boots to userland and runs busybox init

This commit is contained in:
Daniel Barlow 2022-09-20 23:04:08 +01:00
parent b2f7a429f7
commit 6be5b90c96
6 changed files with 102 additions and 28 deletions

View file

@ -8,12 +8,34 @@ Līminis + Nix
## What is this?
This is a reboot/restart of NixWRT: a Nix-based collection of software
tailored for domestic wifi router or IoT device devices, of the kind
that OpenWrt or DD-WRT or Gargoyle or Tomato run on.
This is a Nix-based collection of software tailored for domestic wifi
router or IoT device devices, of the kind that OpenWrt or DD-WRT or
Gargoyle or Tomato run on. It's a reboot/restart/rewrite of NixWRT.
This is not NixOS-on-your-router: it's aimed at devices that are
underpowered for the full NixOS experience.
underpowered for the full NixOS experience. It uses busybox tools,
musl instead of GNU libc, and s6-rc instead of systemd.
## Building
These instructions assume you have nixpkgs checked out in a peer
directory of this one.
You need a `configuration.nix` file pointed to by `<liminix-config>`, a
hardware device definition as argument `device`, and to choose an
appropriate output attribute depending on what your device is and how
you plan to install onto it. For example:
NIX_PATH=nixpkgs=../nixpkgs:$NIX_PATH NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix-build -I liminix-config=./tests/smoke/configuration.nix --arg device "import ./devices/qemu.nix" -A outputs.default
`outputs.default` is intended to do something appropriate for the
device, whatever that is. For the qemu device, it creates a directory
containing a squashfs root image and a kernel, with which you could
then run
./run-qemu.sh result/vmlinux result/squashfs
## Running tests
@ -22,7 +44,6 @@ Assuming you have nixpkgs checked out in a peer directory of this one,
NIX_PATH=nixpkgs=../nixpkgs:$NIX_PATH ./run-tests.sh
## Articles of interest
* [Build Safety of Software in 28 Popular Home Routers](https://cyber-itl.org/assets/papers/2018/build_safety_of_software_in_28_popular_home_routers.pdf):

View file

@ -25,5 +25,11 @@ let
in {
outputs = {
inherit squashfs kernel;
default = nixpkgs.pkgs.runCommand "both-kinds" {} ''
mkdir $out
cd $out
ln -s ${squashfs} squashfs
ln -s ${kernel.vmlinux} vmlinux
'';
};
}

View file

@ -9,6 +9,9 @@
};
};
kernel = {
checkedConfig = {
"BINFMT_SCRIPT" = "y";
};
config = {
SYSVIPC= "y";
NO_HZ= "y";
@ -343,17 +346,9 @@
UIO_CIF= "m";
EXT2_FS= "y";
EXT3_FS= "y";
REISERFS_FS= "m";
REISERFS_PROC_INFO= "y";
REISERFS_FS_XATTR= "y";
REISERFS_FS_POSIX_ACL= "y";
REISERFS_FS_SECURITY= "y";
JFS_FS= "m";
JFS_POSIX_ACL= "y";
JFS_SECURITY= "y";
XFS_FS= "m";
XFS_QUOTA= "y";
XFS_POSIX_ACL= "y";
QUOTA= "y";
QFMT_V2= "y";
FUSE_FS= "m";
@ -366,9 +361,6 @@
PROC_KCORE= "y";
TMPFS= "y";
CONFIGFS_FS= "y";
AFFS_FS= "m";
HFS_FS= "m";
HFSPLUS_FS= "m";
BEFS_FS= "m";
BFS_FS= "m";
EFS_FS= "m";
@ -382,10 +374,10 @@
ROMFS_FS= "m";
SYSV_FS= "m";
UFS_FS= "m";
NFS_FS= "y";
ROOT_NFS= "y";
NFSD= "y";
NFSD_V3= "y";
# NFS_FS= "y";
# ROOT_NFS= "y";
# NFSD= "y";
# NFSD_V3= "y";
NLS_CODEPAGE_437= "m";
NLS_CODEPAGE_737= "m";
NLS_CODEPAGE_775= "m";
@ -444,6 +436,13 @@
CRYPTO_TWOFISH= "m";
RCU_CPU_STALL_TIMEOUT = "60";
ENABLE_DEFAULT_TRACERS = "y";
SQUASHFS = "y";
SQUASHFS_XZ = "y";
VIRTIO_PCI = "y";
VIRTIO_BLK = "y";
VIRTIO_NET = "y";
};
};
}

View file

@ -1,6 +1,14 @@
pkgs: config:
let
inherit (pkgs) callPackage stdenvNoCC closureInfo stdenv writeText s6-rc;
inherit (pkgs)
callPackage
closureInfo
runCommand
s6-rc
stdenv
stdenvNoCC
writeScript
writeText;
# we need to generate s6 db, by generating closure of all
# config.services and calling s6-rc-compile on them
@ -28,8 +36,46 @@ let
s6-rc-compile $out/compiled $srcs
'';
};
makeSquashfs = callPackage <nixpkgs/nixos/lib/make-squashfs.nix> {
storeContents = [ s6db ] ++ config.packages ;
rcS = writeScript "rcS" ''
#!${pkgs.pkgsStatic.busybox}/bin/sh
echo WHEEEE
PATH=${pkgs.pkgsStatic.busybox}/bin:$PATH
export PATH
mount -t devtmpfs none /dev/
mount -t devpts none /dev/pts
mount -t proc none /proc
mkdir -p /run/services
'';
storefs = callPackage <nixpkgs/nixos/lib/make-squashfs.nix> {
storeContents = [ rcS pkgs.pkgsStatic.busybox s6db pkgs.s6-linux-init ] ++ config.packages ;
# comp = "xz -Xdict-size 100%"
};
in makeSquashfs
pseudofiles = writeText "pseudofiles" ''
/ d 0755 0 0
/bin d 0755 0 0
/etc d 0755 0 0
/run d 0755 0 0
/dev d 0755 0 0
/dev/console c 0600 root root 5 1
/dev/null c 0666 root root 1 3
/dev/tty c 0777 root root 5 0
/dev/tty1 c 0777 root root 4 1
/dev/tty2 c 0777 root root 4 2
/dev/tty3 c 0777 root root 4 3
/dev/tty4 c 0777 root root 4 4
/dev/zero c 0666 root root 1 5
/proc d 0555 root root
/dev/pts d 0755 0 0
/etc/init.d d 0755 0 0
/bin/init s 0755 0 0 ${pkgs.pkgsStatic.busybox}/bin/init
/bin/sh s 0755 0 0 ${pkgs.pkgsStatic.busybox}/bin/sh
/bin/busybox s 0755 0 0 ${pkgs.pkgsStatic.busybox}/bin/busybox
/etc/init.d/rcS s 0755 0 0 ${rcS}
'';
in runCommand "frob-squashfs" {} ''
cp ${storefs} ./store.img
chmod +w store.img
${pkgs.buildPackages.squashfsTools}/bin/mksquashfs - store.img -no-recovery -quiet -no-progress -root-becomes store -p "/ d 0755 0 0"
${pkgs.buildPackages.squashfsTools}/bin/mksquashfs - store.img -no-recovery -quiet -no-progress -root-becomes nix -pf ${pseudofiles}
cp store.img $out
''

View file

@ -24,6 +24,6 @@ in
{
vmlinux = callPackage ./make-vmlinux.nix {
inherit tree;
config = config.kernel.config;
inherit (config.kernel) config;# checkedConfig;
};
}

View file

@ -1,6 +1,8 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p qemu
qemu-system-mips -M malta -m 256 \
-append "earlyprintk=serial,ttyS0 console=ttyS0,38400n8 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/vda" \
-kernel $1 -nographic -display none -serial mon:stdio
qemu-system-mips \
-M malta -m 256 \
-append "earlyprintk=serial,ttyS0 console=ttyS0,38400n8 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/vda" \
-drive file=$2,format=raw,readonly,if=virtio \
-kernel $1 -nographic -display none -serial mon:stdio