Rev 84 | Rev 97 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 84 | Rev 96 | ||
|---|---|---|---|
| Line 575... | Line 575... | ||
| 575 | </section> |
575 | </section> |
| 576 | 576 | ||
| 577 | <section> |
577 | <section> |
| 578 | <title>Address spaces</title> |
578 | <title>Address spaces</title> |
| 579 | 579 | ||
| - | 580 | <para>In HelenOS, address spaces are objects that encapsulate the |
|
| - | 581 | following items:</para> |
|
| - | 582 | ||
| - | 583 | <itemizedlist> |
|
| - | 584 | <listitem> |
|
| - | 585 | <para>address space identifier,</para> |
|
| - | 586 | </listitem> |
|
| - | 587 | ||
| - | 588 | <listitem> |
|
| - | 589 | <para>page table PTL0 pointer and</para> |
|
| - | 590 | </listitem> |
|
| - | 591 | ||
| - | 592 | <listitem> |
|
| - | 593 | <para>a set of mutually disjunctive address space areas.</para> |
|
| - | 594 | </listitem> |
|
| - | 595 | </itemizedlist> |
|
| - | 596 | ||
| - | 597 | <para>Address space identifiers will be discussed later in this section. |
|
| - | 598 | The address space contains a pointer to PTL0, provided that the |
|
| - | 599 | architecture uses per address space page tables such as the hierarchical |
|
| - | 600 | 4-level page tables. The most interesting component is the B+tree of |
|
| 580 | <para>last bits about address spaces</para> |
601 | address space areas belonging to the address space.</para> |
| - | 602 | ||
| - | 603 | <section> |
|
| - | 604 | <title>Address space areas</title> |
|
| - | 605 | ||
| - | 606 | <para>Because an address space can be composed of heterogenous mappings |
|
| - | 607 | such as userspace code, data, read-only data and kernel memory, it is |
|
| - | 608 | further broken down into smaller homogenous units called address space |
|
| - | 609 | areas. An address space area represents a continuous piece of userspace |
|
| - | 610 | virtual memory associated with common flags. Kernel memory mappings do |
|
| - | 611 | not take part in address space areas because they are hardwired either |
|
| - | 612 | into TLBs or page tables and are thus shared by all address spaces. The |
|
| - | 613 | flags are a combination of:</para> |
|
| - | 614 | ||
| - | 615 | <itemizedlist> |
|
| - | 616 | <listitem> |
|
| - | 617 | <para><constant>AS_AREA_READ</constant>,</para> |
|
| - | 618 | </listitem> |
|
| - | 619 | ||
| - | 620 | <listitem> |
|
| - | 621 | <para><constant>AS_AREA_WRITE</constant>,</para> |
|
| - | 622 | </listitem> |
|
| - | 623 | ||
| - | 624 | <listitem> |
|
| - | 625 | <para><constant>AS_AREA_EXEC</constant> and</para> |
|
| - | 626 | </listitem> |
|
| - | 627 | ||
| - | 628 | <listitem> |
|
| - | 629 | <para><constant>AS_AREA_CACHEABLE</constant>.</para> |
|
| - | 630 | </listitem> |
|
| - | 631 | </itemizedlist> |
|
| - | 632 | ||
| - | 633 | <para>The <constant>AS_AREA_READ</constant> flag is implicit and cannot |
|
| - | 634 | be removed. The <constant>AS_AREA_WRITE</constant> flag denotes a |
|
| - | 635 | writable address space area and the <constant>AS_AREA_EXEC</constant> is |
|
| - | 636 | used for areas containing code. The combination of |
|
| - | 637 | <constant>AS_AREA_WRITE</constant> and <constant>AS_AREA_EXEC</constant> |
|
| - | 638 | is not allowed. Some architectures don't differentiate between |
|
| - | 639 | executable and non-executable mappings. In that case, the |
|
| - | 640 | <constant>AS_AREA_EXEC</constant> has no effect on mappings created for |
|
| - | 641 | the address space area in the page tables. If the flags don't have |
|
| - | 642 | <constant>AS_AREA_CACHEABLE</constant> set, the page tables content of |
|
| - | 643 | the area is created with caching disabled. This is useful for address |
|
| - | 644 | space areas containing memory of some memory mapped device.</para> |
|
| - | 645 | ||
| - | 646 | <para>Address space areas can be backed by a backend that provides |
|
| - | 647 | virtual functions for servicing page faults that occur within the |
|
| - | 648 | address space area, releasing memory allocated by the area and sharing |
|
| - | 649 | the area. Currently, there are three backends supported by HelenOS: |
|
| - | 650 | anonymous memory backend, ELF image backend and physical memory |
|
| - | 651 | backend.</para> |
|
| - | 652 | ||
| - | 653 | <formalpara> |
|
| - | 654 | <title>Anonymous memory backend</title> |
|
| - | 655 | ||
| - | 656 | <para>Anonymous memory is memory that has no predefined contents such |
|
| - | 657 | as userspace stack or heap. Anonymous address space areas are backed |
|
| - | 658 | by memory allocated from the frame allocator. Areas backed by this |
|
| - | 659 | backend can be resized as long as they are not shared.</para> |
|
| - | 660 | </formalpara> |
|
| - | 661 | ||
| - | 662 | <formalpara> |
|
| - | 663 | <title>ELF image backend</title> |
|
| - | 664 | ||
| - | 665 | <para>Areas backed by the ELF backend are composed of memory that can |
|
| - | 666 | be either initialized, partially initialized or completely anonymous. |
|
| - | 667 | Initialized portions of ELF backend address space areas are those that |
|
| - | 668 | are entirely physically present in the executable image (e.g. code and |
|
| - | 669 | initialized data). Anonymous portions are those pages of the |
|
| - | 670 | <emphasis>bss</emphasis> section that exist entirely outside the |
|
| - | 671 | executable image. Lastly, pages that don't fit into the previous two |
|
| - | 672 | categories are partially initialized as they are both part of the |
|
| - | 673 | image and the <emphasis>bss</emphasis> section. The initialized |
|
| - | 674 | portion does not need any memory from the allocator unless it is |
|
| - | 675 | writable. In that case, pages are duplicated on demand during page |
|
| - | 676 | fault and memory for the copy is allocated from the frame allocator. |
|
| - | 677 | The remaining two parts of the ELF always require memory from the |
|
| - | 678 | frame allocator. Non-shared address space areas backed by the ELF |
|
| - | 679 | image backend can be resized.</para> |
|
| - | 680 | </formalpara> |
|
| - | 681 | ||
| - | 682 | <formalpara> |
|
| - | 683 | <title>Physical memory backend</title> |
|
| - | 684 | ||
| - | 685 | <para>Physical memory backend is used by the device drivers to access |
|
| - | 686 | physical memory. No additional memory needs to be allocated on a page |
|
| - | 687 | fault in this area and when sharing this area. Areas backed by this |
|
| - | 688 | backend cannot be resized.</para> |
|
| - | 689 | </formalpara> |
|
| - | 690 | ||
| - | 691 | <section> |
|
| - | 692 | <title>Memory sharing</title> |
|
| - | 693 | ||
| - | 694 | <para>Address space areas can be shared provided that their backend |
|
| - | 695 | supports sharing<footnote> |
|
| - | 696 | <para>Which is the case for all currently supported |
|
| - | 697 | backends.</para> |
|
| - | 698 | </footnote>. When the kernel calls <code>as_area_share()</code>, a |
|
| - | 699 | check is made to see whether the area is already being shared. If the |
|
| - | 700 | area is already shared, it contains a pointer to the share info |
|
| - | 701 | structure. The pointer is then simply copied into the new address |
|
| - | 702 | space area and a reference count in the share info structure is |
|
| - | 703 | incremented. Otherwise a new address space share info structure needs |
|
| - | 704 | to be created. The backend is then called to duplicate the mapping of |
|
| - | 705 | pages for which a frame is allocated. The duplicated mapping is stored |
|
| - | 706 | in the share info structure B+tree called <varname>pagemap</varname>. |
|
| - | 707 | Note that the reference count of the frames put into the |
|
| - | 708 | <varname>pagemap</varname> must be incremented to prevent .</para> |
|
| - | 709 | </section> |
|
| - | 710 | ||
| - | 711 | <section> |
|
| - | 712 | <title>Page faults</title> |
|
| - | 713 | ||
| - | 714 | <para>When a page fault is encountered in the address space area, the |
|
| - | 715 | address space page fault handler, <code>as_page_fault()</code>, |
|
| - | 716 | invokes the corresponding backend page fault handler to resolve the |
|
| - | 717 | situation. The backend might either confirm the page fault or perform |
|
| - | 718 | a remedy. In the non-shared case, depending on the backend, the page |
|
| - | 719 | fault can be remedied usually by allocating some memory on demand or |
|
| - | 720 | by looking up the frame for the faulting translation in the ELF |
|
| - | 721 | image.</para> |
|
| - | 722 | ||
| - | 723 | <para>Shared address space areas need to consider the |
|
| - | 724 | <varname>pagemap</varname> B+tree. First they need to make sure |
|
| - | 725 | whether to mapping is not present in the <varname>pagemap</varname>. |
|
| - | 726 | If it is there, then the frame reference count is increased and the |
|
| - | 727 | page fault is resolved. Otherwise the handler proceeds similarily to |
|
| - | 728 | the non-shared case. If it allocates a physical memory frame, it must |
|
| - | 729 | increment its reference count and add it to the |
|
| - | 730 | <varname>pagemap</varname>.</para> |
|
| - | 731 | </section> |
|
| - | 732 | </section> |
|
| 581 | 733 | ||
| 582 | <section> |
734 | <section> |
| 583 | <indexterm> |
735 | <indexterm> |
| 584 | <primary>address space</primary> |
736 | <primary>address space</primary> |
| 585 | 737 | ||