[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [microblaze-uclinux] [PATCH] microblaze: fix uClinux romfs corruption
Michal,
I'm not sure I understand the alternative. I've spent most of the last
week tracking down why my CRAMFS wouldn't mount/boot and traced it back
to this set of code. If there are kernel command line or configuration
parameters I can use to fix this problem I would appreciate a pointer in
the right direction.
* Re: reserve_bootmem(): The microblaze code appears to be off-by-one, at
least relative to the same code in powerpc. One or the other is incorrect.
* Re: machine_early_init(): the -rc6 ordering of the code clearly blanks
out a ROMFS that abuts _ebss. I don't see how reordering the code has an
effect on ramfs.
* Re: paging_init(): the -rc6 code clearly puts the bootmem map at __end
(== _ebss) which does not consider klimit adjustments made in
machine_early_init() - again, resulting in ROMFS corruption. I suppose a
smaller patch would be to change '_end' to 'klimit' rather than switching
to lmb_alloc(). The code in the patch was adapted from that in powerpc.
Steve
-----Original Message-----
From: Michal Simek <monstr@xxxxxxxxx>
To: microblaze-uclinux@xxxxxxxxxxxxxx
Cc: steve@xxxxxxxxxxxxxxx
Date: Mon, 18 May 2009 20:54:56 +0200
Subject: Re: [microblaze-uclinux] [PATCH] microblaze: fix uClinux romfs
corruption
>
>
> steve@xxxxxxxxxxxxxxx wrote:
> > Fix Microblaze startup handling of uClinux romfs so that it is not
> > overwritten or corrupted.
> >
> > Signed-off-by: Steven J. Magnani <steve@xxxxxxxxxxxxxxx>
> > ---
> > diff -uprN a/arch/microblaze/kernel/setup.c
> b/arch/microblaze/kernel/setup.c
> > --- a/arch/microblaze/kernel/setup.c 2009-05-18
12:24:21.000000000
> -0500
> > +++ b/arch/microblaze/kernel/setup.c 2009-05-18
12:44:05.000000000
> -0500
> > @@ -23,6 +23,7 @@
> > #include <linux/bug.h>
> > #include <linux/param.h>
> > #include <linux/cache.h>
> > +#include <linux/lmb.h>
> > #include <asm/cacheflush.h>
> > #include <asm/entry.h>
> > #include <asm/cpuinfo.h>
> > @@ -101,6 +102,23 @@ void __init machine_early_init(const cha
> > unsigned int fdt)
> > {
> > unsigned long *src, *dst = (unsigned long *)0x0;
> > +#ifdef CONFIG_MTD_UCLINUX
> > + int romfs_size;
> > + unsigned int romfs_base;
> > + char *old_klimit = klimit;
> > +
> > + /* Move ROMFS out of BSS before clearing it */
> > + {
> > + romfs_base = (ram ? ram : (unsigned int)&__init_end);
> > + /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is
at the
> > + * end of kernel, which is ROMFS_LOCATION defined above.
*/
> > + romfs_size = PAGE_ALIGN(get_romfs_len((unsigned
*)romfs_base));
> > + if (romfs_size > 0) {
> > + memmove(&_ebss, (int *)romfs_base, romfs_size);
> > + klimit += PAGE_ALIGN(romfs_size);
> > + }
> > + }
> > +#endif
> >
> > /* clearing bss section */
> > memset(__bss_start, 0, __bss_stop-__bss_start);
> > @@ -126,27 +144,15 @@ void __init machine_early_init(const cha
> > printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt);
> >
> > #ifdef CONFIG_MTD_UCLINUX
> > - {
> > - int size;
> > - unsigned int romfs_base;
> > - romfs_base = (ram ? ram : (unsigned int)&__init_end);
> > - /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is
at the
> > - * end of kernel, which is ROMFS_LOCATION defined above.
*/
> > - size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base));
> > - early_printk("Found romfs @ 0x%08x (0x%08x)\n",
> > - romfs_base, size);
> > - early_printk("#### klimit %p ####\n", klimit);
> > - BUG_ON(size < 0); /* What else can we do? */
> > -
> > - /* Use memmove to handle likely case of memory overlap */
> > - early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x
\n",
> > - size, romfs_base, (unsigned)&_ebss);
> > - memmove(&_ebss, (int *)romfs_base, size);
> > -
> > - /* update klimit */
> > - klimit += PAGE_ALIGN(size);
> > - early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
> > - }
> > + early_printk("Found romfs @ 0x%08x (0x%08x)\n",
> > + romfs_base, romfs_size);
> > + early_printk("#### klimit %p ####\n", old_klimit);
> > + BUG_ON(romfs_size < 0); /* What else can we do? */
>
> this is not correct - because noMMU will support/supports ramfs too.
> you can enable both MTD_UCLINUX and RAMFS. ROMFS could be outside of
> kernel
> and you can direct it through command line.
>
> Michal
>
> > +
> > + early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
> > + romfs_size, romfs_base, (unsigned)&_ebss);
> > +
> > + early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
> > #endif
> >
> > for (src = __ivt_start; src < __ivt_end; src++, dst++)
> > diff -uprN a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
> > --- a/arch/microblaze/mm/init.c 2009-05-18 12:23:32.000000000
-0500
> > +++ b/arch/microblaze/mm/init.c 2009-05-18 12:25:42.000000000
-0500
> > @@ -41,7 +41,6 @@ unsigned int memory_size;
> > */
> > static void __init paging_init(void)
> > {
> > - int i;
> > unsigned long zones_size[MAX_NR_ZONES];
> >
> > /* Clean every zones */
> > @@ -61,6 +60,8 @@ void __init setup_memory(void)
> > int i;
> > unsigned long map_size;
> > u32 kernel_align_start, kernel_align_size;
> > + unsigned long bootmap_pages;
> > + u64 bootmap_start;
> >
> > /* Find main memory where is the kernel */
> > for (i = 0; i < lmb.memory.cnt; i++) {
> > @@ -115,15 +116,13 @@ void __init setup_memory(void)
> >
> > /*
> > * Find an area to use for the bootmem bitmap.
> > - * We look for the first area which is at least
> > - * 128kB in length (128kB is enough for a bitmap
> > - * for 4GB of memory, using 4kB pages), plus 1 page
> > - * (in case the address isn't page-aligned).
> > */
> > - map_size = init_bootmem_node(NODE_DATA(0),
> PFN_UP(TOPHYS((u32)_end)),
> > - min_low_pfn, max_low_pfn);
> > + bootmap_pages = bootmem_bootmap_pages(lmb_end_of_DRAM() >>
> PAGE_SHIFT);
> >
> > - lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size);
> > + bootmap_start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
> > +
> > + map_size = init_bootmem_node(NODE_DATA(0), bootmap_start >>
> PAGE_SHIFT,
> > + min_low_pfn, max_low_pfn);
> >
> > /* free bootmem is whole main memory */
> > free_bootmem(memory_start, memory_size);
> > @@ -134,7 +133,7 @@ void __init setup_memory(void)
> > (u32) lmb.reserved.region[i].base,
> > (u32) lmb_size_bytes(&lmb.reserved, i));
> > reserve_bootmem(lmb.reserved.region[i].base,
> > - lmb_size_bytes(&lmb.reserved, i) - 1,
BOOTMEM_DEFAULT);
> > + lmb_size_bytes(&lmb.reserved, i),
BOOTMEM_DEFAULT);
> > }
> > paging_init();
> > }
> >
> > ___________________________
> > microblaze-uclinux mailing list
> > microblaze-uclinux@xxxxxxxxxxxxxx
> > Project Home Page :
> http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
> > Mailing List Archive :
> http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/
> >
> >
>
> --
> Michal Simek, Ing. (M.Eng)
> w: www.monstr.eu p: +42-0-721842854
___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/