[syslinux:elflink] linux.c32: Introduce initrdfile= option

syslinux-bot for Shao Miller sha0.miller at gmail.com
Mon Nov 5 08:03:10 PST 2012


Commit-ID:  fb3e1a576ca0243c37786bfd81cc9600d589db45
Gitweb:     http://www.syslinux.org/commit/fb3e1a576ca0243c37786bfd81cc9600d589db45
Author:     Shao Miller <sha0.miller at gmail.com>
AuthorDate: Thu, 25 Oct 2012 21:25:38 -0400
Committer:  Shao Miller <sha0.miller at gmail.com>
CommitDate: Sat, 3 Nov 2012 01:08:32 -0400

linux.c32: Introduce initrdfile= option

It is useful to be able to load a file and pass it into a kernel's
rootfs via the initramfs scheme.  Given "initrdfile=foo", we will
load the file foo, encapsulate it with the initramfs cpio format,
then pass it alongside any initramfs files that were specified by
"initrd=" and "initrd+=" options.

One can specify the desired path/filename for the file to have
within the rootfs by using the at (@) sign, as in:

  initrdfile=foo@/goes/to/foo

One can also specify multiple files, separated by commas, such as:

  initrdfile=foo,bar@/somewhere/bar,baz

One can also use this option multiple times, as in:

  initrdfile=foo,bar initrdfile=baz@/somewhere/baz

Signed-off-by: Shao Miller <sha0.miller at gmail.com>

---
 com32/modules/linux.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/com32/modules/linux.c b/com32/modules/linux.c
index 11cdc18..f657eab 100644
--- a/com32/modules/linux.c
+++ b/com32/modules/linux.c
@@ -50,6 +50,7 @@
 
 enum ldmode {
     ldmode_raw,
+    ldmode_cpio,
     ldmodes
 };
 
@@ -143,6 +144,46 @@ static int ldinitramfs_raw(struct initramfs *initramfs, char *fname)
     return initramfs_load_archive(initramfs, fname);
 }
 
+static f_ldinitramfs ldinitramfs_cpio;
+static int ldinitramfs_cpio(struct initramfs *initramfs, char *fname)
+{
+    char *target_fname, *p;
+    int do_mkdir, unmangle, rc;
+
+    /* Choose target_fname based on presence of "@" syntax */
+    target_fname = strchr(fname, '@');
+    if (target_fname) {
+	/* Temporarily mangle */
+	unmangle = 1;
+	*target_fname++ = '\0';
+
+	/* Make parent directories? */
+	do_mkdir = !!strchr(target_fname, '/');
+    } else {
+	unmangle = 0;
+
+	/* Forget the source path */
+	target_fname = fname;
+	while ((p = strchr(target_fname, '/')))
+	    target_fname = p + 1;
+
+	/* The user didn't specify a desired path */
+	do_mkdir = 0;
+    }
+
+    /*
+     * Load the file, encapsulate it with the desired path, make the
+     * parent directories if the desired path contains them, add to initramfs
+     */
+    rc = initramfs_load_file(initramfs, fname, target_fname, do_mkdir, 0755);
+
+    /* Unmangle, if needed*/
+    if (unmangle)
+	*--target_fname = '@';
+
+    return rc;
+}
+
 /* It only makes sense to call this function from main */
 static int process_initramfs_args(char *arg, struct initramfs *initramfs,
 				  const char *kernel_name, enum ldmode mode,
@@ -157,6 +198,10 @@ static int process_initramfs_args(char *arg, struct initramfs *initramfs,
 	mode_msg = "Loading";
 	ldinitramfs = ldinitramfs_raw;
 	break;
+    case ldmode_cpio:
+	mode_msg = "Encapsulating";
+	ldinitramfs = ldinitramfs_cpio;
+	break;
     case ldmodes:
     default:
 	return 1;
@@ -299,6 +344,14 @@ int main(int argc, char *argv[])
 	    goto bail;
     }
 
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "initrdfile="))) {
+	argl++;
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_cpio,
+				   opt_quiet))
+	    goto bail;
+    }
+
     /* Append the DHCP info */
     if (opt_dhcpinfo &&
 	!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {


More information about the Syslinux-commits mailing list