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 |