577,9 → 577,161 |
<section> |
<title>Address spaces</title> |
|
<para>last bits about address spaces</para> |
<para>In HelenOS, address spaces are objects that encapsulate the |
following items:</para> |
|
<itemizedlist> |
<listitem> |
<para>address space identifier,</para> |
</listitem> |
|
<listitem> |
<para>page table PTL0 pointer and</para> |
</listitem> |
|
<listitem> |
<para>a set of mutually disjunctive address space areas.</para> |
</listitem> |
</itemizedlist> |
|
<para>Address space identifiers will be discussed later in this section. |
The address space contains a pointer to PTL0, provided that the |
architecture uses per address space page tables such as the hierarchical |
4-level page tables. The most interesting component is the B+tree of |
address space areas belonging to the address space.</para> |
|
<section> |
<title>Address space areas</title> |
|
<para>Because an address space can be composed of heterogenous mappings |
such as userspace code, data, read-only data and kernel memory, it is |
further broken down into smaller homogenous units called address space |
areas. An address space area represents a continuous piece of userspace |
virtual memory associated with common flags. Kernel memory mappings do |
not take part in address space areas because they are hardwired either |
into TLBs or page tables and are thus shared by all address spaces. The |
flags are a combination of:</para> |
|
<itemizedlist> |
<listitem> |
<para><constant>AS_AREA_READ</constant>,</para> |
</listitem> |
|
<listitem> |
<para><constant>AS_AREA_WRITE</constant>,</para> |
</listitem> |
|
<listitem> |
<para><constant>AS_AREA_EXEC</constant> and</para> |
</listitem> |
|
<listitem> |
<para><constant>AS_AREA_CACHEABLE</constant>.</para> |
</listitem> |
</itemizedlist> |
|
<para>The <constant>AS_AREA_READ</constant> flag is implicit and cannot |
be removed. The <constant>AS_AREA_WRITE</constant> flag denotes a |
writable address space area and the <constant>AS_AREA_EXEC</constant> is |
used for areas containing code. The combination of |
<constant>AS_AREA_WRITE</constant> and <constant>AS_AREA_EXEC</constant> |
is not allowed. Some architectures don't differentiate between |
executable and non-executable mappings. In that case, the |
<constant>AS_AREA_EXEC</constant> has no effect on mappings created for |
the address space area in the page tables. If the flags don't have |
<constant>AS_AREA_CACHEABLE</constant> set, the page tables content of |
the area is created with caching disabled. This is useful for address |
space areas containing memory of some memory mapped device.</para> |
|
<para>Address space areas can be backed by a backend that provides |
virtual functions for servicing page faults that occur within the |
address space area, releasing memory allocated by the area and sharing |
the area. Currently, there are three backends supported by HelenOS: |
anonymous memory backend, ELF image backend and physical memory |
backend.</para> |
|
<formalpara> |
<title>Anonymous memory backend</title> |
|
<para>Anonymous memory is memory that has no predefined contents such |
as userspace stack or heap. Anonymous address space areas are backed |
by memory allocated from the frame allocator. Areas backed by this |
backend can be resized as long as they are not shared.</para> |
</formalpara> |
|
<formalpara> |
<title>ELF image backend</title> |
|
<para>Areas backed by the ELF backend are composed of memory that can |
be either initialized, partially initialized or completely anonymous. |
Initialized portions of ELF backend address space areas are those that |
are entirely physically present in the executable image (e.g. code and |
initialized data). Anonymous portions are those pages of the |
<emphasis>bss</emphasis> section that exist entirely outside the |
executable image. Lastly, pages that don't fit into the previous two |
categories are partially initialized as they are both part of the |
image and the <emphasis>bss</emphasis> section. The initialized |
portion does not need any memory from the allocator unless it is |
writable. In that case, pages are duplicated on demand during page |
fault and memory for the copy is allocated from the frame allocator. |
The remaining two parts of the ELF always require memory from the |
frame allocator. Non-shared address space areas backed by the ELF |
image backend can be resized.</para> |
</formalpara> |
|
<formalpara> |
<title>Physical memory backend</title> |
|
<para>Physical memory backend is used by the device drivers to access |
physical memory. No additional memory needs to be allocated on a page |
fault in this area and when sharing this area. Areas backed by this |
backend cannot be resized.</para> |
</formalpara> |
|
<section> |
<title>Memory sharing</title> |
|
<para>Address space areas can be shared provided that their backend |
supports sharing<footnote> |
<para>Which is the case for all currently supported |
backends.</para> |
</footnote>. When the kernel calls <code>as_area_share()</code>, a |
check is made to see whether the area is already being shared. If the |
area is already shared, it contains a pointer to the share info |
structure. The pointer is then simply copied into the new address |
space area and a reference count in the share info structure is |
incremented. Otherwise a new address space share info structure needs |
to be created. The backend is then called to duplicate the mapping of |
pages for which a frame is allocated. The duplicated mapping is stored |
in the share info structure B+tree called <varname>pagemap</varname>. |
Note that the reference count of the frames put into the |
<varname>pagemap</varname> must be incremented to prevent .</para> |
</section> |
|
<section> |
<title>Page faults</title> |
|
<para>When a page fault is encountered in the address space area, the |
address space page fault handler, <code>as_page_fault()</code>, |
invokes the corresponding backend page fault handler to resolve the |
situation. The backend might either confirm the page fault or perform |
a remedy. In the non-shared case, depending on the backend, the page |
fault can be remedied usually by allocating some memory on demand or |
by looking up the frame for the faulting translation in the ELF |
image.</para> |
|
<para>Shared address space areas need to consider the |
<varname>pagemap</varname> B+tree. First they need to make sure |
whether to mapping is not present in the <varname>pagemap</varname>. |
If it is there, then the frame reference count is increased and the |
page fault is resolved. Otherwise the handler proceeds similarily to |
the non-shared case. If it allocates a physical memory frame, it must |
increment its reference count and add it to the |
<varname>pagemap</varname>.</para> |
</section> |
</section> |
|
<section> |
<indexterm> |
<primary>address space</primary> |
|