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