Pyro Kernel
Functions | Variables
areas.c File Reference

This file contains functions for manipulating regions of virtual memory known as areas. More...

Functions

void list_areas (MemContext_s *psCtx)
 Prints all areas in the specified memory context to the debug console.
 
void validate_kernel_pages (void)
 
status_t put_area (MemArea_s *psArea)
 
status_t alloc_area_list (uint32_t nProtection, uint32_t nLockMode, uintptr_t nAddress, uint_fast32_t nCount, const char *const *apzNames, size_t *panOffsets, size_t *panSizes, area_id *panAreas)
 Allocates an array of areas with the specified names, starting offsets and sizes. More...
 
status_t resize_area (area_id hArea, size_t nNewSize, bool bAtomic)
 Resizes the specified area. More...
 
status_t delete_area (area_id hArea)
 Deletes the specified area. More...
 
void empty_mem_context (MemContext_s *psCtx)
 Deletes all areas in the specified memory context.
 
void delete_mem_context (MemContext_s *psCtx)
 Deletes the specified memory context and all of its areas.
 
status_t clone_page_pte (pte_t *pDst, pte_t *pSrc, bool bCow)
 Copies a page-table entry, optionally setting up copy-on-write semantics.
 
MemContext_sclone_mem_context (MemContext_s *psOrig)
 Clones the specified memory context.
 
status_t map_area_to_file (area_id hArea, File_s *psFile, flags_t nProtection __attribute__((unused)), off_t nOffset, size_t nSize)
 Maps the specified area onto a file.
 
area_id sys_clone_area (const char *pzName, void **ppAddress, flags_t nProtection, flags_t nLockMode, area_id hSrcArea)
 Clones the specified area at a new address. More...
 
area_id create_area (const char *pzName, void **ppAddress, size_t nSize, size_t nMaxSize, flags_t nProtection, flags_t nLockMode)
 Creates a new memory area in the current process. More...
 
area_id sys_create_area (const char *pzName, void **ppAddress, size_t nSize, flags_t nProtection, flags_t nLockMode)
 Creates a new memory area with the specified attributes. More...
 
status_t sys_delete_area (area_id hArea)
 Deletes the specified area. More...
 
status_t get_area_physical_address (area_id hArea, uintptr_t *pnAddress)
 Returns the starting physical memory address for the specified area. More...
 
status_t get_area_info (area_id hArea, AreaInfo_s *psInfo)
 Returns an AreaInfo_s for the specified area. More...
 
status_t sys_get_area_info (area_id hArea, AreaInfo_s *psInfo)
 Returns an AreaInfo_s for the specified area. More...
 
status_t sys_remap_area (area_id hArea, void *pPhysAddress)
 Remaps the specified area to use a different region of physical memory. More...
 
status_t remap_area (area_id hArea, void *pPhysAddress)
 Remaps the specified area to use a different region of physical memory. More...
 
status_t memcpy_to_user (void *pDst, const void *pSrc, size_t nSize)
 Copies a region of memory from kernel space into user space. More...
 
status_t memcpy_from_user (void *pDst, const void *pSrc, size_t nSize)
 Copies a region of memory from user space into kernel space. More...
 
status_t strncpy_from_user (char *pzDst, const char *pzSrc, size_t nMaxLen)
 Copies a string from user space into kernel space. More...
 
status_t strndup_from_user (const char *pzSrc, size_t nMaxLen, char **ppzDst)
 Copies a string from user space into a newly allocated kernel region. More...
 
status_t strcpy_to_user (char *pzDst, const char *pzSrc)
 Copies a string from kernel space into user space. More...
 
status_t strlen_from_user (const char *pzString)
 Returns the length of the specified string. More...
 
status_t verify_mem_area (const void *pAddress, size_t nSize, bool bWriteAccess)
 Verifies a region of user memory for kernel access. More...
 
void * sys_sbrk (int nDelta)
 Adjusts the upper bound of a user process's data segment. More...
 
area_id clone_from_inactive_ctx (MemArea_s *psArea, uintptr_t nOffset, size_t nLength)
 clone_from_inactive_ctx() and update_inactive_ctx() are used to access an inactive address space / memory context (the associated process is not currently running, page directory is not loaded into CR3). More...
 
status_t update_inactive_ctx (MemArea_s *psOriginalArea, area_id hCloneArea, uintptr_t nOffset)
 
int sys_munmap (void *pStart, size_t nLen)
 
int sys_mprotect (void *pStart, size_t nLen, int nProt)
 
status_t msync (uint32 nAddr, size_t nLen, int nFlags)
 Write dirty pages back to the file backing the area.
 
int sys_msync (void *pStart, size_t nLen, int nFlags)
 
void init_kernel_mem_context ()
 Creates the memory context for the kernel. More...
 
void init_areas (void)
 Initializes the area manager.
 

Variables

MultiArray_s g_sAreas
 A private shared MultiArray for managing areas. More...
 
