|
AquilaOS documentation
How it works, and its code
|
#include <core/system.h>#include <core/printk.h>#include <ds/queue.h>#include <fs/vfs.h>#include <mm/mm.h>#include <ds/hashmap.h>Go to the source code of this file.
Data Structures | |
| struct | vm_space |
| An address space: its mappings, and its page tables. More... | |
| struct | vm_entry |
| A mapping (map entry): a range of an address space, its permissions, and where its pages come from. More... | |
| struct | vm_pager |
| A vm object's pager: reads its pages in, and writes them out. More... | |
| struct | vm_aref |
| An anon's reference to a page (an aref). More... | |
| struct | vm_anon |
| An anon: a mapping's private pages, those the process wrote to. More... | |
| struct | vm_object |
| A vm object: what a mapping's pages come from (a file), and its pages that have been read in. More... | |
| struct | vm_page |
| A page of physical memory (pages[] has one for every page of RAM). More... | |
Macros | |
| #define | VM_KR 0x0001 |
| kernel read | |
| #define | VM_KW 0x0002 |
| kernel write | |
| #define | VM_KX 0x0004 |
| kernel execute | |
| #define | VM_UR 0x0008 |
| user read | |
| #define | VM_UW 0x0010 |
| user write | |
| #define | VM_UX 0x0020 |
| user execute | |
| #define | VM_PERM 0x003F |
| permissions mask | |
| #define | VM_NOCACHE 0x0040 |
| not cached (device memory) | |
| #define | VM_SHARED 0x0080 |
| shared: a fork doesn't copy it | |
| #define | VM_COPY 0x0100 |
| to be copied before it's written to | |
| #define | VM_KRW (VM_KR|VM_KW) |
| kernel read/write | |
| #define | VM_KRX (VM_KR|VM_KX) |
| kernel read/execute | |
| #define | VM_KWX (VM_KW|VM_KX) |
| kernel write/execute | |
| #define | VM_KRWX (VM_KR|VM_KW|VM_KX) |
| kernel read/write/execute | |
| #define | VM_URW (VM_UR|VM_UW) |
| user read/write | |
| #define | VM_URX (VM_UR|VM_UX) |
| user read/execute | |
| #define | VM_UWX (VM_UW|VM_UX) |
| user write/execute | |
| #define | VM_URWX (VM_UR|VM_UW|VM_UX) |
| user read/write/execute | |
| #define | VMOBJ_ZERO 0x0000 |
| pages of zeros | |
| #define | VMOBJ_FILE 0x0001 |
| a file's pages | |
Functions | |
| void | kvmem_setup (void) |
| Sets up the kernel's allocator at boot, once physical memory and the page tables are ready. | |
| void | kvmem_selftest (void) |
| Runs the allocator's self-test, for the kvmem.test kernel argument, and prints whether it passed. | |
| void | kvmem_guardtest (void) |
| Writes one byte past the end of an object, for the kvmem.guard kernel argument: the guard page should fault, and the kernel panic. | |
| int | vm_map (struct vm_space *vm_space, struct vm_entry *vm_entry) |
| Maps a map entry's whole range at once: its physical memory (paddr), or new pages of memory if it has none. | |
| void | vm_unmap_full (struct vm_space *vm_space, struct vm_entry *vm_entry) |
| Unmaps every page of a map entry's range. | |
| int | vm_space_fork (struct vm_space *parent, struct vm_space *child) |
| Copies an address space's mappings into another, for fork(). | |
| void | vm_space_destroy (struct vm_space *vm_space) |
| Removes all the mappings of an address space: its entries are released and freed, and its page tables emptied. | |
| struct vm_entry * | vm_space_find (struct vm_space *vm_space, vaddr_t vaddr) |
| Finds the map entry that an address is in. | |
| int | vm_space_insert (struct vm_space *vm_space, struct vm_entry *vm_entry) |
| Adds a map entry to an address space, in address order. | |
| struct vm_entry * | vm_entry_new (void) |
| Makes a new, empty map entry. | |
| void | vm_entry_destroy (struct vm_entry *vm_entry) |
| Releases what a map entry holds: its references to its anon and its object. | |
| struct vm_anon * | vm_anon_new (void) |
| Makes a new, empty anon. | |
| struct vm_anon * | vm_anon_copy (struct vm_anon *vm_anon) |
| Makes a copy of an anon that shares its arefs, and so its pages, when a mapping's shared anon is written to after a fork. | |
| void | vm_anon_incref (struct vm_anon *vm_anon) |
| Adds a reference to an anon: another mapping shares it (a fork). | |
| void | vm_anon_decref (struct vm_anon *vm_anon) |
| Drops a reference to an anon, and frees it with the last one. | |
| void | vm_anon_destroy (struct vm_anon *vm_anon) |
| Releases an anon's arefs, and the pages of those that no other anon shares. | |
| struct vm_object * | vm_object_vnode (struct vnode *vnode) |
| Gets a vnode's vm object, making it the first time. | |
| void | vnode_pages_update (struct vnode *vnode, off_t start, off_t end) |
| Reads a file's cached pages again after a write or a truncation changed a range of it. | |
| void | vnode_pages_free (struct vnode *vnode) |
| Frees a vnode's vm object and its cached pages, when the vnode itself is freed. | |
| int | vm_object_page_insert (struct vm_object *vm_object, struct vm_page *vm_page) |
| Adds a page to a vm object, at the page's offset (vm_page->off). | |
| void | vm_object_incref (struct vm_object *vm_object) |
| Adds a reference to a vm object: one more mapping of it. | |
| void | vm_object_decref (struct vm_object *vm_object) |
| Drops a reference to a vm object: one mapping of it less. | |
Variables | |
| struct vm_space | kvm_space |
| #define VM_COPY 0x0100 |
to be copied before it's written to
Definition at line 47 of file vm.h.
Referenced by binfmt_elf_load_segments(), pf_anon(), pf_present(), vm_anon_copy(), and vm_space_fork().
| #define VM_KR 0x0001 |
kernel read/write
Definition at line 49 of file vm.h.
Referenced by arch_mmio_map(), arch_phys_map(), earlycon_fb_init(), fbdev_vesa_prope(), kvmem_alloc(), and slab_page_alloc().
| #define VM_KW 0x0002 |
kernel write
Definition at line 39 of file vm.h.
Referenced by pf_anon(), pf_zero(), pte_flags(), pte_flags(), pte_flags(), and vm_space_fork().
| #define VM_KX 0x0004 |
| #define VM_NOCACHE 0x0040 |
not cached (device memory)
Definition at line 45 of file vm.h.
Referenced by arch_mmio_map(), pte_flags(), pte_flags(), and pte_flags().
| #define VM_PERM 0x003F |
permissions mask
Definition at line 44 of file vm.h.
Referenced by pf_anon(), pf_object(), pf_present(), and pf_zero().
| #define VM_SHARED 0x0080 |
shared: a fork doesn't copy it
Definition at line 46 of file vm.h.
Referenced by fbdev_vesa_map(), procfs_proc_maps(), procfs_proc_vmstats(), sys_mmap(), and vm_space_fork().
| #define VM_UR 0x0008 |
user read
Definition at line 41 of file vm.h.
Referenced by binfmt_elf_load_segments(), check_violation(), procfs_proc_maps(), procfs_proc_vmstats(), and sys_mmap().
user read/write/execute
Definition at line 56 of file vm.h.
Referenced by pte_flags(), pte_flags(), and pte_flags().
| #define VM_UW 0x0010 |
user write
Definition at line 42 of file vm.h.
Referenced by binfmt_elf_load_segments(), check_violation(), pf_anon(), pf_object(), procfs_proc_maps(), procfs_proc_vmstats(), pte_flags(), pte_flags(), pte_flags(), sys_mmap(), and vm_space_fork().
| #define VM_UX 0x0020 |
user execute
Definition at line 43 of file vm.h.
Referenced by binfmt_elf_load_segments(), check_violation(), procfs_proc_maps(), procfs_proc_vmstats(), pte_flags(), and sys_mmap().
| #define VMOBJ_FILE 0x0001 |
a file's pages
Definition at line 60 of file vm.h.
Referenced by procfs_proc_maps(), procfs_proc_vmstats(), vfs_map(), vm_object_decref(), vm_object_incref(), and vm_object_vnode().
| #define VMOBJ_ZERO 0x0000 |
| void kvmem_guardtest | ( | void | ) |
Writes one byte past the end of an object, for the kvmem.guard kernel argument: the guard page should fault, and the kernel panic.
Definition at line 278 of file kvmem.c.
References kmalloc(), kvmem_guardtest(), PAGE_ROUND, and printk().
Referenced by kmain(), and kvmem_guardtest().
| void kvmem_selftest | ( | void | ) |
Runs the allocator's self-test, for the kvmem.test kernel argument, and prints whether it passed.
Definition at line 264 of file kvmem.c.
References kvmem_selftest(), kvmem_selftest_run(), and printk().
Referenced by kmain(), and kvmem_selftest().
| void kvmem_setup | ( | void | ) |
Sets up the kernel's allocator at boot, once physical memory and the page tables are ready.
Definition at line 55 of file kvmem.c.
References ARCH_KVMEM_BASE, ARCH_KVMEM_SIZE, kvmem, kvmem_setup(), malloc_types, PAGE_SIZE, panic, and vmem_init().
Referenced by aarch64_init(), kvmem_setup(), and x86_cpu_init().
Makes a copy of an anon that shares its arefs, and so its pages, when a mapping's shared anon is written to after a fork.
The pages themselves are copied later, one by one, as they are written to.
| vm_anon | the anon to copy |
Definition at line 174 of file vm_anon.c.
References vm_anon::flags, kfree(), NULL, vm_anon::ref, vm_anon_copy(), vm_anon_copy_arefs(), vm_anon_destroy(), vm_anon_new(), and VM_COPY.
Referenced by pf_anon(), and vm_anon_copy().
| void vm_anon_decref | ( | struct vm_anon * | vm_anon | ) |
Drops a reference to an anon, and frees it with the last one.
| vm_anon | the anon (NULL does nothing) |
Definition at line 130 of file vm_anon.c.
References kfree(), vm_anon::ref, vm_anon_decref(), and vm_anon_destroy().
Referenced by pf_anon(), vm_anon_decref(), and vm_entry_destroy().
| void vm_anon_destroy | ( | struct vm_anon * | vm_anon | ) |
Releases an anon's arefs, and the pages of those that no other anon shares.
The anon's structure itself is freed by its caller.
| vm_anon | the anon (NULL does nothing) |
Definition at line 85 of file vm_anon.c.
References vm_anon::arefs, hashmap_node::entry, hashmap_for, kfree(), mm_page_dealloc(), vm_page::paddr, vm_aref::ref, qnode::value, vm_anon_destroy(), vm_aref_decref(), and vm_aref::vm_page.
Referenced by vm_anon_copy(), vm_anon_decref(), and vm_anon_destroy().
| void vm_anon_incref | ( | struct vm_anon * | vm_anon | ) |
Adds a reference to an anon: another mapping shares it (a fork).
| vm_anon | the anon (NULL does nothing) |
Definition at line 117 of file vm_anon.c.
References vm_anon::ref, and vm_anon_incref().
Referenced by vm_anon_incref(), and vm_space_fork().
| struct vm_anon * vm_anon_new | ( | void | ) |
Makes a new, empty anon.
Definition at line 36 of file vm_anon.c.
References vm_anon::arefs, kfree(), kmalloc(), M_ZERO, NULL, vm_anon_new(), and vm_aref_eq().
Referenced by pf_object(), pf_zero(), vm_anon_copy(), and vm_anon_new().
| void vm_entry_destroy | ( | struct vm_entry * | vm_entry | ) |
Releases what a map entry holds: its references to its anon and its object.
The entry's structure itself is freed by its caller.
| vm_entry | the entry (NULL does nothing) |
Definition at line 32 of file vm_entry.c.
References vm_entry::vm_anon, vm_anon_decref(), vm_entry_destroy(), vm_entry::vm_object, and vm_object_decref().
Referenced by sys_munmap(), vm_entry_destroy(), and vm_space_destroy().
| struct vm_entry * vm_entry_new | ( | void | ) |
Makes a new, empty map entry.
Definition at line 18 of file vm_entry.c.
References kmalloc(), M_ZERO, NULL, and vm_entry_new().
Referenced by binfmt_elf_load_segments(), sys_mmap(), and vm_entry_new().
Maps a map entry's whole range at once: its physical memory (paddr), or new pages of memory if it has none.
Entries whose pages come in on page faults aren't mapped this way.
| vm_space | the address space |
| vm_entry | the entry |
Definition at line 29 of file vmm.c.
References vm_entry::base, vm_entry::flags, mm_map(), vm_entry::paddr, vm_space::pmap, vm_entry::size, and vm_map().
Referenced by acpi_map(), earlycon_fb_init(), fbdev_vesa_map(), fbdev_vesa_prope(), and vm_map().
| void vm_object_decref | ( | struct vm_object * | vm_object | ) |
Drops a reference to a vm object: one mapping of it less.
A file's object lets go of its vnode with the last one. Its pages stay, cached with the vnode, until the vnode is freed (vnode_pages_free()).
| vm_object | the object |
Definition at line 38 of file vm_object.c.
References vm_object::p, vm_object::ref, vm_object::type, vfs_close(), vm_object_decref(), and VMOBJ_FILE.
Referenced by sys_mmap(), vm_entry_destroy(), and vm_object_decref().
| void vm_object_incref | ( | struct vm_object * | vm_object | ) |
Adds a reference to a vm object: one more mapping of it.
A file's object holds its vnode while it's mapped, because the pages are read from it, and the program file it runs may be removed meanwhile.
| vm_object | the object |
Definition at line 25 of file vm_object.c.
References vm_object::p, vm_object::ref, vnode::ref, vm_object::type, vm_object_incref(), and VMOBJ_FILE.
Referenced by arch_sigcode_map(), binfmt_elf_load_segments(), sys_mmap(), vm_object_incref(), and vm_space_fork().
Adds a page to a vm object, at the page's offset (vm_page->off).
| vm_object | the object |
| vm_page | the page |
Definition at line 52 of file vm_object.c.
References vm_page::off, vm_object::pages, and vm_object_page_insert().
Referenced by sigcode_in(), vm_object_page_insert(), and vnode_page_in().
Gets a vnode's vm object, making it the first time.
| vnode | the vnode |
Definition at line 31 of file vm_object.c.
References kfree(), kmalloc(), M_ZERO, NULL, vm_object::p, vm_object::pager, vm_object::pages, vm_object::type, vnode::vm_object, vm_object_vnode(), vm_page_eq(), VMOBJ_FILE, and vnode_pager.
Referenced by binfmt_elf_load_segments(), sys_mmap(), and vm_object_vnode().
| void vm_space_destroy | ( | struct vm_space * | vm_space | ) |
Removes all the mappings of an address space: its entries are released and freed, and its page tables emptied.
| vm_space | the address space (NULL does nothing) |
Definition at line 124 of file vm_space.c.
References kfree(), NULL, vm_space::pmap, pmap_remove_all(), vm_space::vm_entries, vm_entry_destroy(), and vm_space_destroy().
Referenced by binfmt_fmt_load(), proc_fork(), proc_kill(), and vm_space_destroy().
Finds the map entry that an address is in.
| vm_space | the address space |
| vaddr | the address |
Definition at line 99 of file vm_space.c.
References vm_entry::base, NULL, PAGE_ALIGN, queue_for, vm_entry::size, vm_space::vm_entries, and vm_space_find().
Referenced by mm_page_fault(), and vm_space_find().
Copies an address space's mappings into another, for fork().
The two share the pages, copy on write: writable private mappings become read-only in src, and their anons are marked to be copied, so that the first write to a page gives the writer its own copy (mm/fault.c).
| src | the parent's address space |
| dst | the child's address space, empty |
Definition at line 152 of file vm_space.c.
References vm_entry::base, vm_anon::flags, vm_entry::flags, kfree(), kmalloc(), memcpy(), vm_space::pmap, pmap_protect(), vm_entry::qnode, queue_for, vm_entry::size, vm_entry::vm_anon, vm_anon_incref(), VM_COPY, vm_space::vm_entries, VM_KW, vm_entry::vm_object, vm_object_incref(), VM_SHARED, vm_space_fork(), and VM_UW.
Referenced by proc_fork(), and vm_space_fork().
Adds a map entry to an address space, in address order.
If the entry's base is 0, the entry is placed at the highest free gap between mappings that it fits in. The entry always goes before an existing one (the stack's, at the top of user space): an entry past the last one can't be added.
| vm_space | the address space |
| vm_entry | the entry, with its base (or 0) and size set |
Definition at line 27 of file vm_space.c.
References vm_entry::base, queue::count, queue::head, kmalloc(), M_ZERO, qnode::next, NULL, qnode::prev, vm_entry::qnode, queue_for, vm_entry::size, qnode::value, vm_space::vm_entries, and vm_space_insert().
Referenced by arch_sigcode_map(), sys_mmap(), and vm_space_insert().
Unmaps every page of a map entry's range.
The pages themselves stay with what holds them (the anon, the file, the device): only the mappings go.
| vm_space | the address space |
| vm_entry | the entry |
Definition at line 42 of file vmm.c.
References vm_entry::base, mm_unmap_full(), vm_space::pmap, vm_entry::size, and vm_unmap_full().
Referenced by sys_munmap(), and vm_unmap_full().
| void vnode_pages_free | ( | struct vnode * | vnode | ) |
Frees a vnode's vm object and its cached pages, when the vnode itself is freed.
Nothing maps them then, since a mapping holds the vnode (vm_object_incref()).
| vnode | the vnode |
Definition at line 172 of file vm_object.c.
References hashmap_node::entry, hashmap_for, kfree(), mm_page_dealloc(), NULL, vm_page::paddr, vm_object::pages, qnode::value, vnode::vm_object, and vnode_pages_free().
Referenced by ext2_close(), procfs_close(), pseudofs_close(), and vnode_pages_free().
Reads a file's cached pages again after a write or a truncation changed a range of it.
A page stays where it is, mapped by every process that maps the file, so its contents change but not the page; past the file's end it reads zeros. A private mapping's copies, made when it wrote to a page, are its own and don't change.
| vnode | the file |
| start | the start of the range that changed |
| end | its end (exclusive) |
Definition at line 128 of file vm_object.c.
References hashmap::count, hashmap_node::entry, hashmap_node::hash, kfree(), kmalloc(), memset(), NULL, vm_page::off, vm_page::paddr, PAGE_ALIGN, PAGE_SIZE, vm_object::pages, pmap_page_write(), printk(), vfs_read(), vnode::vm_object, and vnode_pages_update().
Referenced by vfs_trunc(), vfs_write_io(), and vnode_pages_update().
|
extern |
Definition at line 17 of file vmm.c.
Referenced by acpi_map(), earlycon_fb_init(), fbdev_vesa_prope(), kproc_init(), kvmem_alloc(), kvmem_selftest_run(), kvmem_unmap(), pmap_init(), proc_kill(), request_do(), slab_page_alloc(), slab_page_free(), tables_build(), tlb_shootdown(), and x86_ap_start().