aboutsummaryrefslogtreecommitdiffstats
path: root/com32/modules/linux.c
diff options
context:
space:
mode:
authorShao Miller <sha0.miller@gmail.com>2012-10-25 21:25:38 -0400
committerShao Miller <sha0.miller@gmail.com>2012-11-03 01:08:32 -0400
commitfb3e1a576ca0243c37786bfd81cc9600d589db45 (patch)
tree618205e05dce97204dcb01af2d8d10de401b797d /com32/modules/linux.c
parent66484b55fe52e1393b8c6b522ca8d18b898e18f3 (diff)
downloadsyslinux-fb3e1a576ca0243c37786bfd81cc9600d589db45.tar.gz
syslinux-fb3e1a576ca0243c37786bfd81cc9600d589db45.tar.xz
syslinux-fb3e1a576ca0243c37786bfd81cc9600d589db45.zip
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@gmail.com>
Diffstat (limited to 'com32/modules/linux.c')
-rw-r--r--com32/modules/linux.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/com32/modules/linux.c b/com32/modules/linux.c
index 11cdc18f..f657eab4 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)) {