====== MINIX 3 Kernel API ======
**Stale page**
The contents of this page must be revised to reflect the current state of MINIX3.\\
2012-03-31 note: with sys_vumap, the first step has been made to start documenting API calls rather than the protocol.
In general, kernel calls allows system processes to request kernel services, for example to perform privileged operations. This document briefly discusses the organization of kernel calls in MINIX 3 and provides an overview of all kernel calls.
This document aims to describe the Kernel API of **MINIX 3 git-trunk**. While it is a constant work in progress, any mismatches between this document and SVN-current are unintentional.
===== Organization of Kernel Calls =====
A kernel call means that a request is sent to a kernel where it is handled by one of the kernel tasks. The details of assembling a request message, sending it to the kernel and awaiting the response are conveniently hidden in a system library. The header file of this library is **src/include/minix/syslib.h** and its implementation is found in **src/lib/syslib**.
The actual implementation of the kernel calls is defined in the **SYSTEM** kernel task. Suppose that a program makes a **sys_call()** system call. By convention, this call is transformed into a request message with type **SYS_CALL** that is sent to the kernel task SYSTEM. The SYSTEM task handles the request in a function named **do_call()** and returns the result.
The mapping of kernel call numbers and handler functions is done during the SYSTEM task's initialization response. **src/kernel/system.c**. The prototypes of the handler functions are declared in **src/kernel/system.h**. Their implementation is contained in separate files in the directory **src/kernel/system/**. These files are compiled into the library **/src/kernel/system/system.a** that is linked to the kernel.
The kernel call numbers and their request and response parameters are defined in **src/include/minix/com.h**. Kernel calls all start with **SYS_** and all parameters that belong to the same kernel call share a common prefix.
===== Overview of kernel calls in MINIX 3 =====
A concise overview of the kernel calls in MINIX 3 is given in Table 1.
|**Kernel Call** |**Purpose** |
||//PROCESS MANAGEMENT// |
|[[.:#sys_fork|SYS_FORK]] |Fork a process; copy parent process |
|[[.:#sys_exec|SYS_EXEC]] |Execute a process; initialize registers |
|[[.:#sys_exit|SYS_EXIT]] |Exit a user process; clear process slot |
|[[.:#sys_nice|SYS_NICE]] |Change priority of a user process |
|[[.:#sys_privctl|SYS_PRIVCTL]] |Change system process privileges |
|[[.:#sys_trace|SYS_TRACE]] |Trace or control process execution |
|[[.:#sys_setgrant|SYS_SETGRANT]] |Tell kernel about grant table |
|[[.:#sys_runctl|SYS_RUNCTL]] |Set/clear stop flag of a process |
||//SIGNAL HANDLING// |
|[[.:#sys_kill|SYS_KILL]] |Send a signal to a process |
|[[.:#sys_getksig|SYS_GETKSIG]] |Check for pending kernel signals |
|[[.:#sys_endksig|SYS_ENDKSIG]] |Tell kernel signal has been processed |
|[[.:#sys_sigsend|SYS_SIGSEND]] |Start POSIX-style signal handler |
|[[.:#sys_sigreturn|SYS_SIGRETURN]] |Return POSIX-style signal |
||//MEMORY MANAGEMENT// |
|[[.:#sys_newmap|SYS_NEWMAP]] |Install new or updated memory map |
|[[.:#sys_memset|SYS_MEMSET]] |Fill a physical memory area with a constant pattern byte |
|[[.:#sys_vmctl|SYS_VMCTL]] |//(to be documented)// |
||//COPYING DATA// |
|[[.:#sys_umap|SYS_UMAP]] |Map virtual to physical address |
|[[.:#sys_vumap|SYS_VUMAP]] |Batch map virtual to physical addresses |
|[[.:#sys_vircopy|SYS_VIRCOPY]] |Copy data using virtual addressing |
|[[.:#sys_physcopy|SYS_PHYSCOPY]] |Copy data using physical addressing |
|[[.:#sys_safecopyfrom|SYS_SAFECOPYFROM]] |Copy from a grant into own address space |
|[[.:#sys_safecopyto|SYS_SAFECOPYTO]] |Copy from own address space into a grant |
|[[.:#sys_vsafecopy|SYS_VSAFECOPY]] |Handle vector with safe copy requests |
|[[.:#sys_safememset|SYS_SAFEMEMSET]] |Fill a grant with a constant pattern byte |
||//DEVICE I/O// |
|[[.:#sys_devio|SYS_DEVIO]] |Read or write a single device register |
|[[.:#sys_sdevio|SYS_SDEVIO]] |Input or output an entire data buffer |
|[[.:#sys_vdevio|SYS_VDEVIO]] |Process vector with multiple requests |
|[[.:#sys_irqctl|SYS_IRQCTL]] |Set or reset an interrupt policy |
|[[.:#sys_iopenable|SYS_IOPENABLE]] |Give process I/O privilege |
|[[.:#sys_readbios|SYS_READBIOS]] |Copy from the BIOS area |
||//SYSTEM CONTROL// |
|[[.:#sys_abort|SYS_ABORT]] |Abort MINIX: shutdown the system |
|[[.:#sys_getinfo|SYS_GETINFO]] |Get a copy system info or kernel data |
|[[.:#sys_sysctl|SYS_SYSCTL]] |//(to be documented)// |
||//CLOCK FUNCTIONALITY// |
|[[.:#sys_setalarm|SYS_SETALARM]] |Set or reset a synchronous alarm timer |
|[[.:#sys_times|SYS_TIMES]] |Get process times, boot time and uptime |
|[[.:#sys_stime|SYS_STIME]] |Set boot time |
|[[.:#sys_vtimer|SYS_VTIMER]] |Set or retrieve a process virtual timer |
||//PROFILING// |
|[[.:#sys_sprof|SYS_SPROF]] |//(to be documented)// |
|[[.:#sys_cprof|SYS_CPROF]] |//(to be documented)// |
|[[.:#sys_profbuf|SYS_PROFBUF]] |//(to be documented)// |
**Table 1**: This table provides an overview of the kernel calls in MINIX 3.
===== MINIX 3 kernel call interface =====
The kernel call interface is detailed below. For each kernel the message type, the purpose, message type, request and/or response parameters and return value are specified. The shorthand additional remarks about the future status of the call may also be provided.
** Legends ** \\ //CONSTANT:// defined constant; a number indicating the request type or status. \\ //PARAMETER:// message parameter; a field in the request or response message.\\ //void sys_call(arguments):// system library function; shorthand to make a kernel call.
** Alphabetical Overview **\\
==== SYS_ABORT ====
Shutdown MINIX and return to the boot monitor, if possible. This is used by PM, FS and TTY. Normal aborts usually are initiated by the user, for example by means of the //shutdown// command or typing //Ctrl-Alt-Del//. MINIX will also be taken down if a fatal error occurs in the PM or FS.
** request parameters ** \\ ABRT_HOW: How to abort. One of the values defined in src/include/unistd.h
* RBT_HALT: Halt MINIX and return to the boot monitor.
* RBT_REBOOT: Reboot MINIX.
* RBT_PANIC: A kernel panic occurred.
* RBT_MONITOR: Run the specified code at the boot monitor.
* RBT_RESET: Hard reset the system.
ABRT_MON_ENDPT: Process to get the boot monitor parameters from.\\ ABRT_MON_LEN: Length of the boot monitor parameters.\\ ABRT_MON_ADDR: Virtual address of the parameters.
**return value**\\ OK: The shutdown sequence was started.\\ ENIVAL: Invalid process number.\\ EFAULT: Illegal monitor parameters address.\\ E2BIG: Monitor parameters exceed maximum length.
**library functions**\\ int sys_abort(int shutdown_status, ...);
==== SYS_CPROF ====
**request parameters**\\ //(to be documented)//
**response parameters**\\ //(to be documented)//
**return value**\\ //(to be documented)//
**library functions**\\ int sys_cprof(int action, int size, int endpt, void *ctl_ptr, void *mem_ptr);
==== SYS_DEVIO ====
Perform device I/O on behalf of a user-space device driver. The driver can request a single port to be read or written with this call. Also see the [[.:#sys_sdevio|SYS_SDEVIO]] and [[.:#sys_vdevio|SYS_VDEVIO]] kernel calls.
**request parameters**\\ DIO_REQUEST: Flags indicating what to do.
* _DIO_INPUT: Read a value from the given port.
* _DIO_OUTPUT: Write the given value to the given port.\\\\
* _DIO_BYTE: Read/write a byte value.
* _DIO_WORD: Read/write a word value.
* _DIO_LONG: Read/write a long value.
DIO_PORT: The port to be read or written.\\ DIO_VALUE: Value to write to the given port. For DIO_OUTPUT only.
**response parameters**\\ DIO_VALUE: Value that was read from the given port. For DIO_INPUT only.
**return value**\\ OK: The port I/O was successfully done.\\ EINVAL: An invalid DIO_REQUEST or DIO_TYPE was provided.
**library functions**\\ int sys_in(port_t port, unsigned long value, int io_type);\\ int sys_inb(port_t port, u8_t *byte);\\ int sys_inw(port_t port, u16_t *word);\\ int sys_inl(port_t port, u32_t *long);\\ int sys_out(port_t port, unsigned long value, int io_type);\\ int sys_outb(port_t port, u8_t byte);\\ int sys_outw(port_t port, u16_t word);\\ int sys_outl(port_t port, u32t long);\\
==== SYS_ENDKSIG ====
Finish a kernel signal. The PM uses this call to indicate if it has processed the kernel signals in the map obtained through a [[.:#sys_getksig|SYS_GETKSIG]] kernel call.
**request parameters**\\ SIG_ENDPT: The process that it concerns.\\
**return value**\\ EINVAL: The process had no pending signals or already exited.\\ OK: The kernel cleared all pending signals.
**library functions**\\ int sys_endksig(endpoint_t proc_nr);
==== SYS_EXEC ====
Update a process' registers after a successful exec() POSIX-call. After the FS has copied the binary image into memory, the PM informs the kernel about the new register details.
**request parameters**\\ PR_ENDPT: Process that executed a program.\\ PR_STACK_PTR: New stack pointer.\\ PR_IP_PTR: New program counter.\\ PR_NAME_PTR: Pointer to a name of program.\\
**return value**\\ OK: This call always succeeds.
**library functions**\\ int sys_exec(endpoint_t proc, char *stack_ptr, char *prog_name, vir_bytes pc);
==== SYS_EXIT ====
Clear a process slot. This call is to be used by PM only.
**request parameters**\\ PR_ENDPT: Slot number of exiting process if caller is PM. Use SELF to exit the PM.
**return value**\\ OK: The cleanup succeeded.\\ EINVAL: Incorrect process number.\\ EDONTREPLY: This call does not return if a system process exited.
**library functions**\\ int sys_exit(endpoint_t proc_nr);
==== SYS_FORK ====
Allocate a new (child) process in the kernel process table and initialize it based on the prototype (parent) process. The PM has found a free process slot for the child process in its own process table and now requests the kernel to update the kernel's process table.
**request parameters**\\ PR_ENDPT: Parent, the process that forked.\\ PR_SLOT: Child's process table slot.\\ PR_MEM_PTR: New memory map for the child.\\ PR_FORK_FLAGS: Fork flags.
* PFF_VMINHIBIT: Don't schedule process in VM mode until it has a new pagetable.
**response parameters**\\ PR_ENDPT: Process endpoint of the child.
**return value**:\\ OK: A new process slot was successfully assigned.\\ EINVAL: Invalid parent process number or child slot to use.
**library functions**:\\ int sys_fork(endpoint_t parent, int child, endpoint_t *child_endpoint, struct mem_map *ptr, u32_t flags);
==== SYS_GETINFO ====
Obtain a copy of a kernel data structure. This call supports user-space device drivers and servers that need certain system information.
**request parameters**\\ I_REQUEST: The type of system information that is requested.
* GET_AOUTHEADER: Copy boot image a.out headers.
* GET_HZ: Copy system clock frequency in ticks per second.
* GET_IDLETSC: Copy accumulated idle timestamp counter, if CONFIG_IDLE_TSC is defined.
* GET_IMAGE: Copy boot image table.
* GET_IRQACTIDS: Copy IRQ is-hook-active bits.
* GET_IRQHOOKS: Copy table with interrupt hooks.
* GET_KINFO: Copy kernel information structure.
* GET_KMESSAGES: Copy buffer with diagnostic kernel messages.
* GET_LOADINFO: Copy system load information.
* GET_LOCKTIMING: Copy lock times, if DEBUG_TIME_LOCKS is set.
* GET_MACHINE: Copy system information.
* GET_MONPARAMS: Copy parameters set by the boot monitor.
* GET_PRIV: Copy system privileges table slot.
* GET_PRIVTAB: Copy system privileges table.
* GET_PROC: Copy single process table slot.
* GET PROCTAB: Copy entire kernel process table.
* GET_RANDOMNESS: Copy randomness gathered by kernel events.
* GET_RANDOMNESS_BIN: Copy and wipe randomness bin.
* GET_WHOAMI: Copy process name and endpoint.
I_VAL_PTR: Virtual address where the information should be copied to.\\ I_VAL_LEN: Maximum length that the caller can handle. \\ I_VAL_PTR2: Optional, second address. Used when copying scheduling data.\\ I_VAL_LEN2: Optional, second length. Overloaded for process number.
**return number**\\ OK: The information request succeeded.\\ EFAULT: An illegal memory address was detected.\\ E2BIG: Requested data exceeds the maximum provided by the caller.\\
**library functions**\\ int sys_getaoutheader(struct exec *e_hdr, int index);\\ int sys_getidletsc(u64_t *idle_tsc);\\ int sys_getinfo(int request,void *ptr,int len,void *ptr2,int len2);\\ int sys_getirqactids(int *irq_actids);\\ int sys_getirqhooks(struct irq_hook *ptr);\\ int sys_getimage(struct boot_image *ptr);\\ int sys_getkinfo(struct kinfo *ptr);\\ int sys_getkmessages(struct kmessages *ptr);\\ int sys_getloadinfo(struct loadinfo *ptr);\\ int sys_getlocktimings(struct lock_timingdata *ptr);\\ int sys_getmachine(struct machine *ptr);\\ int sys_getmonparams(char *ptr,int max_len);\\ int sys_getpriv(struct priv *ptr, endpoint_t proc_nr);\\ int sys_getprivtab(struct priv *ptr);\\ int sys_getproc(struct proc *ptr,int proc_nr);\\ int sys_getproctab(struct proc *ptr);\\ int sys_getrandomness(struct randomness *ptr);\\ int sys_getrandom_bin(struct k_randomness_bin *ptr, int bin);\\ int sys_whoami(endpoint_t *ep, char *name, int namelen);\\
==== SYS_GETKSIG ====
Checks whether there is a process that must be signaled. This is repeatedly done by the PM after receiving a notification that there are kernel signals pending.
**response parameters**\\ SIG_ENDPT: Return next process with pending signals or NONE.\\ SIG_MAP: Bit map with pending kernel signals.
**return value**\\ OK: This call always succeeds.
**library functions**\\ int sys_getksig(endpoint_t *proc_nr, sigset_t *sig_map);
==== SYS_IOPENABLE ====
Enable the CPU's I/O privilege level bits for the given process, so that it is allowed to directly perform I/O in user space.
**request parameters**\\ IOP_ENDPT: The process to give I/O privileges.
**return value**\\ OK: Always succeeds.
**library functions**\\ int sys_enable_iop(endpoint_t proc);
==== SYS_IRQCTL ====
Set or reset a hardware interrupt policy for a given IRQ line and enable or disable interrupts for this line. This call allows user-space device drivers to grab a hook for use with the kernel's generic interrupt handler. The kernel's interrupt handler merely notifies the driver about the interrupt with a HARD_INT message and reenables the IRQ line if the policy says so. The notification message will contain the //id// provided by the caller as an argument. Once a policy is in place, drivers can enable and disable interrupts.
**request parameters**\\ IRQ_REQUEST: Interrupt control request to perform.
* IRQ_SETPOLICY: Set interrupt policy for the generic interrupt handler.
* IRQ_RMPOLICY: Remove a previously set interrupt policy.
* IRQ_ENABLE: Enable IRQs for the given IRQ line.
* IRQ_DISABLE: Disable IRQs for the given IRQ line.
IRQ_VECTOR: IRQ line that must be controlled. \\ IRQ_POLICY: Bit map with flags indicating IRQ policy. \\ IRQ_HOOK_ID: When setting a policy this provides index sent to caller upon interrupt. For other requests it is the kernel hook identifier returned by the kernel.\\
**response parameters**\\ IRQ_HOOK_ID: Kernel hook identifier associated with the driver.
**return value**\\ EINVAL: Invalid request, IRQ line, hook id, or process number.\\ EPERM: Only owner of hook can toggle interrupts or release the hook.\\ ENOSPC: No free IRQ hook could be found.\\ OK: The request was successfully handled.\\
**library functions**\\ int sys_irqctl(int request, int irq_vec, int policy, int *hook_id);\\ int sys_irqsetpolicy(int irq_vec, int policy, int *hook_id);\\ int sys_irqrmpolicy(int *hook_id);\\ int sys_irqenable(int *hook_id);\\ int sys_irqdisable(int *hook_id);
==== SYS_KILL ====
Signal a process on behalf of a system server. A system process can signal another process with this call. The kernel notifies the PM about the pending signal for further processing (Note that the //kill()// POSIX-call is directly handled at the PM). The PM uses this call to indirectly send a signal message to a system process. This happens when a signal arrives for a system process that set the special SIG_MESS signal handler with the //sigaction()// POSIX-call.
**request parameters**\\ SIG_ENDPT: Process to be signalled.\\ SIG_NUMBER: Signal number. Range from 0 to _NSIG.
**return value**\\ OK: Call succeeded.\\ EINVAL: Illegal process or signal number.\\ EPERM: Cannot send a signal to a kernel task. PM cannot signal a user process with a notification message.
**library functions**\\ int sys_kill(endpoint_t proc_nr, int sig_nr);
==== SYS_NEWMAP ====
Install a new memory map for a newly forked process or if a process's memory map is changed. The kernel fetches the new memory map from PM and updates its data structures.
**request parameters**\\ PR_ENDPT: Install new map for this process.\\ PR_MEM_PTR: Pointer to memory map at PM.\\
**return value**\\ OK: New map was successfully installed. \\ EFAULT: Incorrect address for new memory map. \\ EINVAL: Invalid process number. \\
**library functions**\\ int sys_newmap(endpoint_t proc_nr, struct mem_map *ptr);
==== SYS_NICE ====
Change a process' priority. This is done by passing a nice value between PRIO_MIN(negative) and PRIO_MAX(positive). A nice value of zero resets the priority to the default.
**request parameters**\\ PR_ENDPT: Process whose priority should be changed.\\ PR_PRIORITY: New nice value for process' priority.
**return value**\\ OK: New priority was successfully set.\\ EINVAL: Invalid process number of priority.\\ EPERM: Cannot change priority of kernel task.
**library functions**\\ int sys_nice(endpoint_t proc_nr, int priority);
==== SYS_PHYSCOPY ====
Copy data using physical addressing. The source and/or destination address can be virtual like with [[.:#sys_vircopy|SYS_VIRCOPY]], but in addition an arbitrary physical address is accepted with PHYS_SEG.
**request parameters**\\ CP_SRC_SPACE: Source segment.\\ CP_SRC_ADDR: Virtual source address.\\ CP_SRC_ENDPT: Process number of the source process.\\ CP_DST_SPACE: Destination segment.\\ CP_DST_ADDR: Virtual destination address.\\ CP_DST_ENDPT: Process number of the destination process.\\ CP_NR_BYTES: Number of bytes to copy.
**return value**\\ OK: The copying was done.\\ EDOM: Invalid copy count.\\ EFAULT: Virtual to physical mapping failed.\\ EINVAL: Incorrect segment type of process number.\\ EPERM: Only owner of REMOTE_SEG can copy to or from it.
**library functions**\\ int sys_abscopy(phys_bytes src_phys, phys_bytes dst_phys, phys_bytes count);\\ int sys_physcopy(endpoint_t src_proc, vir_bytes src_vir, endpoint_t dst_proc, vir_bytes dst_vir, phys_bytes count);
==== SYS_PRIVCTL ====
Get a private privilege structure and update a process' privileges. This is used to dynamically start system services. For VM, this call also supports querying a memory range for previously added memory permissions.
**request parameters**\\ CTL_ENDPT: Process whose privileges should be updated/queried.\\ CTL_REQUEST: The privilege modification/query request.
* SYS_PRIV_ALLOW: Allow a process to run.
* SYS_PRIV_DISALLOW: Disallow a process from running.
* SYS_PRIV_SET_SYS: Give a process system privileges.
* SYS_PRIV_SET_USER: Give a process user privileges.
* SYS_PRIV_ADD_IO: Add an I/O range to the process's resources.
* SYS_PRIV_ADD_MEM: Add a memory range to the process's resources
* SYS_PRIV_ADD_IRQ: Add an IRQ to the process's resources.
* SYS_PRIV_QUERY_MEM: Check if the process has permission to access a physical memory range.
CTL_ARG_PTR: Pointer to arguments for this request (**not** for SYS_PRIV_QUERY_MEM).\\ CTL_PHYSSTART: Start of physical memory range to test (only for SYS_PRIV_QUERY_MEM).\\ CTL_PHYSLEN: Length of physical memory range to test (only for SYS_PRIV_QUERY_MEM).
**return value**\\ OK: The calls succeeded.\\ EINVAL: Invalid process number, request, or arguments.\\ ENOSPC: No free privilege structure found.\\ EPERM: Resources can not be added to user processes, or permission denied.\\ ENOMEM: No storage available for this resource.
**library functions**\\ int sys_privctl(endpoint_t proc, int req, void *p);\\ int sys_privquery_mem(endpoint_t proc, phys_bytes start, phys_bytes len);
==== SYS_PROFBUF ====
**request parameters**\\ //(to be documented)//
**response parameters**\\ //(to be documented)//
**return value**\\ //(to be documented)//
**library functions**\\ int sys_profbuf(void *ctl_ptr, void *mem_ptr);
==== SYS_READBIOS ====
Copy from the BIOS area.
**request parameters**\\ RDB_ADDR: Absolute address in BIOS area.\\ RDB_BUF: Buffer address in the requesting process.\\ RDB_SIZE: The number of bytes to copy.
**return value**\\ OK: The call succeeded.\\ EDOM: Invalid number of bytes.\\ EFAULT: Invalid buffer address.
**library functions**\\ int sys_readbios(phys_bytes address, void *buf, size_t size);
==== SYS_RUNCTL ====
Control the process's PROC_STOP flag. Used for process management (by PM). Stopping a process is generally done for the purpose of either setting up a signal handler or stopping a process that is about to be killed. When stopping for setting up a signal handler, the RC_DELAY flag will be supplied. This means that if the process is queued sending a message, or stopped for system call tracing, then this call will, instead of stopping the process, return EBUSY and later send a //SIGNDELAY// pseudo-signal to the process when it has been established that this process will not send a message anymore. The process never becomes actually runnable before PM eventually tells the kernel that it is done processing the SIGNDELAY (using [[.:#sys_endksig|SYS_ENDKSIG]]). This "delay stop" mechanism is used by PM to make sure that no signal is delivered to a process that still has a call pending to a system server. This is required for POSIX compliance.
**request parameters**\\ RC_ENDPT: The process number to control.\\ RC_ACTION: Stop or resume the process.
* RC_STOP: Stop the process.
* RC_RESUME: Resume the process.
RC_FLAGS: Request flags.
* RC_DELAY: Delay stop if process is sending.
**return value**\\ OK: The call succeeded.\\ EINVAL: Invalid process number.\\ EPERM: The caller is a kernel task.\\ EBUSY: The process is blocked sending a message or blocked for system call tracing.
**library functions**\\ int sys_runctl(endpoint_t proc_ep, int action, int flags);\\ int sys_stop(endpoint_t proc_ep);\\ int sys_delay_stop(endpoint_t proc_ep);\\ int sys_resume(endpoint_t proc_ep);
==== SYS_SAFECOPYFROM ====
Copy data from a granted memory area of another process, into one's own address space. The caller must have CPF_READ access to the grant.
**request parameters**\\ SCP_FROM_TO: The process endpoint to copy from.\\ SCP_SEG: The segment within the caller to copy to (typically D).\\ SCP_GID: The grant ID.\\ SCP_OFFSET: Starting byte offset within the grant.\\ SCP_ADDRESS: Pointer to buffer to store the data in.\\ SCP_BYTES: Number of bytes to copy.
**return value**\\ OK: The call succeeded.\\ EINVAL: Invalid process number.\\ EPERM: Invalid grant ID, insufficient access, or bad byte range.\\ ELOOP: Chain of indirect grants too long.
**library functions**\\ int sys_safecopyfrom(endpoint_t source, cp_grant_id_t grant, vir_bytes grant_offset, vir_bytes my_address, size_t bytes);
==== SYS_SAFECOPYTO ====
Copy data from one's own address space, to a granted memory area of another process. The caller must have CPF_WRITE access to the grant.
**request parameters**\\ SCP_FROM_TO: The process endpoint to copy to.\\ SCP_SEG: The segment within the caller to copy from (typically D).\\ SCP_GID: The grant ID.\\ SCP_OFFSET: Starting byte offset within the grant.\\ SCP_ADDRESS: Pointer to data to copy.\\ SCP_BYTES: Number of bytes to copy.
**return value**\\ OK: The call succeeded.\\ EINVAL: Invalid process number.\\ EPERM: Invalid grant ID, insufficient access, or bad byte range.\\ ELOOP: Chain of indirect grants too long.
**library functions**\\ int sys_safecopyto(endpoint_t dest, cp_grant_id_t grant, vir_bytes grant_offset, vir_bytes my_address, size_t bytes);
==== SYS_SDEVIO ====
Perform device I/O on behalf of a user-space device driver. Note that this call supports only byte and word granularity. The driver can request input or output of an entire buffer. Also see [[.:#sys_devio|SYS_DEVIO]] and [[.:#sys_vdevio|SYS_VDEVIO]] kernel calls.
**request parameters**\\ DIO_REQUEST: Flags indicating what to do.
* _DIO_INPUT: Read one or more values from the given port.
* _DIO_OUTPUT: Write one or more values to the given port.\\\\
* _DIO_BYTE: Read/write byte values.
* _DIO_WORD: Read/write word values.\\\\
* _DIO_SAFE: The given address is a grant.
DIO_PORT: The port to be read or written.\\ DIO_VEC_ENDPT: Process number where buffer is.\\ DIO_VEC_ADDR: Virtual address of buffer, or grant ID.\\ DIO_VEC_SIZE: Number of elements to input or output.\\ DIO_OFFSET: Offset into grant.
**return value**\\ OK: The port I/O was successfully done.\\ EINVAL: Invalid request or port granularity.\\ EPERM: Cannot do I/O for kernel tasks.\\ EFAULT: Invalid virtual address of buffer.
**library functions**\\ int sys_insb(port_t port, u8_t buffer, int count);\\ int sys_insw(port_t port, u16_t buffer, int count);\\ int sys_outsb(port_t port, u8_t buffer, int count);\\ int sys_outsw(port_t port, u16_t buffer, int count);\\ int sys_safe_insb(port_t port, endpoint_t proc_nr, void *grant, int count, vir_bytes offset);\\ int sys_safe_insw(port_t port, endpoint_t proc_nr, void *grant, int count, vir_bytes offset);\\ int sys_safe_outsb(port_t port, endpoint_t proc_nr, void *grant, int count, vir_bytes offset);\\ int sys_safe_outsw(port_t port, endpoint_t proc_nr, void *grant, int count, vir_bytes offset);\\ int sys_sdevio(int req, long port, endpoint_t proc_nr, void *buffer, int count, vir_bytes offset);
==== SYS_SETALARM ====
Set or reset a synchronous alarm timer. When the timer expires it causes a SYN_ALARM notification message with the current uptime as an argument to be sent to the caller. Only system processes can request synchronous alarms.
**request parameters**\\ ALRM_EXP_TIME: Absolute or relative expiration time in ticks for this alarm.\\ ALRM_ABS_TIME: Zero if expire time is relative to the current uptime.
**response parameters**\\ ALRM_TIME_LEFT: Ticks left on the previous alarm.
**return value**\\ OK: The alarm was successfully set.\\ EPERM: User processes cannot request alarms.
**library functions**\\ int sys_setalarm(clock_t expire_time, int abs_flag);
==== SYS_SETGRANT ====
Set the address and size of the process's grant table. The previous address and size will be replaced.
**request parameters**\\ SG_ADDR: Address of grant table in own address space.\\ SG_SIZE: Number of entries.
**return value**\\ OK: The grant table has been set.\\ EPERM: The caller has no privilege table.
**library functions**\\ int sys_setgrant(cp_grant_t *grants, int ngrants);
==== SYS_SIGRETURN ====
Return from a POSIX-style signal handler. The PM requests the kernel to put things in order before the signalled process can resume execution. Also see the [[.:#sys_sigsend|SYS_SIGSEND]] kernel call that pushes a signal context frame onto the stack.
**request parameters**\\ SIG_ENDPT: Indicates the process was signalled.\\ SIG_CTXT_PTR: Pointer to context structure for POSIX-style signal handling.
**return value**\\ OK: Signal handling action successfully performed.\\ EINVAL: Invalid process number or context structure.\\ EFAULT: Invalid context structure address, or could not copy signal frame.
**library functions**\\ int sys_sigreturn(endpoint_t proc_nr, struct sigmsg *sig_context);
==== SYS_SIGSEND ====
Signal a process on behalf of the PM by placing the context structure onto the stack. The kernel fetches the structure, initializes it, and copies it to the user's stack.
**request parameters**\\ SIG_ENDPT: Indicates the process that was signalled.\\ SIG_CTXT_PTR: Pointer to content structure for POSIX-style signal handling.
**return value**\\ OK: Signal handling action successfully performed.\\ EINVAL: Invalid process number.\\ EPERM: Cannot signal kernel tasks.\\ EFAULT: Invalid context structure address, or could not copy signal frame.
**library functions**\\ int sys_sigsend(endpoint_t proc_nr, struct sigmsg *sig_context);
==== SYS_SPROF ====
**request parameters**\\ //(to be documented)//
**response parameters**\\ //(to be documented)//
**return value**\\ //(to be documented)//
**library functions**\\ //(to be documented)//
==== SYS_STIME ====
Set the boot time. This effectively sets the current time, as the current time is computed by adding the uptime to the boot time.
**request parameters**\\ T_BOOTTIME: Boot time in seconds.
**return value**\\ OK: Always succeeds.
**library functions**\\ int sys_stime(time_t boottime);
==== SYS_SYSCTL ====
**request parameters**\\ //(to be documented)//
**response parameters**\\ //(to be documented)//
**return value**\\ //(to be documented)//
**library functions**\\ //(to be documented)//
==== SYS_TIMES ====
Get the kernel's uptime since boot and process execution times.
**request parameters**\\ T_ENDPT: Process for which to request the user and system time, or NONE.
**response parameters**\\ T_USER_TIME: Process' user time in ticks, if given endpoint is not NONE.\\ T_SYSTEM_TIME: Process's system time in ticks, if given endpoint is not NONE.\\ T_BOOT_TICKS: Number of ticks since MINIX boot (uptime).\\ T_BOOTTIME: Boot time in seconds.
**return value**\\ OK: Always succeeds.
**library functions**\\ int sys_times(endpoint_t proc_nr, clock_t *user_time, clock_t *system_time, clock_t *uptime);
==== SYS_TRACE ====
Monitor or control execution of the given process. Handle the debugging commands supported by the ptrace() system call.
**request parameters**\\ CTL_REQUEST: The tracing request.
* T_STOP: Stop the process.
* T_GETINS: Return value from instruction space.
* T_GETDATA: Return value from data space.
* T_GETUSER: Return value from user process table.
* T_SETINS: Set value from instruction space.
* T_SETDATA: Set value from data space.
* T_SETUSER: Set value in user process table.
* T_RESUME: Resume execution.
* T_STEP: Set trace bit.
* T_SYSCALL: Trace system call.
* T_DETACH: Detach from a traced process.
CTL_ENDPT: The process number that is being traced.\\ CTL_ADDRESS: Virtual address in the traced process' space.\\ CTL_DATA: Data to be written.
**response parameters**\\ CTL_DATA: Data to be returned.
**return value**\\ OK: Trace operation succeeded.\\ EIO: Set or get value failed.\\ EINVAL: Unsupported trace request.\\ PERM: Can only trace user processes.
**library functions**\\ int sys_trace(int request, endpoint_t proc_nr, long addr, long *data_ptr);
==== SYS_UMAP ====
Map a virtual address to a physical address and return the physical address. The virtual address can be in LOCAL_SEG, REMOTE_SEG or BIOS_SEG. An offset in bytes can be passed to verify whether this also falls within the segment.
**request parameters**\\ CP_SRC_ENDPT: Process number of the address relates to.\\ CP_SRC_SPACE: Segment identifier.\\ CP_SRC_ADDR: Offset within segment.\\ CP_NR_BYTES: Number of bytes from start.
**response parameters**\\ CP_DST_ADDR: Physical address if mapping succeeded.
**return value**\\ OK: The copying was done.\\ EFAULT: Virtual to physical mapping failed.\\ EINVAL: Incorrect segment type or process number.
**remarks**\\ Address zero within BIOS_SEG returns EFAULT, while the zeroth BIOS interrupt vector is in fact a valid address.
**library functions**\\ int sys_umap(endpoint_t proc_nr, int seg, vir_bytes vir_addr, vir_bytes count, phys_bytes *phys_addr);
==== SYS_VDEVIO ====
Perform a series of device I/O on behalf of a user process. The call accepts a pointer to the first element of an array of (port,value)-pairs that are to be handled at once. Hardware interrupts are temporarily disabled to prevent the batch of I/O calls to be interrupted. Also see [[.:#sys_devio|SYS_DEVIO]] and [[.:#sys_sdevio|SYS_SDEVIO]].
**request parameters**\\ DIO_REQUEST: Flags indicating what to do.
* _DIO_INPUT: Read values from ports.
* _DIO_OUTPUT: Write values to ports.\\\\
* _DIO_BYTE: Read/write byte values.
* _DIO_WORD: Read/write word values.
* _DIO_LONG: Read/write long values.
DIO_VEC_SIZE: The number of ports to be handled.\\ DIO_VEC_ADDR: Virtual address of the (port,address)-pairs in the caller's space.
**return value**\\ OK: The port I/O was successfully done.\\ EINVAL: Invalid request or granularity.\\ E2BIG: Vector size exceeds maximum that can be handled.\\ EFAULT: The address of the (port,value)-pair is erroneous.
**library functions**\\ int sys_voutb(pvb_pair_t *pvb_vec, int vec_size);\\ int sys_voutw(pvb_pair_t *pvw_vec, int vec_size);\\ int sys_voutl(pvb_pair_t *pvl_vec, int vec_size);\\ int sys_vinb(pvb_pair_t *pvb_vec, int vec_size);\\ int sys_vinw(pvb_pair_t *pvw_vec, int vec_size);\\ int sys_vinl(pvb_pair_t *pvl_vec, int vec_size);
==== SYS_VIRCOPY ====
Copy data using virtual addressing. The virtual can be in three segments: LOCAL_SEG(text, stack, data segments), REMOTE_SEG(e.g. RAM disk, video memory) and the BIOS_SEG(BIOS interrupt vectors, BIOS data area). This is the most common system call relating to copying.
**request parameters**\\ CP_SRC_SPACE: Source segment\\ CP_SRC_ADDR: Virtual source address.\\ CP_SRC_ENDPT: Process number of the source process.\\ CP_DST_SPACE: Destination segment. \\ CP_DST_ADDR: Virtual destination address.\\ CP_DST_ENDPT: Process number of the destination process.\\ CP_NR_BYTES: Number of bytes to copy.
**return value**\\ OK: The copying was done.\\ EDOM: Invalid copy count. \\ EFAULT: Virtual to physical mapping failed.\\ EPERM: No permission to use PHYS_SEG.\\ EINVAL: Incorrect segment type or process number.\\ EPERM: Only owner of REMOTE_SEG can copy to or from it.
**library functions**\\ int sys_biosin(vir_bytes bios_vir, vir_bytes dst_vir, phys_bytes bytes);\\ int sys_biosout(vir_bytes src_vir, vir_bytes bios_vir, phys_bytes bytes);\\ int sys_datacopy(endpoint_t src_proc, vir_bytes src_vir, endpoint_t dst_proc, vir_bytes dst_vir, phys_bytes bytes);\\ int sys_textcopy(endpoint_t src_proc, vir_bytes src_vir, endpoint_t dst_proc, vir_bytes dst_vir, phys_bytes bytes);\\ int sys_stackcopy(endpoint_t src_proc, vir_bytes src_vir, endpoint_t dst_proc, vir_bytes dst_vir, phys_bytes bytes);\\ int sys_vircopy(endpoint_t src_proc, vir_bytes src_vir, endpoint_t dst_proc, vir_bytes dst_vir, phys_bytes bytes);
==== SYS_VMCTL ====
**request parameters**\\ //(to be documented)//
**response parameters**\\ //(to be documented)//
**return value**\\ //(to be documented)//
**library functions**\\ int sys_vmctl(endpoint_t who, int param, u32_t value);\\ int sys_vmctl_get_pagefault_i386(endpoint_t *who, u32_t *cr2, u32_t *err);\\ int sys_vmctl_get_cr3_i386(endpoint_t who, u32_t *cr3);\\ int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem, vir_bytes *len, int *wrflag, endpoint_t *who_s, vir_bytes *mem_s, endpoint_t *);\\ int sys_vmctl_enable_paging(struct mem_map *);\\ int sys_vmctl_get_mapping(int index, phys_bytes *addr, phys_bytes *len, int *flags);\\ int sys_vmctl_reply_mapping(int index, vir_bytes addr);
==== SYS_VSAFECOPY ====
Perform a vectored safecopy operation. Each vector element specifies the source, destination, grant ID, grant offset, pointer into caller's address space, and number of bytes to copy. For each element, either source or destination must be set to SELF. The data segment is used for both source and destination.
**request parameters**\\ VSCP_VEC_ADDR: Pointer to a vector of //struct vscp_vec// elements.\\ VSCP_VEC_SIZE: Number of elements in the given vector.
**return value**\\ OK: The call succeeded.\\ EDOM: Invalid number of vector elements.\\ EFAULT: Invalid address.\\ EINVAL: Invalid process number, or neither source nor destination is set to SELF.\\ EPERM: Invalid grant ID, insufficient access, or bad byte range.\\ ELOOP: Chain of indirect grants too long.
**remarks**\\ The operation does not fail atomically: Upon failure, the receiving buffers should be considered to be in an undefined state.
**library functions**\\ int sys_vsafecopy(struct vscp_vec *copyvec, int elements);
==== SYS_VTIMER ====
Set and/or retrieve the value of one of a process' virtual timers. Each process may have two virtual timers: a **virtual** timer that is decreased as the process itself executes (user time), and a **profile** timer that decreases as the process executes (user time) //or// a system server executes on behalf of the process (system time). If a timer expires, the process will get a SIGVTALRM or SIGPROF signal, respectively.
**request parameters**\\ VT_WHICH: The timer to set/retrieve: VT_VIRTUAL for the virtual timer, or VT_PROF for the profile timer.\\ VT_SET: A flag indicating whether to set, or just retrieve, the timer's value.\\ VT_VALUE: The new expiration time, if VT_SET is nonzero.\\ VT_ENDPT: Endpoint of the target process.
**response parameters**\\ VT_VALUE: The old expiration time.
**return value**\\ OK: The timer was set (if requested), and the old timer value was returned.\\ EPERM: User processes cannot request timers.\\ EINVAL: Invalid timer or process.
**library functions**\\ int sys_vtimer(endpoint_t proc_nr, int which, clock_t *newval, clock_t *oldval);
==== SYS_MEMSET ====
Fill a physical memory area with a constant pattern byte.
int sys_memset(endpoint_t who, unsigned long pattern, phys_bytes base, phys_bytes bytes);
The **sys_memset** function sets //length// bytes starting from physical address //base// to the low-order byte of //pattern//.
**Return values**:\\
OK: Call always succeeds.
**Notes**: \\
This function is used, for example, to zero the BSS segment on an exec() POSIX-call. The kernel is asked to do the work for performance reasons.
==== SYS_SAFEMEMSET ====
Fill a memory grant with a constant pattern byte.
int sys_safememset(endpoint_t endpt, cp_grant_id_t grant, vir_bytes grant_offset, int pattern, size_t bytes);
The **sys_safememset** function sets //bytes// bytes from offset //grant_offset// in memory grant //grant// to the low-order byte of //pattern//.
**Return values** (not complete):\\
OK: //bytes// bytes filled with the pattern byte.\\
EPERM: Caller has no write permissions (CPF_WRITE) for //grant//. \\
EPERM: Permission checks for //grant// failed. \\
**Notes:** \\
The memory driver uses this function for reads of /dev/zero to set a requestor's buffer to all '\0'.
==== SYS_VUMAP ====
Batch mapping of virtual to physical addresses.
int sys_vumap(endpoint_t endpt, struct vumap_vir *vvec, int vcount, size_t offset, int access, struct vumap_phys *pvec, int *pcount);
The **sys_vumap** function perform batch conversion of one or more virtual buffers, to a series of physical addresses for those buffers. It is intended to be used by drivers that want to perform DMA directly from or to buffers in another process, authorized by that other process by means of memory grants. It can also be used to look up local addresses in the calling processes itself.
The buffers to convert are provided in the //vvec// vector. Each entry in this vector contains either a grant identifier (//vv_grant//) or a local virtual address (//vv_addr//) for the buffer, and a size (//vv_size//) of the buffer. The owner of the buffer is specified using the //endpt// parameter; If //endpt// is set to SELF, the local virtual addresses are used; otherwise, the grant identifiers are used. The //vcount// parameter specifies the number of entries in the //vvec// vector. The caller must provide at least one entry. No more than ''MAPVEC_NR'' input entries are processed in one call.
The //offset// parameter determines the offset into the first entry of the //vvec// vector. This allows the caller to perform multiple **sys_vumap** calls to map input that exceeds the size limits for a single call. The offset affects both the address and the size of the first entry.
The //access// parameter specifies the access requested for the buffers. At least one of the following flags must be specified: ''VUA_READ'' (to read from the buffers), ''VUA_WRITE'' (to write to the buffers). If the ''VUA_READ'' flag is not set, any unallocated pages in the address range will be allocated automatically. If the ''VUA_READ'' flag is set, the caller must always provide allocated pages. The requested access must match that of the given grants, and thus acts as a sanity check; it however does not prevent the caller from performing DMA in the wrong direction on the resolved physical addresses.
The kernel stores the resulting physical addresses in the //pvec// vector. Each entry in this vector contains a physical address (//pv_addr//) and a size (//pv_size//). The caller must set the //pcount// integer to the maximum number of entries in the //pvec// vector; upon success, the variable will be set to the number of entries filled in by the kernel. The caller must provide at least one entry. Upon success, at least one and at most ''MAPVEC_NR'' output entries are returned. Upon failure, the //pvec// and //pcount// contents are unchanged.
The caller is encouraged not to pay too much attention to the returned //pcount// value for determining whether the entire input vector has been mapped. Instead, it should consider the sizes returned in the //pvec// entries. If the sum of the sizes in the //pvec// vector equals the sum of the sizes in the //vvec// vector, the entire virtual vector has been resolved. Otherwise, additional **sys_vumap** calls are necessary to resolve the rest of the virtual vector.
**Return values** (not complete):\\ OK: addresses successfully mapped\\ EINVAL: //vcount// or //pcount// is negative or zero\\ EINVAL: //access// contains neither ''VUA_READ'' nor ''VUA_WRITE''\\ EFAULT: //vvec// or //pvec// point to invalid memory\\ EINVAL: one of the entries in //vvec// is zero-sized\\ EINVAL: one of the grants in //vvec// is invalid\\ EPERM: one of the grants in //vvec// is revoked\\ EPERM: the requested access does not match the granted access\\ EFAULT: the memory provided in one of the //vvec// entries is invalid\\ EFAULT: ''VUA_READ'' access is specified, and part of the given memory is not allocated\\
----
===== References =====
~-[[http://www.minix3.org/doc/kernel-api.pdf|Original MINIX 3 Kernel API Document]] by Jorrit N. Herder jnhderder AT cs DOT vu DOT nl