2006-10-31 07:22:09

by Jun Sun

[permalink] [raw]
Subject: reserve memory in low physical address - possible?


This question is specific to i386 architecture. While I am fairly
comfortable with Linux kernel, I am not familiar with i386 arch.

My objective is to reserve, or hide from kernel, some memory space in low
physical address range starting from 0. The memory amount is in the order
of 100MB to 200MB. The total memory is assumed to be around 512MB.

Is this possible?

I understand it is possible to reserve some memory at the end by
specifying "mem=xxxM" option in kernel command line. I looked into
"memmap=xxxM" option but it appears not helpful for what I want.

While searching on the web I also found things like DMA zone and loaders
etc that all seem to assume the existence low-addressed physical
memory. True?

I can certainly workaround the loader issue. I can also re-code the real-mode
part of kernel code to migrate to higher addresses. The DMA zone might be
a thorny one. Any clues? Are modern PCs still subject to
the 16MB DMA zone restriction?

Am I too far off from what I want to do?

Thanks.

Jun


2006-10-31 08:13:16

by Paul Mundt

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

On Mon, Oct 30, 2006 at 11:22:03PM -0800, Jun Sun wrote:
> I understand it is possible to reserve some memory at the end by
> specifying "mem=xxxM" option in kernel command line. I looked into
> "memmap=xxxM" option but it appears not helpful for what I want.
>
memmap takes multiple arguments, including the start address for the
memory map. You could also bump min_low_pfn manually if memmap= isn't
suitable for you, something like:

magic_space = PFN_UP(init_pg_tables_end);
min_low_pfn = magic_space + magic_size;

(assuming magic_size is rounded up already), should work fine. Though
memmap= already takes care of most of this for you, could you explain why
it's unsuitable?

2006-10-31 12:33:12

by Richard B. Johnson

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?


----- Original Message -----
From: "Jun Sun" <[email protected]>
To: <[email protected]>
Sent: Tuesday, October 31, 2006 2:22 AM
Subject: reserve memory in low physical address - possible?


>
> This question is specific to i386 architecture. While I am fairly
> comfortable with Linux kernel, I am not familiar with i386 arch.
>
> My objective is to reserve, or hide from kernel, some memory space in low
> physical address range starting from 0. The memory amount is in the order
> of 100MB to 200MB. The total memory is assumed to be around 512MB.
>
> Is this possible?
>
> I understand it is possible to reserve some memory at the end by
> specifying "mem=xxxM" option in kernel command line. I looked into
> "memmap=xxxM" option but it appears not helpful for what I want.
>

For special purpose (DMA to user-space, etc.), it has become commonplace to
reserve some high memory.
Then, in your driver, you can find the end of kernel memory as
(num_physpages * PAGE_SIZE).

You will not be able to reserve any address space starting at 0 anyway, but
your driver or even
user-space code can memory-map it.

> While searching on the web I also found things like DMA zone and loaders
> etc that all seem to assume the existence low-addressed physical
> memory. True?
>

Some early (ISA) boards couldn't access address-space beyoond 16 megabytes,
hense the "low" memory
for DMA.

> I can certainly workaround the loader issue. I can also re-code the
> real-mode
> part of kernel code to migrate to higher addresses. The DMA zone might be
> a thorny one. Any clues? Are modern PCs still subject to
> the 16MB DMA zone restriction?
>

Anything that plugs into a PCI bus will __not__ have a low address
restriction.

> Am I too far off from what I want to do?
>
> Thanks.
>
> Jun
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/


2006-10-31 12:46:00

by Mark Hounschell

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

