More hpcboot memory/ELF loading errors?

Rafal Boni <[email protected]> Thu, 21 Feb 2008 13:37:07 -0500
Newsgroups gmane.os.netbsd.ports.hpcarm
Message-ID <[email protected]>
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               |\/\/|      [email protected]