Port-hpcarm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

More hpcboot memory/ELF loading errors?



Folks:
        I've been having a lot of trouble getting hpcboot to correctly
        load/boot much of anything on my iPAQ, and the symptoms look very
        much like the bug Uwe fixed about 2 years ago... looks like I'm
        running out of memory in the currently allocated region(s) and
        some page is either leaked into or overwritten because it's been
        handed out more than once.

        Unfortunately in my case it appears to generally be the bootinfo
        page, which means my 2nd-stage loader jumps to some junk address
        rather than the start of the kernel.

        It *does* seem related to size of the binary being loaded, but
        not in a bigger-is-worse way... it's the rounding of the memory
        use to the 64-k regions that seems to bite me.

        As an example, a slightly bigger than 16k test executable I built
        which just outputs some stuff to the serial port and spins still
        hit the rounding condition (it allocated 16 4k-pages, not sure why
        it needed that many) a vast majority of the time.  Occasionally
        the memory pages returned by the allocator to hpcboot would be
        different and it would work, but most of the time it would fail
        because the start address (and everything else) in the bootinfo
        page would be trashed by the time it got into the assembly code.
        The same happened with a couple of test kernels I built and/or
        sucked off the web... the majority of the time I'd die due to
        the bootinfo page getting smashed.

        The following is my hack^Wworkaround (for illustration purposes
        mostly -- it's extracted from a bigger set of changes, so it may
        not apply cleanly or at all):

        I'm going to dig a little bit more, but thought I'd send a query
        out in case anybody else has fallen into this hole, and to troll
        for ideas before I go dive in after the issue again.

Thanks,
--rafal

  - - - 8< - - Cut here - - 8< - -     - - - 8< - - Cut here - - 8< - - 
Index: hpcboot/arch.cpp
===================================================================
RCS file: /cvsroot/src/sys/arch/hpc/stand/hpcboot/arch.cpp,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 arch.cpp
--- hpcboot/arch.cpp    5 Mar 2006 04:05:39 -0000       1.14
+++ hpcboot/arch.cpp    21 Feb 2008 18:10:43 -0000
@@ -69,8 +69,8 @@ Architecture::allocateMemory(size_t sz)
 {
        //binary image.
        sz = _mem->estimateTaggedPageSize(sz);
-       //pvec + BootArgs + 2 nd bootloader + bootloader stack.
-       sz += _mem->getPageSize() * 4;
+       //pvec + BootArgs + guard page + 2 nd bootloader + guard page + 
bootloader stack.
+       sz += _mem->getPageSize() * 6;
        sz = _mem->roundRegion(sz);
        return _mem->reservePage(sz);
 }
Index: hpcboot/arm/arm_arch.cpp
===================================================================
RCS file: /cvsroot/src/sys/arch/hpc/stand/hpcboot/arm/arm_arch.cpp,v
retrieving revision 1.6
diff -u -p -u -p -r1.6 arm_arch.cpp
--- hpcboot/arm/arm_arch.cpp    19 Feb 2006 13:04:42 -0000      1.6
+++ hpcboot/arm/arm_arch.cpp    21 Feb 2008 18:26:18 -0000
@@ -94,8 +94,14 @@ BOOL
 ARMArchitecture::setupLoader()
 {
        vaddr_t v;
+       vaddr_t p;
        vsize_t sz = BOOT_FUNC_END - BOOT_FUNC_START;
 
+       // get a guard page...
+       _mem->getPage(v , p);
+       DPRINTF((TEXT("bootloader guard vaddr=0x%08x paddr=0x%08x\n"),
+           (unsigned)v,(unsigned)p));
+
        // check 2nd bootloader size.
        if (sz > _mem->getPageSize()) {
                DPRINTF((TEXT("2nd bootloader size(%dbyte) is larger than page 
size(%d).\n"),
@@ -126,9 +132,16 @@ ARMArchitecture::jump(paddr_t info, padd
        vaddr_t v;
        paddr_t p;
 
-       // stack for bootloader
+       // guard page before bootloader stack
+       _mem->getPage(v, p);
+       memset(reinterpret_cast <LPVOID>(v), 0x69, _mem->getPageSize());
+       DPRINTF((TEXT("guard page for bootloader stack = %08x\n"), p));
+
+       // stack for bootloader 
        _mem->getPage(v, p);
+       memset(reinterpret_cast <LPVOID>(v), 0x42, _mem->getPageSize());
        sp = ptokv(p) + _mem->getPageSize();
+       DPRINTF((TEXT("sp for bootloader = %08x\n"), sp));
 
        // writeback whole D-cache
        WritebackDCache();
        from a bigger set of changes so it 
        a much bigger set of changes and I can't
  - - - 8< - - Cut here - - 8< - -     - - - 8< - - Cut here - - 8< - - 

-- 
  Time is an illusion; lunchtime, doubly so.     |/\/\|           Rafal Boni
                   -- Ford Prefect               |\/\/|      
rafal%pobox.com@localhost


Home | Main Index | Thread Index | Old Index