Add ability to run init script through config var
authorKevin Klues <klueska@cs.berkeley.edu>
Thu, 26 Jun 2014 21:06:06 +0000 (14:06 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 26 Jun 2014 21:11:41 +0000 (14:11 -0700)
There is now a config variable that allows you to specify a script to
run after the kernel has booted.  Use this variable to specify the path
to a script, followed by any arguments you want to pass it.  There is
default init.sh script that has been put in kfs/bin that simply calls
ifconfig and then drops you into busybox.

If this config variable isn't set, we still run the manager function, for
backwards compatibility reasons.  Eventually we want to do away with the
managers altogether, but the way jenkins is set up currently prevents
this without some major changes.  Once we have something like Ron's #z
device, we will be able to do away the menager completely since jenkins
will be able to use #z to run kernel tests from userspace.

Kconfig
kern/kfs/bin/init.sh [new file with mode: 0644]
kern/src/init.c

diff --git a/Kconfig b/Kconfig
index 9d3a537..8fa0228 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -15,6 +15,20 @@ config 64BIT
        help
                Say yes to build a 64-bit kernel, amd64 / x86_64, riscv64, etc.
 
+menuconfig RUN_INIT_SCRIPT
+       bool "Run init script after boot"
+       default n
+       help
+               Run an init script after boot instead of dropping into the monitor
+
+config INIT_SCRIPT_PATH_AND_ARGS
+    depends on RUN_INIT_SCRIPT
+    string "Path to init script, followed by its arguments."
+    default /bin/init.sh
+    help
+               Path to the init script run at boot time, followed by a space separated
+               list of arguments
+
 source "kern/arch/$SRCARCH/Kconfig"
 
 source "kern/src/net/Kconfig"
diff --git a/kern/kfs/bin/init.sh b/kern/kfs/bin/init.sh
new file mode 100644 (file)
index 0000000..26f748e
--- /dev/null
@@ -0,0 +1,3 @@
+# This is the default init script.  Simply run ifconfig and drop into a shell
+/ifconfig
+/bin/ash
index 1a76999..bd8074c 100644 (file)
@@ -52,6 +52,7 @@
 int booting = 1;
 struct sysinfo_t sysinfo;
 static void run_linker_funcs(void);
+static int run_init_script(void);
 
 void kernel_init(multiboot_info_t *mboot_info)
 {
@@ -106,7 +107,59 @@ void kernel_init(multiboot_info_t *mboot_info)
        // zra: let's Ivy know we're done booting
        booting = 0;
 
+#ifdef CONFIG_RUN_INIT_SCRIPT
+       if (run_init_script()) {
+               printk("Configured to run init script, but no script specified!\n");
+               manager();
+       }
+#else
        manager();
+#endif
+}
+
+static int run_init_script(void)
+{
+       /* If we have an init script path specified */
+       if (strlen(CONFIG_INIT_SCRIPT_PATH_AND_ARGS) != 0) {
+               int vargs = 0;
+               char *sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
+
+               /* Figure out how many arguments there are, by finding the spaces */
+               while (*sptr != '\0') {
+                       if (*(sptr++) != ' ') {
+                               vargs++;
+                               while ((*sptr != ' ') && (*sptr != '\0'))
+                                       sptr++;
+                       }
+               }
+
+               /* Initialize l_argv with its first three arguments, but allocate space
+                * for all arguments as calculated above */
+               int static_args = 3;
+               int total_args = vargs + static_args;
+               char *l_argv[total_args];
+               l_argv[0] = "";
+               l_argv[1] = "busybox";
+               l_argv[2] = "ash";
+
+               /* Initialize l_argv with the rest of the arguments */
+               int i = static_args;
+               sptr = &CONFIG_INIT_SCRIPT_PATH_AND_ARGS[0];
+               while (*sptr != '\0') {
+                       if (*sptr != ' ') {
+                               char *sbeg = sptr;
+                               while ((*sptr != ' ') && (*sptr != '\0'))
+                                       sptr++;
+                               *sptr = '\0';
+                               l_argv[i++] = sbeg;
+                       }
+                       sptr++;
+               }
+
+               /* Run the script with its arguments */
+               mon_bin_run(total_args, l_argv, NULL);
+       }
+       return -1;
 }
 
 /*