How does the kernel access user arguments?

In other Linux implementations the kernel is mapped to the upper 1G of the virtual 
address.  This leaves 3G to the user processes.  This mapping allows the kernel to use 
addresses passed as arguments without any translation, and it allows the kernel to 
access user space directly.  All Unix systems I know of (and Windows) do something 
similar, although they usually divide the address space into two 2G regions.

-----Original Message-----
From: Ulrich Weigand [mailto:[EMAIL PROTECTED]
Sent: Friday, July 18, 2003 5:00 PM
To: [EMAIL PROTECTED]
Subject: Re: How Linux is actually loaded into memory?


Jim Sibley wrote:

>How is 31bit Linux actually loaded into memory in a 2 GB LPAR or EC? How
>are the addresses mapped?
>
>How would a 64bit Linux be loaded in a 3 GB LPAR or EC?
>
>I have a user that was told
>"With 31-bit, Zlinux offers 2GB of addressing space, we were told that "the
>system libraries for linux are loaded right in the middle of the address
>space, which left you with about 700MB of shared memory on either side of
>the address space for your application software".

[ This refers to the (default) layout of a process' virtual address space,
which has nothing to do with either Linux' use of real memory, or the
layout of the *kernel's* virtual address space (which is distinct from
all user address spaces, just as these are pairwise distinct). ]

A user process has 2 GB (31-bit) or 2 TB (64-bit) virtual address space
available for its use, and can -if required- arrange for this space to
be arbitrarly filled with whatever mappings it desires, up to the last
page.  However, if a process doesn't do anything special, some default
mappings will be arranged by the kernel and the toolchain.

Those usually look like this (on 31-bit):

  0  .. 4M   empty (NULL pointer trap area)
  4M .. xx   main application code + data
  xx .. 1G   free (usually for use as malloc () heap)
  1G .. yy   shared library code + data
  yy .. zz   free (usually for use as mmap () space)
  zz .. 2G   main stack (grows downwards)

and very similar on 64-bit, only with different absolute addresses:

  0  .. 2G   empty (NULL pointer trap area)
  2G .. xx   main application code + data
  xx .. 1T   free (usually for use as malloc () heap)
  1T .. yy   shared library code + data
  yy .. zz   free (usually for use as mmap () space)
  zz .. 2T   main stack (grows downwards)

Note that the two 'free' regions will be used interchangeably if full
(e.g. malloc will use the mmap region or vice versa).

The upper and lower limits are given by the architecture, and the
main application load address is hard-coded by the linker (the 4M
come from the default linker script).  The only question is where
the 1G / 1TB default shared library load address comes from -- this
is decided by the kernel.

And this latter fact has indeed been proven to be a problematic
point for certain applications (e.g. databases or Java) that
require to allocate one single large contiguous area of address
space from the operating system, to perform their own memory
allocation scheme within.  Thus, the largest available contiguous
address space region limits the maximum size of memory this type
of applications can use, and this can on 31-bit indeed lie in
the range of 700 MB.

However, in SLES-8 there is a kernel patch that provides the
option to override the default 1 GB address for shared libraries.
This can be done on a per-process basis using the
  /proc/<pid>/map_base
entry.  The value is inherited over fork () and exec (), so it
should be set up in the *parent* process of the one that needs
the large area.  The exact value to choose depends a bit on
the circumstances; some experimentation may be required.

This should allow use of contiguous regions of nearly up to
2 GB ...   (Of course, you might prefer to just use a 64-bit
kernel if your address space is this cramped ;-))

Bye,
Ulrich

--
  Dr. Ulrich Weigand
  [EMAIL PROTECTED]

Reply via email to