sem_id g_hAreaTableSema = -1
 A semaphore to control access to g_sAreas. More...
 

Detailed Description

This file contains functions for manipulating regions of virtual memory known as areas.

An area can exist in one of several states depending on its access privileges and whether or not it is currently located in physical memory.

Read only:
Both the area and the PTE are marked read only.
Cloned as copy-on-write:
The PTE is marked as read-only and the area is marked as read-write.
Memory mapped/not present:
The area has a non-NULL a_psFile entry and the PTE has the value 0.
Memory mapped/present:
The area has a non-NULL a_psFile entry and the PTE is marked present.
Shared/not-present:
The area has the AREA_SHARED flag set and the PTE is marked not present.
Swapped out:
The PTE is marked not-present but the address is non-null.

Function Documentation

status_t alloc_area_list ( uint32_t  nProtection,
uint32_t  nLockMode,
uintptr_t  nAddress,
uint_fast32_t  nCount,
const char *const *  apzNames,
size_t *  panOffsets,
size_t *  panSizes,
area_id *  panAreas 
)

Allocates an array of areas with the specified names, starting offsets and sizes.

All areas will have the same protection mask and locking mode.

Parameters
nProtectiona protection bitmask containing any combination of: AREA_READ, AREA_WRITE, AREA_EXEC, AREA_KERNEL, and AREA_WRCOMB.
nLockModethe locking mode to use: AREA_NO_LOCK, AREA_LAZY_LOCK, AREA_FULL_LOCK, or AREA_CONTIGUOUS.
nAddressthe base virtual memory address for the new areas. Each area will start at (nAddress + panOffsets[i]).
nCountthe number of areas to create. apzNames, panOffsets, panSizes, and panAreas are arrays of this size.
apzNamesan array of pointers to strings containing the names to use for each area. Any entry can be NULL to create an unnamed area, or a NULL pointer can be passed here to create all areas without names.
panOffsetsan array of byte offsets from nAddress to use as the start address for each area.
panSizesan array of sizes in bytes for each area.
panAreasthe area_ids of the new areas will be copied to this array.
Returns
-EINVAL if any of the areas to create would overlap or if the starting offsets are not in sequential order, -ENOADDRSPC if there isn't enough free virtual address space for the new areas, -ENOMEM if there isn't enough physical memory available; 0 otherwise.
See Also
find_unmapped_area(), do_create_area(), do_delete_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
area_id clone_from_inactive_ctx ( MemArea_s psArea,
uintptr_t  nOffset,
size_t  nLength 
)

clone_from_inactive_ctx() and update_inactive_ctx() are used to access an inactive address space / memory context (the associated process is not currently running, page directory is not loaded into CR3).

clone_from_inactive_ctx() will create in kernel space a clone of (a part of) the specified area. If you have written to the cloned area, call update_inactive_ctx() to make sure that pages allocated by the copy-on-write mechanism are transfered to the originating memory context.

area_id create_area ( const char *  pzName,
void **  ppAddress,
size_t  nSize,
size_t  nMaxSize,
flags_t  nProtection,
flags_t  nLockMode 
)

Creates a new memory area in the current process.

Parameters
pzNamea pointer to the string containing the name for the new area.
ppAddressa pointer to the variable where the start address of the new area will be stored, or NULL. If non- NULL, the previous value of the variable it points to will be used as the preferred start address of the new area.
nSizethe size in bytes of the requested area.
nMaxSizethe maximum size in bytes of the requested area.
nProtectiona protection bitmask containing any combination of: AREA_READ, AREA_WRITE, AREA_EXEC, AREA_KERNEL, and AREA_WRCOMB.
nLockModethe locking mode to use: AREA_NO_LOCK, AREA_LAZY_LOCK, AREA_FULL_LOCK, or AREA_CONTIGUOUS.
Returns
-EINVAL if the preferred starting address at *ppAddress is not a multiple of PAGE_SIZE; -ENOADDRSPC if there isn't enough virtual address space, -ENOMEM if there isn't enough physical memory; the area_id of the new area otherwise.
See Also
alloc_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t delete_area ( area_id  hArea)

Deletes the specified area.

Parameters
hAreaa handle to the area to resize.
Returns
-EINVAL if the area handle is invalid, -ENOADDRSPC if there isn't enough virtual address space available, -ENOMEM if there isn't enough physical memory available; 0 otherwise.
See Also
do_delete_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t get_area_info ( area_id  hArea,
AreaInfo_s psInfo 
)

Returns an AreaInfo_s for the specified area.

Parameters
hAreaa handle to the area for which to return info.
psInfoa pointer to the AreaInfo_s in which to store the results.
Returns
-EINVAL if the area handle is invalid or the area doesn't belong to this process; 0 otherwise.
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t get_area_physical_address ( area_id  hArea,
uintptr_t *  pnAddress 
)

Returns the starting physical memory address for the specified area.

