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 7 struct buffer { 8 size_t size; 9 char data[]; 10 }; 11 12 static 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 19 static const struct file_operations atags_fops = { 20 .read = atags_read, 21 .llseek = default_llseek, 22 }; 23 24 #define BOOT_PARAMS_SIZE 1536 25 static char __initdata atags_copy[BOOT_PARAMS_SIZE]; 26 27 void __init save_atags(const struct tag *tags) 28 { 29 memcpy(atags_copy, tags, sizeof(atags_copy)); 30 } 31 32 static 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 pr_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 69 nomem: 70 kfree(b); 71 pr_err("Exporting ATAGs: not enough memory\n"); 72 73 return -ENOMEM; 74 } 75 arch_initcall(init_atags_procfs); 76