Re: MM with fragmented memory

Kenneth Albanowski (kjahds@kjahds.com)
Thu, 22 Oct 1998 04:59:14 -0400 (EDT)


On Thu, 22 Oct 1998, Werner Almesberger wrote:

> [ Posted to linux-kernel and linux-7110 ]
>
> I'd like to get some opinions on what could be a reasonable memory mapping
> for the Psion S5. The problem with this device is that its physical RAM is
> scattered over a 30 bit address space in little fragments of 512kB,
> aligned to multiples of 1MB. Since it's impossible to fit any useful
> kernel into 512kB, some creative memory layout is necessary.

I'm working with uClinux, which fits quite well in less then 512kB of ROM,
and can certainly run in 512kB of RAM (although more is always better).
Note that I don't copy the kernel from ROM to RAM. Indeed, I go out of my
way to leave things in ROM if I can.

> I can see two viable approaches:
>
> (1) play linker tricks and insert holes in the kernel such that it skips
> over the gaps in memory. Then map all the memory 1:1 and let
> start_mem and end_mem each have one of the 512kB fragments for
> linear allocation.

I find this very interesting, from an eclectic viewpoint. If you want to
run the kernel from RAM, and it's over 512K in length, then obviously,
you'll need to teach the linker, _and probably the assembler_ how to
properly place code across the gaps, and still let the code run. (And all
of this applies equally to user applications that try to load over gaps.
If you want relocatable code, I'd simply refuse to touch that problem.)

I have a nagging feeling that somebody else had to implement this sort of
thing, but I can't think who.

> (2) use the MMU to create virtually continuous memory and let the kernel
> manage that in the usual way.

Simplest, obviously. If you've got an MMU, take advantage of it.

> The problems I see with (1) are:
> - at least part of the memory layout needs to be known when linking the
> kernel

Very much so.

> - allocations from start_mem and end_mem are each limited to a total of
> 512kB

I'm not sure I follow. All allocations of memory with contiguous physical
addresses would be limited to 512K, yes. That's about the only limit I can
see. The page system would be a little inefficient, but it can easily cope
with this sort of missing memory.

> - need to re-arrange VMALLOC_END, because on ARM-Linux it's 256 MB after
> PAGE_OFFSET, but VMALLOC_START will already have to be about 278 MB
> after that, due to the "exploded" address space. (But that change may
> be harmless.)
> The problems I see with (2) are:
> - virt_to_phys and phys_to_virt now need to perform lookups (in (1)
> they're no-ops). With a few tricks, I can get each of them done in
> about 10 clock cycles, clobbering two registers (out of 16), and
> accessing memory once

How often are virt_to_phys and phys_to_virt invoked? Offhand, I can't see
why these (or virt vs. bus) should be invoked very often. (I could easily
be wrong.)

> - a little voice in the back of my head saying that something in the
> kernel will certainly trip over a virtual:physical mapping that isn't
> just an offset

Hmm... Offhand, I have to agree. There's a problem here of how large the
"assumed address range" of a virt_to_phys ptr is. In your case, it could
range from [0K,+512K] to [-512K,0K], depending on the original pointer.

However, once again I'm not sure I can see any reason why this should
hurt: there is no reason for the kernel to be using physical or bus
addresses for block memory accesses, unless the ARM is considerably
different then the other processors I'm familiar with. Those address
spaces should only be useful from outside the processor, or within the
processor's MMU, and no where else.

If there was a memcpy_to_phys/bus, then you'd have to hack it up to
understand this sort of thing. But there isn't. And normal memcpy isn't
supposed to work with phys or bus address spaces, in any case.

If it's a matter of the kernel running in a different memory mapping mode
then user code, well, you do have memcpy_to/from_fs, and get/put_user to
hide any translation.

Now will the Linux MMU code die on this sort of system? As long as pages
never cross these 512K boundries, I can't think why it would break.

> While I'm attracted by the simplicity of (1), I'm a little worried about
> the limitation for linear allocations. Also, initrd needs a little work
> to function in such a scenario.

See if you can ditch initrd: if you can boot off a ROM disk, and then
mount a RAM disk in /var, you save all the memory of copying the initrd
image in to RAM. (#1 rule of small systems: if it's already in memory
somewhere, don't bother copying it somewhere else.)

> The disadvantage of (2) is clearly its complexity. Also, I don't like
> what that little voice is saying ...
>
> Any suggestions ?

As they say, "Hope This Helped".

> Thanks,
> - Werner

Cheers,
Ken

-- 
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/