Parameters
hAreaa handle to the area.
pnAddressa pointer to the variable where the starting physical address for hArea will be copied.
Returns
-EINVAL if hArea is invalid; 0 otherwise.
See Also
claim_device(), unregister_device(), do_get_area_physical_address()
Author
Arno Klenke (arno_.nosp@m.klen.nosp@m.ke@ya.nosp@m.hoo..nosp@m.de)
void init_kernel_mem_context ( void  )

Creates the memory context for the kernel.

This context holds all kernel areas below AREA_FIRST_USER_ADDRESS.

status_t memcpy_from_user ( void *  pDst,
const void *  pSrc,
size_t  nSize 
)

Copies a region of memory from user space into kernel space.

Parameters
pDstthe starting address of the destination region.
pSrcthe starting address of the source region.
nSizethe number of bytes to copy.
Returns
The error code from verify_mem_area() on failure; 0 otherwise.
See Also
verify_mem_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t memcpy_to_user ( void *  pDst,
const void *  pSrc,
size_t  nSize 
)

Copies a region of memory from kernel space into user space.

Parameters
pDstthe starting address of the destination region.
pSrcthe starting address of the source region.
nSizethe number of bytes to copy.
Returns
The error code from verify_mem_area() on failure; 0 otherwise.
See Also
verify_mem_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t remap_area ( area_id  hArea,
void *  pPhysAddress 
)

Remaps the specified area to use a different region of physical memory.

Parameters
hAreaa handle to the area to remap.
pPhysAddressthe new start address in physical memory for the region.
Returns
-EINVAL if the area handle is invalid or if nPhysAddress isn't a multiple of PAGE_SIZE; 0 otherwise.
See Also
do_remap_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t resize_area ( area_id  hArea,
size_t  nNewSize,
bool  bAtomic 
)

Resizes the specified area.

Parameters
hAreaa handle to the area to resize.
nNewSizethe new area size in bytes.
bAtomicif true, resize_area() will repeatedly shrink the block cache by 64K and try again if an -ENOMEM error is returned by alloc_area_pages() or alloc_area_page_tables().
Returns
-EINVAL if the area handle is invalid, -ENOADDRSPC if there isn't enough virtual address space available, -ENOMEM if there isn't enough physical memory available; 0 otherwise.
See Also
alloc_area_page_tables(), alloc_area_pages(), free_area_page_tables(), free_area_pages(), shrink_caches()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t strcpy_to_user ( char *  pzDst,
const char *  pzSrc 
)

Copies a string from kernel space into user space.

Parameters
pzDstthe starting address of the destination region.
pzSrcthe address of the string to copy.
Returns
The error code from verify_mem_area() on failure; 0 otherwise.
See Also
verify_mem_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t strlen_from_user ( const char *  pzString)

Returns the length of the specified string.

Parameters
pzStringthe starting address of the string.
Returns
The error code from verify_mem_area() on failure; the length of the string otherwise.
See Also
verify_mem_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t strncpy_from_user ( char *  pzDst,
const char *  pzSrc,
size_t  nMaxLen 
)

Copies a string from user space into kernel space.

Parameters
pzDstthe starting address of the destination region.
pzSrcthe address of the string to copy.
nMaxLenthe maximum size of the string to copy.
Returns
The error code from verify_mem_area() on failure; 0 otherwise.
See Also
verify_mem_area()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t strndup_from_user ( const char *  pzSrc,
size_t  nMaxLen,
char **  ppzDst 
)

Copies a string from user space into a newly allocated kernel region.

Parameters
pzSrcthe address of the string to copy.
nMaxLenthe maximum size of the string to copy.
ppzDsta pointer to the variable in which to store a pointer to the new string.
Returns
-ENAMETOOLONG if the length of the string, including the trailing '\0', is greater than nMaxLen, -ENOMEM if there isn't enough free memory for kmalloc(), any error code from verify_mem_area() on failure; 0 otherwise.
See Also
verify_mem_area(), kmalloc()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)
status_t update_inactive_ctx ( MemArea_s psOriginalArea,
area_id  hCloneArea,
uintptr_t  nOffset 
)
status_t verify_mem_area ( const void *  pAddress,
size_t  nSize,
bool  bWriteAccess 
)

Verifies a region of user memory for kernel access.

Parameters
pAddressthe start address of the region to lock.
nSizethe size in bytes of the region to lock.
bWriteAccesstrue to lock the region for write access; false otherwise.
Returns
-EFAULT if pAddress points to an address in kernel space, doesn't correspond to an area in user space, or if (pAddress + nSize - 1) extends beyond the end of the area; -ENOMEM if there isn't enough physical memory available; 0 otherwise.
See Also
alloc_area_pages()
Author
Kurt Skauen (kurt@.nosp@m.athe.nosp@m.os.cx)

Variable Documentation

sem_id g_hAreaTableSema = -1

A semaphore to control access to g_sAreas.

MultiArray_s g_sAreas

A private shared MultiArray for managing areas.