[oe] [PATHC] ATAG export for the linux kernel

Hans Henry von Tresckow hvontres at gmail.com
Wed Dec 5 21:06:06 UTC 2007


On Nov 12, 2007 2:02 AM, Uli Luckas <u.luckas at road.de> wrote:

> 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.osys_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
>
>
Tested on 2.6.21 and 2.6.17 for poodle. Thank you very much. Any Chance you
could push this upstream?

-- 
Henry von Tresckow (hvontres)



More information about the Openembedded-devel mailing list