Jun Sun wrote:
> This question is specific to i386 architecture. While I am fairly
> comfortable with Linux kernel, I am not familiar with i386 arch.
>
> My objective is to reserve, or hide from kernel, some memory space in low
> physical address range starting from 0. The memory amount is in the order
> of 100MB to 200MB. The total memory is assumed to be around 512MB.
>
> Is this possible?
>
> I understand it is possible to reserve some memory at the end by
> specifying "mem=xxxM" option in kernel command line. I looked into
> "memmap=xxxM" option but it appears not helpful for what I want.
>
> While searching on the web I also found things like DMA zone and loaders
> etc that all seem to assume the existence low-addressed physical
> memory. True?
>
> I can certainly workaround the loader issue. I can also re-code the real-mode
> part of kernel code to migrate to higher addresses. The DMA zone might be
> a thorny one. Any clues? Are modern PCs still subject to
> the 16MB DMA zone restriction?
>
> Am I too far off from what I want to do?
>
> Thanks.
>
> Jun

Maybe the bigphysarea patch is what you want?

Mark

2006-10-31 15:06:18

by Jun Sun

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

On Tue, Oct 31, 2006 at 05:12:39PM +0900, Paul Mundt wrote:
> On Mon, Oct 30, 2006 at 11:22:03PM -0800, Jun Sun wrote:
> > I understand it is possible to reserve some memory at the end by
> > specifying "mem=xxxM" option in kernel command line. I looked into
> > "memmap=xxxM" option but it appears not helpful for what I want.
> >
> memmap takes multiple arguments, including the start address for the
> memory map. You could also bump min_low_pfn manually if memmap= isn't
> suitable for you, something like:
>
> magic_space = PFN_UP(init_pg_tables_end);
> min_low_pfn = magic_space + magic_size;
>
> (assuming magic_size is rounded up already), should work fine. Though
> memmap= already takes care of most of this for you, could you explain why
> it's unsuitable?

That is fair question. I got that conclusion by a quick test with
"memmap=" and kernel did not boot. :)

Now think about it, it could be because the loader (or the real-mode
part of kernel) has not been modified to deal with the initial gap.
Can someone confirm that and give some hints on how to do this?

Thanks.

Jun

2006-10-31 15:14:24

by Jun Sun

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

On Tue, Oct 31, 2006 at 07:45:57AM -0500, Mark Hounschell wrote:
> Jun Sun wrote:
> > This question is specific to i386 architecture. While I am fairly
> > comfortable with Linux kernel, I am not familiar with i386 arch.
> >
> > My objective is to reserve, or hide from kernel, some memory space in low
> > physical address range starting from 0. The memory amount is in the order
> > of 100MB to 200MB. The total memory is assumed to be around 512MB.
> >
> > Is this possible?
> >
> > I understand it is possible to reserve some memory at the end by
> > specifying "mem=xxxM" option in kernel command line. I looked into
> > "memmap=xxxM" option but it appears not helpful for what I want.
> >
> > While searching on the web I also found things like DMA zone and loaders
> > etc that all seem to assume the existence low-addressed physical
> > memory. True?
> >
> > I can certainly workaround the loader issue. I can also re-code the real-mode
> > part of kernel code to migrate to higher addresses. The DMA zone might be
> > a thorny one. Any clues? Are modern PCs still subject to
> > the 16MB DMA zone restriction?
> >
> > Am I too far off from what I want to do?
> >
> > Thanks.
> >
> > Jun
>
> Maybe the bigphysarea patch is what you want?
>

I took a look. The patch will allocate (actually pre-allocate) a big chunk
at boot time, which is arguably more friendly to MM subsystem. However,
you cannot specify the location of the memory chunk which is what I want.

Thanks.

Jun

2006-10-31 15:40:27

by Jun Sun

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

On Tue, Oct 31, 2006 at 07:32:37AM -0500, Richard B. Johnson wrote:
>
> You will not be able to reserve any address space starting at 0 anyway, but
> your driver or even
> user-space code can memory-map it.
>

Any reasons or concerns as to why I can't reserve any address space
starting from 0?

To make my motivation clearer, here is the application scenario.

My system will load an initial OS (could be a strip down Linux or some
simple RTOS) into the low memory starting from address 0. The initial OS
will then load Linux into higher memory region, say @100M. Then control jumps
to Linux while the initial OS is still lurking in the RAM for future
use.

> Some early (ISA) boards couldn't access address-space beyoond 16 megabytes,
> hense the "low" memory
> for DMA.
>

So if I don't have ISA performing DMA, I should be OK in this regard?

