Documentation ¶
Index ¶
- Variables
- func EarlyReserveRegion(size uintptr) (uintptr, *kernel.Error)
- func IdentityMapRegion(startFrame mm.Frame, size uintptr, flags PageTableEntryFlag) (mm.Page, *kernel.Error)
- func Init(kernelPageOffset uintptr) *kernel.Error
- func Map(page mm.Page, frame mm.Frame, flags PageTableEntryFlag) *kernel.Error
- func MapRegion(frame mm.Frame, size uintptr, flags PageTableEntryFlag) (mm.Page, *kernel.Error)
- func MapTemporary(frame mm.Frame) (mm.Page, *kernel.Error)
- func PageOffset(virtAddr uintptr) uintptr
- func Translate(virtAddr uintptr) (uintptr, *kernel.Error)
- func Unmap(page mm.Page) *kernel.Error
- type PageDirectoryTable
- type PageTableEntryFlag
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidMapping is returned when trying to lookup a virtual memory address that is not yet mapped. ErrInvalidMapping = &kernel.Error{Module: "vmm", Message: "virtual address does not point to a mapped physical page"} )
var ReservedZeroedFrame mm.Frame
ReservedZeroedFrame is a special zero-cleared frame allocated by the vmm package's Init function. The purpose of this frame is to assist in implementing on-demand mmory allocation when mapping it in conjunction with the CopyOnWrite flag. Here is an example of how it can be used:
func ReserveOnDemand(start vmm.Page, pageCount int) *kernel.Error { var err *kernel.Error mapFlags := vmm.FlagPresent|vmm.FlagCopyOnWrite for page := start; pageCount > 0; pageCount, page = pageCount-1, page+1 { if err = vmm.Map(page, vmm.ReservedZeroedFrame, mapFlags); err != nil { return err } } return nil }
In the above example, page mappings are set up for the requested number of pages but no physical mmory is reserved for their contents. A write to any of the above pages will trigger a page-fault causing a new frame to be allocated, cleared (the blank frame is copied to the new frame) and installed in-place with RW permissions.
Functions ¶
func EarlyReserveRegion ¶
EarlyReserveRegion reserves a page-aligned contiguous virtual memory region with the requested size in the kernel address space and returns its virtual address. If size is not a multiple of mm.PageSize it will be automatically rounded up.
This function allocates regions starting at the end of the kernel address space. It should only be used during the early stages of kernel initialization.
func IdentityMapRegion ¶
func IdentityMapRegion(startFrame mm.Frame, size uintptr, flags PageTableEntryFlag) (mm.Page, *kernel.Error)
IdentityMapRegion establishes an identity mapping to the physical mmory region which starts at the given frame and ends at frame + pages(size). The size argument is always rounded up to the nearest page boundary. IdentityMapRegion returns back the Page that corresponds to the region start.
func Init ¶
Init initializes the vmm system, creates a granular PDT for the kernel and installs paging-related exception handlers.
func Map ¶
Map establishes a mapping between a virtual page and a physical mmory frame using the currently active page directory table. Calls to Map will use the supplied physical frame allocator to initialize missing page tables at each paging level supported by the MMU.
Attempts to map ReservedZeroedFrame with a RW flag will result in an error.
func MapRegion ¶
MapRegion establishes a mapping to the physical mmory region which starts at the given frame and ends at frame + pages(size). The size argument is always rounded up to the nearest page boundary. MapRegion reserves the next available region in the active virtual address space, establishes the mapping and returns back the Page that corresponds to the region start.
func MapTemporary ¶
MapTemporary establishes a temporary RW mapping of a physical mmory frame to a fixed virtual address overwriting any previous mapping. The temporary mapping mechanism is primarily used by the kernel to access and initialize inactive page tables.
Attempts to map ReservedZeroedFrame will result in an error.
func PageOffset ¶
PageOffset returns the offset within the page specified by a virtual address.
Types ¶
type PageDirectoryTable ¶
type PageDirectoryTable struct {
// contains filtered or unexported fields
}
PageDirectoryTable describes the top-most table in a multi-level paging scheme.
func (PageDirectoryTable) Activate ¶
func (pdt PageDirectoryTable) Activate()
Activate enables this page directory table and flushes the TLB
func (*PageDirectoryTable) Init ¶
func (pdt *PageDirectoryTable) Init(pdtFrame mm.Frame) *kernel.Error
Init sets up the page table directory starting at the supplied physical address. If the supplied frame does not match the currently active PDT, then Init assumes that this is a new page table directory that needs bootstapping. In such a case, a temporary mapping is established so that Init can:
- call kernel.Memset to clear the frame contents
- setup a recursive mapping for the last table entry to the page itself.
func (PageDirectoryTable) Map ¶
func (pdt PageDirectoryTable) Map(page mm.Page, frame mm.Frame, flags PageTableEntryFlag) *kernel.Error
Map establishes a mapping between a virtual page and a physical memory frame using this PDT. This method behaves in a similar fashion to the global Map() function with the difference that it also supports inactive page PDTs by establishing a temporary mapping so that Map() can access the inactive PDT entries.
func (PageDirectoryTable) Unmap ¶
func (pdt PageDirectoryTable) Unmap(page mm.Page) *kernel.Error
Unmap removes a mapping previousle installed by a call to Map() on this PDT. This method behaves in a similar fashion to the global Unmap() function with the difference that it also supports inactive page PDTs by establishing a temporary mapping so that Unmap() can access the inactive PDT entries.
type PageTableEntryFlag ¶
type PageTableEntryFlag uintptr
PageTableEntryFlag describes a flag that can be applied to a page table entry.
const ( // FlagPresent is set when the page is available in memory and not swapped out. FlagPresent PageTableEntryFlag = 1 << iota // FlagRW is set if the page can be written to. FlagRW // FlagUserAccessible is set if user-mode processes can access this page. If // not set only kernel code can access this page. FlagUserAccessible // FlagWriteThroughCaching implies write-through caching when set and write-back // caching if cleared. FlagWriteThroughCaching // FlagDoNotCache prevents this page from being cached if set. FlagDoNotCache // FlagAccessed is set by the CPU when this page is accessed. FlagAccessed // FlagDirty is set by the CPU when this page is modified. FlagDirty // FlagHugePage is set if when using 2Mb pages instead of 4K pages. FlagHugePage // FlagGlobal if set, prevents the TLB from flushing the cached memory address // for this page when the swapping page tables by updating the CR3 register. FlagGlobal // FlagCopyOnWrite is used to implement copy-on-write functionality. This // flag and FlagRW are mutually exclusive. FlagCopyOnWrite = 1 << 9 // FlagNoExecute if set, indicates that a page contains non-executable code. FlagNoExecute = 1 << 63 )