On Thu, Jun 14, 2007 at 09:47:06PM -0400, Kevin O'Connor wrote:
> On Thu, Jun 14, 2007 at 09:17:13PM -0400, Kevin O'Connor wrote:
> > > Another issue I hit during experiments is that initrd buffer wanted
> > > to overwrite itself. I fixed that with memmove-like solution, moving
> > > blocks from the end instead of beginning.
> >
> > Be careful - if you copy the pages in reverse order, you need to make
> > sure the pages don't overwrite the preloader.
>
> On further thought, I don't think this will work at all.
Paul,
Could try the following patch on your 27MB initrd? I think this
overwriting prevention algorithm should work in the general case.
When testing on devices that have fbduringboot support, you may want
to run "set kernelcrc 1" - that should find any cases where the
relocation stuff messes up.
-Kevin
Index: src/memory.cpp
===================================================================
RCS file: /cvs/haret/src/memory.cpp,v
retrieving revision 1.32
diff -u -r1.32 memory.cpp
--- src/memory.cpp 12 Jun 2007 01:14:50 -0000 1.32
+++ src/memory.cpp 16 Jun 2007 01:57:17 -0000
@@ -462,12 +462,6 @@
* Page allocation
****************************************************************/
-static int physPageComp(const void *e1, const void *e2) {
- pageAddrs *i1 = (pageAddrs*)e1, *i2 = (pageAddrs*)e2;
- return (i1->physLoc < i2->physLoc ? -1
- : (i1->physLoc > i2->physLoc ? 1 : 0));
-}
-
// Free pages allocated with allocPages()
void
freePages(void *data, int pageCount)
@@ -508,9 +502,6 @@
pd->physLoc = pfns[i]; // XXX should: x << UserKInfo[KINX_PFN_SHIFT]
}
- // Sort the pages by physical location.
- qsort(pages, pageCount, sizeof(pages[0]), physPageComp);
-
return data;
}
Index: src/linboot.cpp
===================================================================
RCS file: /cvs/haret/src/linboot.cpp,v
retrieving revision 1.53
diff -u -r1.53 linboot.cpp
--- src/linboot.cpp 14 Jun 2007 23:13:01 -0000 1.53
+++ src/linboot.cpp 16 Jun 2007 01:57:17 -0000
@@ -420,6 +420,34 @@
struct pageAddrs *pg_data = &pages[totalCount-2];
struct pageAddrs *pg_preload = &pages[totalCount-1];
+ // Prevent pages from being overwritten during relocation
+ for (int i=0; i<totalCount; i++) {
+ struct pageAddrs *pg = &pages[i], *ovpg;
+ uint32 relPhys = pg->physLoc - memPhysAddr;
+ // See if this page will be overwritten in preloader.
+ if (relPhys == 0)
+ ovpg = pg_tag;
+ else if (relPhys >= PHYSOFFSET_KERNEL
+ && relPhys < PHYSOFFSET_KERNEL + kernelSize)
+ ovpg = &pgs_kernel[(relPhys - PHYSOFFSET_KERNEL) / PAGE_SIZE];
+ else if (initrdSize
+ && (relPhys >= PHYSOFFSET_INITRD
+ && relPhys < PHYSOFFSET_INITRD + initrdSize))
+ ovpg = &pgs_initrd[(relPhys - PHYSOFFSET_INITRD) / PAGE_SIZE];
+ else
+ // This page wont be overwritten.
+ continue;
+ if (pg == ovpg)
+ // This page will be overwritten by itself - no problem
+ continue;
+ // This page will be overwritten - swap it with the page that
+ // it will be overwritten by and retry.
+ struct pageAddrs tmp = *pg;
+ *pg = *ovpg;
+ *ovpg = tmp;
+ i--;
+ }
+
Output("Allocated %d pages (tags=%p/%08x kernel=%p/%08x initrd=%p/%08x"
" index=%p/%08x)"
, totalCount
@@ -428,25 +456,6 @@
, pgs_initrd->virtLoc, pgs_initrd->physLoc
, pgs_index->virtLoc, pgs_index->physLoc);
- if (pg_tag->physLoc < memPhysAddr + PHYSOFFSET_TAGS) {
- Output(C_ERROR "Allocated memory for tags will overwrite itself");
- cleanupBootMem(bm);
- return NULL;
- }
-
- if (pgs_kernel->physLoc < memPhysAddr + PHYSOFFSET_KERNEL) {
- Output(C_ERROR "Allocated memory for kernel will overwrite itself");
- cleanupBootMem(bm);
- return NULL;
- }
-
- if ((initrdSize
- && pgs_initrd->physLoc < memPhysAddr + PHYSOFFSET_INITRD)) {
- Output(C_ERROR "Allocated memory for initrd will overwrite itself");
- cleanupBootMem(bm);
- return NULL;
- }
-
// Setup linux tags.
setup_linux_params(pg_tag->virtLoc, memPhysAddr + PHYSOFFSET_INITRD
, initrdSize);
_______________________________________________
Haret mailing list
[email protected]
https://handhelds.org/mailman/listinfo/haret