diff options
Diffstat (limited to 'init/initramfs.c')
-rw-r--r-- | init/initramfs.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/init/initramfs.c b/init/initramfs.c index 8d0fd946cdd2..01dbd0e81501 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -16,9 +16,10 @@ #include <linux/mm.h> #include <linux/namei.h> #include <linux/init_syscalls.h> -#include <linux/task_work.h> #include <linux/umh.h> +#include "do_mounts.h" + static __initdata bool csum_present; static __initdata u32 io_csum; @@ -574,6 +575,16 @@ extern unsigned long __initramfs_size; #include <linux/initrd.h> #include <linux/kexec.h> +static ssize_t raw_read(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t pos, size_t count) +{ + memcpy(buf, attr->private + pos, count); + return count; +} + +static BIN_ATTR(initrd, 0440, raw_read, NULL, 0); + void __init reserve_initrd_mem(void) { phys_addr_t start; @@ -669,8 +680,6 @@ static void __init populate_initrd_image(char *err) struct file *file; loff_t pos = 0; - unpack_to_rootfs(__initramfs_start, __initramfs_size); - printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n", err); file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700); @@ -715,13 +724,18 @@ done: * If the initrd region is overlapped with crashkernel reserved region, * free only memory that is not part of crashkernel region. */ - if (!do_retain_initrd && initrd_start && !kexec_free_initrd()) + if (!do_retain_initrd && initrd_start && !kexec_free_initrd()) { free_initrd_mem(initrd_start, initrd_end); + } else if (do_retain_initrd && initrd_start) { + bin_attr_initrd.size = initrd_end - initrd_start; + bin_attr_initrd.private = (void *)initrd_start; + if (sysfs_create_bin_file(firmware_kobj, &bin_attr_initrd)) + pr_err("Failed to create initrd sysfs file"); + } initrd_start = 0; initrd_end = 0; - flush_delayed_fput(); - task_work_run(); + init_flush_fput(); } static ASYNC_DOMAIN_EXCLUSIVE(initramfs_domain); |