From a5cfa37ed3f640e60adf890ecd29a06f1cd0182d Mon Sep 17 00:00:00 2001
From: Daniel Barlow <dan@telent.net>
Date: Thu, 23 Mar 2023 21:50:44 +0000
Subject: [PATCH] unify kernel command line handling

We now use MIPS_CMDLINE_DTB_EXTEND for all boot varieties
(tftpboot, flash boot, kexec) with the addition of
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE - local patch -
so that the bootloader args are ignored unless they
contain the string "liminix"
---
 modules/base.nix                 |  4 ++
 modules/flashable.nix            |  4 --
 modules/kexecboot.nix            |  3 --
 modules/tftpboot.nix             |  5 +--
 pkgs/kernel/cmdline-cookie.patch | 63 ++++++++++++++++++++++++++++++++
 pkgs/kernel/default.nix          |  5 +++
 6 files changed, 74 insertions(+), 10 deletions(-)
 create mode 100644 pkgs/kernel/cmdline-cookie.patch

diff --git a/modules/base.nix b/modules/base.nix
index 29ade8f65..7015b0f53 100644
--- a/modules/base.nix
+++ b/modules/base.nix
@@ -79,6 +79,10 @@ in {
         MODULE_SIG = "y";
         DEBUG_FS = "y";
 
+        MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
+        MIPS_BOOTLOADER_CMDLINE_COOKIE = "\"liminix\"";
+        MIPS_CMDLINE_DTB_EXTEND = "y";
+
         # basic networking protocols
         NET = "y";
         UNIX = "y";
diff --git a/modules/flashable.nix b/modules/flashable.nix
index 20162103e..a88ef88b2 100644
--- a/modules/flashable.nix
+++ b/modules/flashable.nix
@@ -14,10 +14,6 @@ in {
     kernel = {
       config = {
         MTD_SPLIT_UIMAGE_FW = "y";
-        # ignore the commandline provided by U-Boot because it's most
-        # likely wrong
-        MIPS_CMDLINE_FROM_BOOTLOADER = lib.mkForce "n";
-        MIPS_CMDLINE_FROM_DTB = "y";
       };
     };
 
diff --git a/modules/kexecboot.nix b/modules/kexecboot.nix
index 43468cc85..c78b7c9de 100644
--- a/modules/kexecboot.nix
+++ b/modules/kexecboot.nix
@@ -11,9 +11,6 @@ in {
   config = {
     boot.ramdisk.enable = true;
 
-    kernel.config.MIPS_CMDLINE_FROM_DTB = "y";
-    kernel.config.MIPS_CMDLINE_FROM_BOOTLOADER = mkForce "n";
-
     outputs.kexecboot =
       let o = config.outputs; in
       pkgs.runCommand "kexecboot" {} ''
diff --git a/modules/tftpboot.nix b/modules/tftpboot.nix
index 974614e4f..48f2d2a8a 100644
--- a/modules/tftpboot.nix
+++ b/modules/tftpboot.nix
@@ -11,7 +11,6 @@ in {
   imports = [ ./ramdisk.nix ];
   config = {
     boot.ramdisk.enable = true;
-    kernel.config.MIPS_CMDLINE_FROM_BOOTLOADER = "y";
 
     outputs.tftpboot =
       let o = config.outputs; in
@@ -35,12 +34,12 @@ in {
           squashfsStart=0x$(printf %x $((${cfg.loadAddress} + 0x100000 + $uimageSize)))
           squashfsBytes=$(($(stat -L -c %s ${config.outputs.squashfs}) + 0x100000 &(~0xfffff)))
           squashfsMb=$(($squashfsBytes >> 20))
-          cmd="mtdparts=phram0:''${squashfsMb}M(nix) phram.phram=phram0,''${squashfsStart},''${squashfsMb}Mi memmap=''${squashfsMb}M\$''${squashfsStart} root=1f00";
+          cmd="mtdparts=phram0:''${squashfsMb}M(rootfs) phram.phram=phram0,''${squashfsStart},''${squashfsMb}Mi memmap=''${squashfsMb}M\$''${squashfsStart} root=1f00";
 
           cat > $out << EOF
           setenv serverip ${cfg.serverip}
           setenv ipaddr ${cfg.ipaddr}
-          setenv bootargs '${concatStringsSep " " config.boot.commandLine} $cmd'
+          setenv bootargs 'liminix $cmd'
           tftp 0x$(printf %x ${cfg.loadAddress}) result/uimage ; tftp 0x$(printf %x $squashfsStart) result/squashfs
           bootm 0x$(printf %x ${cfg.loadAddress})
           EOF
diff --git a/pkgs/kernel/cmdline-cookie.patch b/pkgs/kernel/cmdline-cookie.patch
new file mode 100644
index 000000000..468787521
--- /dev/null
+++ b/pkgs/kernel/cmdline-cookie.patch
@@ -0,0 +1,63 @@
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 393eb2133243..f61bfbaa4001 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -3157,6 +3157,24 @@ choice
+ 		  if you don't intend to always append a DTB.
+ endchoice
+ 
++config MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE
++	bool "Ignore bootloader command-line unless cookie present"
++	default n
++
++config MIPS_BOOTLOADER_CMDLINE_COOKIE
++	string "Bootloader kernel argument cookie string"
++	depends on MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE
++	help
++	  Use bootloader command line if and only if it contains
++	  this string. Some bootloaders allow setting the command line
++	  for interactive boots but provide an incorrect (and
++	  unchangeable) default when booting unattended.
++
++	  This option can be combined with e.g. MIPS_CMDLINE_DTB_EXTEND
++	  or MIPS_CMDLINE_BUILTIN_EXTEND: it doesn't affect
++	  where else your command line comes from, just whether
++	  the bootloader-provided command line is used as part of it.
++
+ choice
+ 	prompt "Kernel command line type" if !CMDLINE_OVERRIDE
+ 	default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index ef73ba1e0ec1..52a836c43630 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -72,6 +72,12 @@ static const char builtin_cmdline[] __initconst = CONFIG_CMDLINE;
+ static const char builtin_cmdline[] __initconst = "";
+ #endif
+ 
++#ifdef CONFIG_MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE
++static const char cmdline_cookie[] __initconst = CONFIG_MIPS_BOOTLOADER_CMDLINE_COOKIE;
++#else
++static const char cmdline_cookie[] __initconst = NULL;
++#endif
++
+ /*
+  * mips_io_port_base is the begin of the address space to which x86 style
+  * I/O ports are mapped.
+@@ -558,6 +564,16 @@ static void __init bootcmdline_init(void)
+ 		return;
+ 	}
+ 
++	/* If CMDLINE_REQUIRE_COOKIE is set to a string, we require that
++	 * string to be present in the bootloader command line, otherwise
++	 * we ignore it. This is to accommodate bootloaders that allow
++	 * the command line to be specified for interactive boots but
++	 * hardcode an incorrect command line for unattended boots */
++#ifdef CONFIG_MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE
++	if(strstr(arcs_cmdline, cmdline_cookie) == NULL) {
++	    arcs_cmdline[0] = '\0';
++	}
++#endif
+ 	/*
+ 	 * If the user specified a built-in command line &
+ 	 * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix
index ed0636143..ce7df46d3 100644
--- a/pkgs/kernel/default.nix
+++ b/pkgs/kernel/default.nix
@@ -41,6 +41,7 @@ stdenv.mkDerivation rec {
     "unpackPhase"
     "butcherPkgconfig"
     "extraPatchPhase"
+    "patchPhase"
     "patchScripts"
     "configurePhase"
     "checkConfigurationPhase"
@@ -48,6 +49,10 @@ stdenv.mkDerivation rec {
     "installPhase"
   ];
 
+  patches = [
+    ./cmdline-cookie.patch
+  ];
+
   # this is here to work around what I think is a bug in nixpkgs
   # packaging of ncurses: it installs pkg-config data files which
   # don't produce any -L options when queried with "pkg-config --lib