Hi Finn,
On 22/03/21 6:24 pm, Finn Thain wrote:
I guess once the RAM chunk list has been sorted, it was most convenient
to use that sorted list directly for the bootinfo records.
A constraint that says the first chunk must be the largest one is
undesirable because if the largest chunk has higher address than some
other large chunk, the latter would become inaccessible.
A similar problem arises when you have only two chunks of equal size.
Sorting by size doesn't help and the bootloader could theoretically end up
putting the kernel in bank B, leaving bank A unavailable.
Can't fault your reasoning there. The use case of multiple large chunks
present (and only the largest one used unless banks are rearranged)
might have been rare back in '98.
Why not sort chunks by physical address and omit any chunks prior to
the largest one, to satisfy both requirements? Then ask users to
re-arrange RAM SIMMs such that bank A is the largest.
Yes, that could be done. I don't think the kernel would mind any RAM
banks not passed in the bootinfo struct (to wit, IIRC amiboot has a
'memfile' option to allow exclusion of RAM chunks from bootinfo, to skip
RAM that's slow or unreliable).
Based on the commit that Geert cited, I'd be inclined to sort chunks by
physical address, find the lowest chunk having size >= 16 MB and put that
one and the higher ones into bootinfo. (Or failing that, find the one
having size >= 8 MB, or failing that, 4 MB.)
Do you know the size of the uncompressed kernel at that stage? That way,
you could skip all RAM banks smaller than that size (plus some margin
for the initial mappings, one 4k page for each 4 MB of chunk size plus
required number of pointer table pages) and use the first one (lowest
address one) that satisfies such a minimum size criterion.
In this way, you won't lose all of the smaller but still useful banks,
just in case a user arranged the banks in ascending size order.
(Skipping the lower address banks isn't strictly required BTW - the
kernel will warn and ignore them as it used to. No harm done.)
A full sort isn't really needed here but does offer some determinism. Are
there implications for mm data structures? E.g. memblock_add_node() is
called for each chunk, and if the chunks are in the "wrong" order, perhaps
that would affect mm algorithms (?)
There is no checks about order that I would have seen. But the reason
why memory with lower addresses than mapped by head.S can't be used
still isn't clear to me. Best leave the rest of the chunk list in
address order.
Does any of this help with the problem of RBV Macs? Video RAM must start
at address 0x0, and reordering RAM to have the largest chunk at that
address would occupy the RBV video range and render RBV unusable? Can
you even rearrange RAM in these machines?
I've argued elsewhere in this thread that the bank A issue in RBV Macs
doesn't matter that much.
If on-board video is enabled, bank A is slowed down. That suggests to me
that bank A is probably not that useful for Linux and is probably
relatively small anyway. As Brad said, bank A is always 1 MB on a IIsi. So
I don't mind if Linux ignores it in this case.
Probably good cause to only use it for video RAM through a separate
allocator and pool (if a user absolutely insists and someone writes a
patch that you would accept). We can't share it with the kernel anyway
at present (and with a fixed size of 1 MB, it would be useless for
modern times kernels).
Perhaps we need to look at head.S from before 1998 to figure out what
motivated Penguin's '020 special case and the option to disable it?
I know the head.S MMU code was completely rewritten around that time to
accommodate changes needed for the Mac port. What we used before on
Atari and Amiga bears little to no relation to what we have now. My
guess is that 030 (has transparent translation register) and 020 (does
not have tt1) used distinct code paths before the rewrite, but share
much of the code now.
I haven't found a kernel source that old on my system so I can't verify
my recollection of this though. Geert has a git tree somewhere that
contains all the ancient history, might be worth checking.
Maybe that rewrite happened around the "pre2.05" release...
https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/arch/m68k/kernel/head.S?h=2.0&id=37147b87dddfc389e97d99f078be5a0f1012ba74
Unfortunately, even in the oldest head.S at that link, it's not obvious to
me why 68020/68851 and 68030 would execute different code paths. It's easy
to believe that the Penguin hack for 68020/68851 was incomplete (should
have been extended to 68030).
I think I've found the difference: commit
75ce89a86b88c2dd77a0d2697c1ecaf9c53016ce (the earliest//I found) has
head.S set up a page descriptor entry at the pointer table level (i.e.
'early termination' descriptor). That maps 32 MB in one go, regardless
of size and alignment of that chunk, which would not have mattered for
Atari and Amiga (as far as I know, the RAM banks are far enough apart
for such mappings not to overlap) but might have caused trouble on Mac
if the RAM banks fall within 32 MB and the kernel runs from the second
bank (which then isn't 32 MB aligned).
Today's head.S only uses early termination only if both size and
alignment match.
As you said, there is no distinction made between 020 and 030 in that
code, so the same hack should have been applied to 030. Maybe the MacII
(were there other 020 Macs?) was the only one with RAM banks A and B
spaced closer than 32 MB?
But that's academic. If we change the bootloader to fix the issue that
Stan reported and if it remains backwards compatible with Linux v2.2.25
(or Debian 3) I'd be happy with that.
I'm quite certain that today's head.S needs no more 020 hacks and ought
to work on MacII if you can fit enough RAM in bank B to hold the kernel.
But finding a MacII to test this on is more than a little academic indeed.
Let's fix the meminfo chunk ordering and see whether that fixes Stan's
issues. I have no doubt that as long as the long-standing constraint
about the first chunk holding the kernel isn't violated, old kernels
will continue to boot OK.
Cheers,
Michael