Hi, I modified the article introducing the Haiku vm system. Thanks to Axel and Travis, they have pointed out my mistakes. There still must be mistakes. If you find bugs, please let me know. BTW: Writing a technical document is not easy for me. Though I spent one day modifying, it is not satisfying yet. I will continue working on it... Time to sleep, bye. A General Introduction to Haiku Virtual Memory Management The Major Facilities of Haiku Virtual Memory System There are 5 key data structures in the system that handles the virtual memory management: l vm_address_space: structure that describes the virtual address space of a process. l vm_area: structure that represents a virtually contiguous range of address space that shares protection and inheritance attributes l vm_page: structure that represents one physical memory page. l vm_cache: structure that describes a source of data for a range of addresses l vm_store: structure that contains data necessary to support swapping All of the structures listed above are defined in trunk\headers\private\kernel\arch\vm_types.h. Virtual Address Space The vm_address_space structure encapsulates the virtual memory information of a particular process. It’s defined as: struct vm_address_space { struct vm_area *areas; struct vm_area *area_hint; sem_id sem; addr_t base; addr_t size; int32 change_count; vm_translation_map translation_map; team_id id; int32 ref_count; int32 fault_count; int32 state; addr_t scan_va; addr_t working_set_size; addr_t max_working_set; addr_t min_working_set; bigtime_t last_working_set_adjust; struct vm_address_space *hash_next; }; Two fields of vm_address_space should be noticed: one is areas: a pointer to its linked list of areas(see below); the other is translation_map , which contains the virtual to physical address translation information. Virtual Memory Areas An area is a chunk of virtual memory of any size. A process divides its linear virtual address space into a number of areas(regions). For example, a simple process may have several areas for its process binary, heap, stack and shared-libraries respectively. (To see how many areas a process contains, use the listarea command in the terminal). An area can be mapped from a file or it can use the “anonymous memory”. Areas for process binaries and shared-libraries are mapped from files and will be filled in with the appropriate content when first accessed. Uninitiated data (e.g. heap and stack) use anonymous memory. It is zero filled and its contents are abandoned when the last reference is dropped. The vm_area structure is defined as follows: struct vm_area { char *name; area_id id; addr_t base; addr_t size; uint32 protection; uint16 wiring; uint16 memory_type; struct vm_cache *cache; vint32 no_cache_change; off_t cache_offset; uint32 cache_type; vm_area_mappings mappings; struct vm_address_space *address_space; struct vm_area *address_space_next; struct vm_area *cache_next; struct vm_area *cache_prev; struct vm_area *hash_next; }; The address_space field tells which address space it belongs to and the base and size fields give the position of the area in the address space. Each vm_area is associated with a single vm_cache which really holds the data(see below) and the cache field points to the right vm_cache. Page Cache vm_cache contains a list of pages that stores the data. The structure makes easy share between different virtual memory areas. For example, if two areas in the same/different process are mapped from the same file, they will point to the same vm_cache The definition of vm_cache is listed below: struct vm_cache { mutex lock; struct vm_area *areas; vint32 ref_count; struct list_link consumer_link; struct list consumers; vm_page *page_list; struct vm_cache *source; struct vm_store *store; off_t virtual_base; off_t virtual_size; uint32 page_count; uint32 temporary : 1; uint32 scan_skip : 1; uint32 busy : 1; uint32 type : 5; }; Pages are cached in the same vm_cache mainly because they share one backing store (e.g. files, block device, swap). The store field in the vm_cache points to the right backing store(see below). Pages Physical Memory is divided into fixed size pieces called pages. The vm_page structure is used to describe one physical page and each physical frame has associated with a vm_page structure. struct vm_page { struct vm_page *queue_prev; struct vm_page *queue_next; struct vm_page *hash_next; addr_t physical_page_number; struct vm_cache *cache; uint32 cache_offset; struct vm_page *cache_prev; struct vm_page *cache_next; vm_page_mappings mappings; uint8 type : 2; uint8 state : 3; uint8 is_cleared : 1; uint8 busy_writing : 1; uint16 wired_count; int8 usage_count; }; Each page of physical memory is associated with a vm_cache; the cache identifies the backing store for the page. Pages are also categorized through the placement of their respective vm_page structures on one of several paging queues. There are 5 types of queues for storing pages: sFreePageQueue, sClearPageQueue, sModifiedPageQueue, sInactivePageQueue, sActivePageQueue: Backing Stores A backing store is a place for data to live when it is not resident. In the case of a memory-mapped file, the backing store is the file itself. When the kernel needs to evict from physical memory a page that is backed by a file, it can simply discard the page unless the page has been modified while it was resident, in which case the change can be committed to the backing store. The vm_store structure provides the mechanism by which data are moved between backing store and physical memory. The major component of vm_store is a number of registered functions that defines its operation. struct vm_store { struct vm_store_ops *ops; struct vm_cache *cache; off_t committed_size; }; typedef struct vm_store_ops { void (*destroy)(struct vm_store *backingStore); status_t (*commit)(struct vm_store *backingStore, off_t size); bool (*has_page)(struct vm_store *backingStore, off_t offset); status_t (*read)(struct vm_store *backingStore, off_t offset, const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); status_t (*write)(struct vm_store *backingStore, off_t offset, const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); status_t (*fault)(struct vm_store *backingStore, struct vm_address_space *aspace, off_t offset); status_t (*acquire_unreferenced_ref)(struct vm_store *backingStore); void (*acquire_ref)(struct vm_store *backingStore); void (*release_ref)(struct vm_store *backingStore); } vm_store_ops; Link them together The figure below shows how these structures are linked together. In this case, two vm_areas are mapped from the same part of a file, so they share a vm_cache. Figure 1 Link all the structures together