diff options
author | Shao Miller <sha0.miller@gmail.com> | 2012-10-25 21:25:38 -0400 |
---|---|---|
committer | Shao Miller <sha0.miller@gmail.com> | 2012-11-03 01:08:32 -0400 |
commit | fb3e1a576ca0243c37786bfd81cc9600d589db45 (patch) | |
tree | 618205e05dce97204dcb01af2d8d10de401b797d | |
parent | 66484b55fe52e1393b8c6b522ca8d18b898e18f3 (diff) | |
download | syslinux-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>
-rw-r--r-- | 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 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)) { |