[oe] [PATHC] ATAG export for the linux kernel
Uli Luckas
u.luckas at road.de
Mon Nov 12 10:02:51 UTC 2007
And here comes the patch ...
Signed-off-by: Uli Luckas <u.luckas at road.de>
---
arch/arm/kernel/Makefile | 2 +-
arch/arm/kernel/atags.c | 113
++++++++++++++++++++++++++++++++++++++++++++++
arch/arm/kernel/atags.h | 2 +
arch/arm/kernel/setup.c | 3 +
4 files changed, 119 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/kernel/atags.c
create mode 100644 arch/arm/kernel/atags.h
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index bb28087..188e1d1 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -8,7 +8,7 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
obj-y := compat.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
- time.o traps.o
+ time.o traps.o atags.o
obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
new file mode 100644
index 0000000..f0922a7
--- /dev/null
+++ b/arch/arm/kernel/atags.c
@@ -0,0 +1,113 @@
+#include <asm/setup.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/page.h>
+
+struct buffer {
+ size_t size;
+ char *data;
+};
+
+static char atags_addr[12];
+
+static struct buffer addr_buffer =
+{
+ .size = sizeof(atags_addr) - 1,
+ .data = atags_addr,
+};
+static struct buffer tags_buffer;
+
+
+static int
+read_buffer(char* page, char** start, off_t off, int count,
+ int* eof, void* data)
+{
+ struct buffer *buffer = (struct buffer *)data;
+
+ if (off >= buffer->size) {
+ *eof = 1;
+ return 0;
+ }
+
+ count = min((int) (buffer->size - off), count);
+
+ memcpy(page, &buffer->data[off], count);
+
+ return count;
+}
+
+
+static int
+create_proc_entries(void)
+{
+ struct proc_dir_entry* atags_dir;
+ struct proc_dir_entry* addr_entry;
+ struct proc_dir_entry* tags_entry;
+
+ atags_dir = proc_mkdir("atags", NULL);
+ if(!atags_dir)
+ return -ENOMEM;
+
+ addr_entry = create_proc_read_entry("addr", 0400, atags_dir,
read_buffer, &addr_buffer);
+ if(!addr_entry) {
+ remove_proc_entry("atags", NULL);
+ return -ENOMEM;
+ }
+
+ tags_entry = create_proc_read_entry("tags", 0400, atags_dir,
read_buffer, &tags_buffer);
+ if(!tags_entry) {
+ remove_proc_entry("addr", atags_dir);
+ remove_proc_entry("atags", NULL);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+
+#define BOOT_PARAMS_SIZE 1536
+static unsigned long __initdata atags_phys;
+static char __initdata atags_copy_buf[BOOT_PARAMS_SIZE];
+static char __initdata *atags_copy;
+
+
+void __init save_atags(const unsigned long phys, const struct tag *tags) {
+ atags_phys = phys;
+ atags_copy = atags_copy_buf;
+ memcpy(atags_copy, tags, BOOT_PARAMS_SIZE);
+}
+
+
+static int
+__init init_atags_procfs(void)
+{
+ struct tag *tag;
+ int error;
+
+ if (!atags_copy) {
+ printk(KERN_WARNING "Exporting ATAGs: No saved tags
found\n");
+ return -EIO;
+ }
+
+ snprintf(atags_addr, sizeof(atags_addr), "0x%08lx\n", atags_phys);
+ for (tag = (struct tag *) atags_copy; tag->hdr.size; tag =
tag_next(tag))
+ ;
+
+ tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr);
+ tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL);
+ if (tags_buffer.data == NULL)
+ return -ENOMEM;
+ memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
+
+ error = create_proc_entries();
+ if (error) {
+ printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
+ kfree(tags_buffer.data);
+ tags_buffer.size = 0;
+ tags_buffer.data = NULL;
+ }
+
+ return error;
+}
+
+arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
new file mode 100644
index 0000000..792c4a8
--- /dev/null
+++ b/arch/arm/kernel/atags.h
@@ -0,0 +1,2 @@
+extern void
+save_atags( unsigned long phys, struct tag *tags);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0453dcc..168b975 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -37,6 +37,7 @@
#include <asm/mach/time.h>
#include "compat.h"
+#include "atags.h"
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
@@ -798,6 +799,8 @@ void __init setup_arch(char **cmdline_p)
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
+ if (mdesc->boot_params)
+ save_atags(mdesc->boot_params, tags);
parse_tags(tags);
}
--
1.5.3.4
More information about the Openembedded-devel
mailing list