From 7bc1e4d8d506462c7d40118196f79a709f3fecfd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 21 Aug 2013 22:36:32 +0200 Subject: m68k: Add support to export bootinfo in procfs Add optional support to export the bootinfo used to boot the kernel in a "bootinfo" file in procfs. This is useful with kexec. This is based on the similar feature for ATAGS on ARM. Signed-off-by: Geert Uytterhoeven --- arch/m68k/kernel/bootinfo_proc.c | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 arch/m68k/kernel/bootinfo_proc.c (limited to 'arch/m68k/kernel/bootinfo_proc.c') diff --git a/arch/m68k/kernel/bootinfo_proc.c b/arch/m68k/kernel/bootinfo_proc.c new file mode 100644 index 0000000..7ee853e --- /dev/null +++ b/arch/m68k/kernel/bootinfo_proc.c @@ -0,0 +1,80 @@ +/* + * Based on arch/arm/kernel/atags_proc.c + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + + +static char bootinfo_tmp[1536] __initdata; + +static void *bootinfo_copy; +static size_t bootinfo_size; + +static ssize_t bootinfo_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + return simple_read_from_buffer(buf, count, ppos, bootinfo_copy, + bootinfo_size); +} + +static const struct file_operations bootinfo_fops = { + .read = bootinfo_read, + .llseek = default_llseek, +}; + +void __init save_bootinfo(const struct bi_record *bi) +{ + const void *start = bi; + size_t size = sizeof(bi->tag); + + while (be16_to_cpu(bi->tag) != BI_LAST) { + uint16_t n = be16_to_cpu(bi->size); + size += n; + bi = (struct bi_record *)((unsigned long)bi + n); + } + + if (size > sizeof(bootinfo_tmp)) { + pr_err("Cannot save %zu bytes of bootinfo\n", size); + return; + } + + pr_info("Saving %zu bytes of bootinfo\n", size); + memcpy(bootinfo_tmp, start, size); + bootinfo_size = size; +} + +static int __init init_bootinfo_procfs(void) +{ + /* + * This cannot go into save_bootinfo() because kmalloc and proc don't + * work yet when it is called. + */ + struct proc_dir_entry *pde; + + if (!bootinfo_size) + return -EINVAL; + + bootinfo_copy = kmalloc(bootinfo_size, GFP_KERNEL); + if (!bootinfo_copy) + return -ENOMEM; + + memcpy(bootinfo_copy, bootinfo_tmp, bootinfo_size); + + pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_fops, NULL); + if (!pde) { + kfree(bootinfo_copy); + return -ENOMEM; + } + + return 0; +} + +arch_initcall(init_bootinfo_procfs); -- cgit v1.1