Compare commits
8 commits
main
...
strong-tft
Author | SHA1 | Date | |
---|---|---|---|
|
499e30cdd7 | ||
|
3c33c0eaf4 | ||
|
e25df0b6e2 | ||
|
4be1d9c95c | ||
|
0550e0a5b1 | ||
|
7fb23079c2 | ||
|
4689bb9bb1 | ||
|
5b5b527f92 |
12 changed files with 183 additions and 35 deletions
|
@ -170,7 +170,7 @@
|
|||
maxLEBcount = "256";
|
||||
};
|
||||
|
||||
flash.eraseBlockSize = 65536;
|
||||
flash.eraseBlockSize = 64 * 1024;
|
||||
|
||||
# This is a FIT containing a kernel padded and
|
||||
# a UBI volume rootfs.
|
||||
|
@ -181,8 +181,8 @@
|
|||
# Aligned on 2kb.
|
||||
alignment = 2048;
|
||||
|
||||
rootDevice = "ubi:rootfs";
|
||||
alternativeRootDevice = "ubi:rootfs";
|
||||
rootDevice = "ubi0:rootfs";
|
||||
alternativeRootDevice = "ubi1:rootfs";
|
||||
|
||||
# Auto-attach MTD devices: ubi_a then ubi_b.
|
||||
ubi.mtds = [ "ubi_a" "ubi_b" ];
|
||||
|
@ -224,6 +224,7 @@
|
|||
tftp = {
|
||||
# 5MB is nice.
|
||||
freeSpaceBytes = 5 * 1024 * 1024;
|
||||
appendDTB = true;
|
||||
loadAddress = lim.parseInt "0x2000000";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -14,5 +14,8 @@
|
|||
boot.commandLine = [
|
||||
"console=ttyS0,115200" # true of all mips we've yet encountered
|
||||
];
|
||||
boot.tftp.commandLine = [
|
||||
"console=ttyS0,115200" # true of all mips we've yet encountered
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -109,7 +109,13 @@ in {
|
|||
]
|
||||
++ (map (mtd: "ubi.mtd=${mtd}") config.hardware.ubi.mtds)
|
||||
++ lib.optional (config.rootOptions != null) "rootflags=${config.rootOptions}"
|
||||
++ lib.optional (config.hardware.alternativeRootDevice != null) "altroot=${config.hardware.alternativeRootDevice}";
|
||||
++ lib.optional (config.hardware.alternativeRootDevice != null) "rootalt=${config.hardware.alternativeRootDevice}";
|
||||
|
||||
boot.tftp.commandLine = [
|
||||
"panic=10 oops=panic init=/bin/init loglevel=8"
|
||||
"fw_devlink=off"
|
||||
"rootfstype=${config.rootfsType}"
|
||||
];
|
||||
|
||||
system.callService = path : parameters :
|
||||
let
|
||||
|
|
|
@ -26,6 +26,10 @@ in {
|
|||
interface = mkOption {
|
||||
type = liminix.lib.types.service;
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.hostapd;
|
||||
};
|
||||
params = mkOption {
|
||||
type = types.attrs;
|
||||
};
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
{
|
||||
liminix
|
||||
, hostapd
|
||||
, writeText
|
||||
, lib
|
||||
}:
|
||||
{ interface, params} :
|
||||
{ package, interface, params } :
|
||||
let
|
||||
inherit (liminix.services) longrun;
|
||||
inherit (lib) concatStringsSep mapAttrsToList;
|
||||
|
@ -35,5 +34,5 @@ let
|
|||
in longrun {
|
||||
inherit name;
|
||||
dependencies = [ interface ];
|
||||
run = "${hostapd}/bin/hostapd -i $(output ${interface} ifname) -P /run/${name}.pid -S ${conf}";
|
||||
run = "${package}/bin/hostapd -i $(output ${interface} ifname) -P /run/${name}.pid -S ${conf}";
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
, ...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkIf mkOption types;
|
||||
inherit (pkgs) liminix;
|
||||
inherit (lib) mkIf;
|
||||
o = config.system.outputs;
|
||||
in
|
||||
{
|
||||
|
@ -24,17 +25,10 @@ in
|
|||
};
|
||||
boot.initramfs.enable = true;
|
||||
system.outputs = {
|
||||
rootfs =
|
||||
let
|
||||
inherit (pkgs.pkgsBuildBuild) runCommand mtdutils;
|
||||
endian = if pkgs.stdenv.isBigEndian
|
||||
then "--big-endian" else "--little-endian";
|
||||
in runCommand "make-jffs2" {
|
||||
depsBuildBuild = [ mtdutils ];
|
||||
} ''
|
||||
tree=${o.bootablerootdir}
|
||||
(cd $tree && mkfs.jffs2 --compression-mode=size ${endian} -e ${toString config.hardware.flash.eraseBlockSize} --enable-compressor=lzo --pad --root . --output $out --squash --faketime )
|
||||
'';
|
||||
rootfs = liminix.builders.jffs2 {
|
||||
bootableRootDirectory = o.bootablerootdir;
|
||||
inherit (config.hardware.flash) eraseBlockSize;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
14
modules/outputs/tftpboot-fit.its
Normal file
14
modules/outputs/tftpboot-fit.its
Normal file
|
@ -0,0 +1,14 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "Liminix TFTP bootscript";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
bootscript {
|
||||
description = "Bootscript";
|
||||
data = /incbin/("boot.scr");
|
||||
type = "script";
|
||||
compression = "none";
|
||||
};
|
||||
};
|
|
@ -5,10 +5,18 @@
|
|||
, ...
|
||||
}:
|
||||
let
|
||||
inherit (lib) mkOption types concatStringsSep;
|
||||
inherit (lib) mkOption mkIf types concatStringsSep;
|
||||
inherit (pkgs) liminix;
|
||||
cfg = config.boot.tftp;
|
||||
hw = config.hardware;
|
||||
arch = pkgs.stdenv.hostPlatform.linuxArch;
|
||||
|
||||
# UBI cannot run on the top of phram.
|
||||
needsSquashfs = config.rootfsType == "ubifs";
|
||||
rootfstype = if needsSquashfs then "squashfs" else config.rootfsType;
|
||||
rootfs = if needsSquashfs then
|
||||
liminix.builders.squashfs config.filesystem.contents
|
||||
else config.system.outputs.rootfs;
|
||||
in {
|
||||
imports = [ ../ramdisk.nix ];
|
||||
options.boot.tftp = {
|
||||
|
@ -28,6 +36,14 @@ in {
|
|||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
commandLine = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = config.boot.commandLine;
|
||||
description = ''
|
||||
TFTP-specific command line.
|
||||
Defaults to the classical one if unset.
|
||||
'';
|
||||
};
|
||||
};
|
||||
options.system.outputs = {
|
||||
tftpboot = mkOption {
|
||||
|
@ -51,11 +67,52 @@ in {
|
|||
It uses the Linux `phram <https://github.com/torvalds/linux/blob/master/drivers/mtd/devices/phram.c>`_ driver to emulate a flash device using a segment of physical RAM.
|
||||
'';
|
||||
};
|
||||
|
||||
tftpboot-fit = mkOption {
|
||||
type = types.package;
|
||||
description = ''
|
||||
tftpboot-fit
|
||||
************
|
||||
|
||||
This output is a variant that encloses the `boot.scr` in a FIT
|
||||
if that's simpler to transfer for you.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = {
|
||||
boot.ramdisk.enable = true;
|
||||
|
||||
kernel.config = mkIf needsSquashfs {
|
||||
SQUASHFS = "y";
|
||||
SQUASHFS_XZ = "y";
|
||||
};
|
||||
|
||||
system.outputs = rec {
|
||||
tftpboot-fit =
|
||||
let
|
||||
tftpboot-fit = pkgs.writeText "tftpboot.its" ''
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "Liminix TFTP bootscript";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
bootscript {
|
||||
description = "Bootscript";
|
||||
data = /incbin/("${tftpboot}/boot.scr");
|
||||
type = "script";
|
||||
compression = "none";
|
||||
};
|
||||
};
|
||||
};
|
||||
'';
|
||||
in
|
||||
pkgs.runCommand "tftpboot-fit" { nativeBuildInputs = with pkgs.pkgsBuildBuild; [ ubootTools ]; } ''
|
||||
mkdir -p $out/
|
||||
cp -rf ${tftpboot}/* $out/
|
||||
mkimage -f ${tftpboot-fit} $out/script.ub
|
||||
'';
|
||||
tftpboot =
|
||||
let
|
||||
inherit (pkgs.lib.trivial) toHexString;
|
||||
|
@ -69,7 +126,7 @@ in {
|
|||
zimage = "bootz";
|
||||
}; in choices.${cfg.kernelFormat};
|
||||
|
||||
cmdline = concatStringsSep " " config.boot.commandLine;
|
||||
cmdline = concatStringsSep " " config.boot.tftp.commandLine;
|
||||
objcopy = "${pkgs.stdenv.cc.bintools.targetPrefix}objcopy";
|
||||
stripAndZip = ''
|
||||
${objcopy} -O binary -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id -S vmlinux.elf vmlinux.bin
|
||||
|
@ -84,7 +141,7 @@ in {
|
|||
hex() { printf "0x%x" $1; }
|
||||
|
||||
rootfsStart=${toString cfg.loadAddress}
|
||||
rootfsSize=$(binsize64k ${o.rootfs} )
|
||||
rootfsSize=$(binsize64k ${rootfs} )
|
||||
rootfsSize=$(($rootfsSize + ${toString cfg.freeSpaceBytes} ))
|
||||
|
||||
ln -s ${o.manifest} manifest
|
||||
|
@ -98,13 +155,13 @@ in {
|
|||
dtbStart=$(($rootfsStart + $rootfsSize))
|
||||
${if cfg.compressRoot
|
||||
then ''
|
||||
lzma -z9cv ${o.rootfs} > rootfs.lz
|
||||
lzma -z9cv ${rootfs} > rootfs.lz
|
||||
rootfsLzStart=$dtbStart
|
||||
rootfsLzSize=$(binsize rootfs.lz)
|
||||
dtbStart=$(($dtbStart + $rootfsLzSize))
|
||||
''
|
||||
else ''
|
||||
ln -s ${o.rootfs} rootfs
|
||||
ln -s ${rootfs} rootfs
|
||||
''
|
||||
}
|
||||
|
||||
|
@ -121,7 +178,7 @@ in {
|
|||
fdtput -p -t s dtb /reserved-memory/$node compatible phram
|
||||
fdtput -p -t lx dtb /reserved-memory/$node reg $ac_prefix $(hex $rootfsStart) $sz_prefix $(hex $rootfsSize)
|
||||
|
||||
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} root=/dev/mtdblock0";
|
||||
cmd="liminix ${cmdline} mtdparts=phram0:''${rootfsSize}(rootfs) phram.phram=phram0,''${rootfsStart},''${rootfsSize},${toString config.hardware.flash.eraseBlockSize} rootfstype=${rootfstype} root=/dev/mtdblock0";
|
||||
fdtput -t s dtb /chosen ${config.boot.commandLineDtbNode} "$cmd"
|
||||
|
||||
dtbSize=$(binsize ./dtb )
|
||||
|
|
36
overlay.nix
36
overlay.nix
|
@ -143,6 +143,42 @@ extraPkgs // {
|
|||
});
|
||||
in h.override { openssl = null; sqlite = null; };
|
||||
|
||||
hostapd-radius =
|
||||
let
|
||||
config = [
|
||||
"CONFIG_DRIVER_NL80211=y"
|
||||
"CONFIG_DRIVER_WIRED=y"
|
||||
"CONFIG_EAP=y"
|
||||
"CONFIG_EAP_PEAP=y"
|
||||
"CONFIG_RADIUS_SERVER=y"
|
||||
"CONFIG_FULL_DYNAMIC_VLAN=y"
|
||||
"CONFIG_IAPP=y"
|
||||
"CONFIG_IEEE80211AC=y"
|
||||
"CONFIG_IEEE80211AX=y"
|
||||
"CONFIG_IEEE80211N=y"
|
||||
"CONFIG_IEEE80211W=y"
|
||||
"CONFIG_INTERNAL_LIBTOMMATH=y"
|
||||
"CONFIG_INTERNAL_LIBTOMMATH_FAST=y"
|
||||
"CONFIG_IPV6=y"
|
||||
"CONFIG_LIBNL32=y"
|
||||
"CONFIG_PKCS12=y"
|
||||
"CONFIG_RSN_PREAUTH=y"
|
||||
# Required to read the key material for RADIUS.
|
||||
"CONFIG_TLS=openssl"
|
||||
];
|
||||
h = prev.hostapd.overrideAttrs(o: {
|
||||
extraConfig = "";
|
||||
configurePhase = ''
|
||||
cat > hostapd/defconfig <<EOF
|
||||
${builtins.concatStringsSep "\n" config}
|
||||
EOF
|
||||
${o.configurePhase}
|
||||
'';
|
||||
});
|
||||
in h.override { sqlite = null; };
|
||||
|
||||
|
||||
|
||||
kexec-tools-static = prev.kexec-tools.overrideAttrs(o: {
|
||||
# For kexecboot we copy kexec into a ramdisk on the system being
|
||||
# upgraded from. This is more likely to work if kexec is
|
||||
|
|
|
@ -13,6 +13,7 @@ in {
|
|||
liminix = {
|
||||
builders = {
|
||||
squashfs = callPackage ./liminix-tools/builders/squashfs.nix {};
|
||||
jffs2 = callPackage ./liminix-tools/builders/jffs2.nix {};
|
||||
dtb = callPackage ./kernel/dtb.nix {};
|
||||
uimage = callPackage ./kernel/uimage.nix {};
|
||||
kernel = callPackage ./kernel {};
|
||||
|
|
17
pkgs/liminix-tools/builders/jffs2.nix
Normal file
17
pkgs/liminix-tools/builders/jffs2.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
stdenv
|
||||
, busybox
|
||||
, buildPackages
|
||||
, callPackage
|
||||
, pseudofile
|
||||
, runCommand
|
||||
, writeText
|
||||
} : { eraseBlockSize, bootableRootDirectory }:
|
||||
let
|
||||
endian = if stdenv.isBigEndian then "--big-endian" else "--little-endian";
|
||||
in runCommand "frob-jffs2" {
|
||||
depsBuildBuild = [ buildPackages.mtdutils ];
|
||||
} ''
|
||||
tree=${bootableRootDirectory}
|
||||
(cd $tree && mkfs.jffs2 --compression-mode=size ${endian} -e ${toString eraseBlockSize} --enable-compressor=lzo --pad --root . --output $out --squash --faketime)
|
||||
''
|
|
@ -65,13 +65,18 @@ static char * eat_param(char *p, char *param_name, char **out)
|
|||
return p;
|
||||
}
|
||||
|
||||
#define SCAN_CMDLINE(cmdline, identifier, field) do { \
|
||||
for (char* p = strdup(cmdline); *p; p++) { \
|
||||
p = eat_param(p, identifier, &(opts->field)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
void parseopts(char * cmdline, struct root_opts *opts) {
|
||||
for(char *p = cmdline; *p; p++) {
|
||||
p = eat_param(p, "root=", &(opts->device));
|
||||
p = eat_param(p, "rootfstype=", &(opts->fstype));
|
||||
p = eat_param(p, "rootflags=", &(opts->mount_opts));
|
||||
p = eat_param(p, "altroot=", &(opts->altdevice));
|
||||
};
|
||||
SCAN_CMDLINE(cmdline, "root=", device);
|
||||
SCAN_CMDLINE(cmdline, "rootfstype=", fstype);
|
||||
SCAN_CMDLINE(cmdline, "rootflags=", mount_opts);
|
||||
SCAN_CMDLINE(cmdline, "rootalt=", altdevice);
|
||||
}
|
||||
|
||||
#ifdef TESTS
|
||||
|
@ -85,6 +90,8 @@ void parseopts(char * cmdline, struct root_opts *opts) {
|
|||
#define S(x) #x
|
||||
#define expect_equal(actual, expected) \
|
||||
if(!actual || strcmp(actual, expected)) die("%d: expected \"%s\", got \"%s\"", __LINE__, expected, actual);
|
||||
#define expect_null(actual) \
|
||||
if (actual) die("%d: expected null, got \"%s\"", __LINE__, actual);
|
||||
|
||||
|
||||
int main()
|
||||
|
@ -92,6 +99,7 @@ int main()
|
|||
struct root_opts opts = {
|
||||
.device = "/dev/hda1",
|
||||
.fstype = "xiafs",
|
||||
.altdevice = NULL,
|
||||
.mount_opts = NULL
|
||||
};
|
||||
char *buf;
|
||||
|
@ -103,14 +111,22 @@ int main()
|
|||
expect_equal(opts.fstype, "ubifs");
|
||||
expect_equal(opts.mount_opts, "subvol=1");
|
||||
|
||||
// finds altroot= options
|
||||
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs rootflags=subvol=1 fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0 altroot=/dev/mtdblock6 foo");
|
||||
// finds rootalt= options
|
||||
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs rootflags=subvol=1 fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0 rootalt=/dev/mtdblock6 foo");
|
||||
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts);
|
||||
expect_equal(opts.device, "/dev/mtdblock0");
|
||||
expect_equal(opts.altdevice, "/dev/mtdblock6");
|
||||
expect_equal(opts.fstype, "ubifs");
|
||||
expect_equal(opts.mount_opts, "subvol=1");
|
||||
|
||||
// Ensure that `altdevice` is NULL.
|
||||
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 fw_devlink=off rootfstype=ubifs mtdparts=phram0:19791872(rootfs) phram.phram=phram0,33554432,19791872,65536 rootfstype=jffs2 root=/dev/mtdblock0");
|
||||
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts);
|
||||
expect_equal(opts.device, "/dev/mtdblock0");
|
||||
expect_null(opts.altdevice);
|
||||
expect_equal(opts.fstype, "jffs2");
|
||||
expect_null(opts.mount_opts);
|
||||
|
||||
// in case of duplicates, chooses the latter
|
||||
// also: works if the option is end of string
|
||||
buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0");
|
||||
|
@ -146,12 +162,12 @@ int main()
|
|||
if(opts.altdevice) die("expected null altdevice, got \"%s\"", opts.altdevice);
|
||||
|
||||
// provides empty strings for empty options
|
||||
buf = strdup("liminix rootfstype= fw_devlink=off root= altroot= /dev/hda1");
|
||||
buf = strdup("liminix rootfstype= fw_devlink=off root= rootalt= /dev/hda1");
|
||||
memset(&opts, '\0', sizeof opts); parseopts(buf, &opts);
|
||||
|
||||
if(strlen(opts.fstype)) die("expected empty rootfstype, got \"%s\"", opts.fstype);
|
||||
if(strlen(opts.device)) die("expected empty root, got \"%s\"", opts.device);
|
||||
if(strlen(opts.altdevice)) die("expected empty altroot, got \"%s\"", opts.altdevice);
|
||||
if(strlen(opts.altdevice)) die("expected empty rootalt, got \"%s\"", opts.altdevice);
|
||||
|
||||
expect_equal("01", pr_u32(1));
|
||||
expect_equal("ab", pr_u32(0xab));
|
||||
|
|
Loading…
Reference in a new issue