Thanks.

Jun

2006-10-31 15:57:31

by Alan

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

Ar Maw, 2006-10-31 am 07:40 -0800, ysgrifennodd Jun Sun:
> On Tue, Oct 31, 2006 at 07:32:37AM -0500, Richard B. Johnson wrote:
> >
> > You will not be able to reserve any address space starting at 0 anyway, but
> > your driver or even
> > user-space code can memory-map it.
> >
>
> Any reasons or concerns as to why I can't reserve any address space
> starting from 0?

None at all, Richard is wrong on this point. You can happily reserve
memory starting at physical zero on an x86. In fact the x86 kernel
*already* does this because many BIOSes use the first page for BIOS data
and touch it when we use BIOS services or in SMM.

For a worked example of loading Linux under a small RTOS take a look at
RTLinux, which turns Linux into on task running on a tiny strict RT
kernel.

Alan


2006-11-02 18:41:12

by Jun Sun

[permalink] [raw]
Subject: Re: reserve memory in low physical address - possible?

On Tue, Oct 31, 2006 at 07:06:12AM -0800, Jun Sun wrote:
> On Tue, Oct 31, 2006 at 05:12:39PM +0900, Paul Mundt wrote:
> > On Mon, Oct 30, 2006 at 11:22:03PM -0800, Jun Sun wrote:
> > > I understand it is possible to reserve some memory at the end by
> > > specifying "mem=xxxM" option in kernel command line. I looked into
> > > "memmap=xxxM" option but it appears not helpful for what I want.
> > >
> > memmap takes multiple arguments, including the start address for the
> > memory map. You could also bump min_low_pfn manually if memmap= isn't
> > suitable for you, something like:
> >
> > magic_space = PFN_UP(init_pg_tables_end);
> > min_low_pfn = magic_space + magic_size;
> >
> > (assuming magic_size is rounded up already), should work fine. Though
> > memmap= already takes care of most of this for you, could you explain why
> > it's unsuitable?
>
> That is fair question. I got that conclusion by a quick test with
> "memmap=" and kernel did not boot. :)
>
> Now think about it, it could be because the loader (or the real-mode
> part of kernel) has not been modified to deal with the initial gap.
> Can someone confirm that and give some hints on how to do this?
>

I finally managed to boot a kernel only uses the second 256MB memory
on a 512MB system. In case someone wants to do the same in the future,
I post my solution here.

http://junsun.net/linux/patches/generic/hacks/061102-reserve-low-memory.patch
http://junsun.net/linux/patches/generic/hacks/061102-vmplayer-no-module-2.6.16.config

The objective is to reserve the first 256MB staring from 0 and hide it from
kernel in a 512MB system. In other words, kernel only uses the second
256MB memory.

Several notes related to this hack:

* In the config, I set CONFIG_PHYSICAL_START to 0x10000000 (256MB)
See the .config file in the same directory. My target is vmplayer.
(BTW, this config disables module and is quite useful for fast devel)

* The patch will change __PAGE_OFFSET from 0xC0000000 to 0xB0000000 so that
the virtual address of kernel would still start from 0xC0000000 region.
(This may be necessary? Pro's and Con's?)

* Since we lose out the first 16MB DMA zone, many drivers will complain.
The patch increase MAX_DMA_ADDRESS to 1GB, which effectively cover
all memory area. If you have floppy or other ISA devices doing DMA,
this change may break your system.

* Specify the memory map through kernel command line:
memmap=exactmap memmap=0x0fef0000@0x10000000
Note
. the memory region must include the kernel itself
. also, grub does not seem to understand memmap option (BUG!!). It
would still load initrd to the end of memory. So you better
specify the size of memory to cover (almost) end of the second
256MB. Otherwise, you will see complains about not finding
"LABEL=/" root device.
. Tricky enough, you cannot specify the whole 256MB as the size
because the first 0x1000 block in the last 1M+ is used for ACPI
data and NVS. (What are they for anyway?) When I tried to
include them in memmap spec, the system failed to start (BusLogic
driver errors)

Jun