linux/arch/arm/kernel/atags_proc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/slab.h>
   3#include <linux/proc_fs.h>
   4#include <asm/setup.h>
   5#include <asm/types.h>
   6#include <asm/page.h>
   7
   8struct buffer {
   9        size_t size;
  10        char data[];
  11};
  12
  13static ssize_t atags_read(struct file *file, char __user *buf,
  14                          size_t count, loff_t *ppos)
  15{
  16        struct buffer *b = PDE_DATA(file_inode(file));
  17        return simple_read_from_buffer(buf, count, ppos, b->data, b->size);
  18}
  19
  20static const struct proc_ops atags_proc_ops = {
  21        .proc_read      = atags_read,
  22        .proc_lseek     = default_llseek,
  23};
  24
  25#define BOOT_PARAMS_SIZE 1536
  26static char __initdata atags_copy[BOOT_PARAMS_SIZE];
  27
  28void __init save_atags(const struct tag *tags)
  29{
  30        memcpy(atags_copy, tags, sizeof(atags_copy));
  31}
  32
  33static int __init init_atags_procfs(void)
  34{
  35        /*
  36         * This cannot go into save_atags() because kmalloc and proc don't work
  37         * yet when it is called.
  38         */
  39        struct proc_dir_entry *tags_entry;
  40        struct tag *tag = (struct tag *)atags_copy;
  41        struct buffer *b;
  42        size_t size;
  43
  44        if (tag->hdr.tag != ATAG_CORE) {
  45                pr_info("No ATAGs?\n");
  46                return -EINVAL;
  47        }
  48
  49        for (; tag->hdr.size; tag = tag_next(tag))
  50                ;
  51
  52        /* include the terminating ATAG_NONE */
  53        size = (char *)tag - atags_copy + sizeof(struct tag_header);
  54
  55        WARN_ON(tag->hdr.tag != ATAG_NONE);
  56
  57        b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
  58        if (!b)
  59                goto nomem;
  60
  61        b->size = size;
  62        memcpy(b->data, atags_copy, size);
  63
  64        tags_entry = proc_create_data("atags", 0400, NULL, &atags_proc_ops, b);
  65        if (!tags_entry)
  66                goto nomem;
  67
  68        return 0;
  69
  70nomem:
  71        kfree(b);
  72        pr_err("Exporting ATAGs: not enough memory\n");
  73
  74        return -ENOMEM;
  75}
  76arch_initcall(init_atags_procfs);
  77