1# Zircon Kernel Concepts 2 3## Introduction 4 5The kernel manages a number of different types of Objects. Those which are 6accessible directly via system calls are C++ classes which implement the 7Dispatcher interface. These are implemented in 8[kernel/object](../kernel/object). Many are self-contained higher-level Objects. 9Some wrap lower-level lk primitives. 10 11## [System Calls](syscalls.md) 12 13Userspace code interacts with kernel objects via system calls, and almost exclusively 14via Handles. In userspace, a Handle is represented as 32bit integer 15(type zx_handle_t). When syscalls are executed, the kernel checks that Handle 16parameters refer to an actual handle that exists within the calling process's handle 17table. The kernel further checks that the Handle is of the correct type (passing 18a Thread Handle to a syscall requiring an event handle will result in an error), 19and that the Handle has the required Rights for the requested operation. 20 21System calls fall into three broad categories, from an access standpoint: 22 231. Calls which have no limitations, of which there are only a very few, for 24example [*zx_clock_get()*](syscalls/clock_get.md) 25and [*zx_nanosleep()*](syscalls/nanosleep.md) may be called by any thread. 262. Calls which take a Handle as the first parameter, denoting the Object they act upon, 27which are the vast majority, for example [*zx_channel_write()*](syscalls/channel_write.md) 28and [*zx_port_queue()*](syscalls/port_queue.md). 293. Calls which create new Objects but do not take a Handle, such as 30[*zx_event_create()*](syscalls/event_create.md) and 31[*zx_channel_create()*](syscalls/channel_create.md). Access to these (and limitations 32upon them) is controlled by the Job in which the calling Process is contained. 33 34System calls are provided by libzircon.so, which is a "virtual" shared 35library that the Zircon kernel provides to userspace, better known as the 36[*virtual Dynamic Shared Object* or vDSO](vdso.md). 37They are C ELF ABI functions of the form *zx_noun_verb()* or 38*zx_noun_verb_direct-object()*. 39 40The system calls are defined by [syscalls.abigen](../system/public/zircon/syscalls.abigen) 41and processed by the [abigen](../system/host/abigen/) tool into include files and glue 42code in libzircon and the kernel's libsyscalls. 43 44 45## [Handles](handles.md) and [Rights](rights.md) 46 47Objects may have multiple Handles (in one or more Processes) that refer to them. 48 49For almost all Objects, when the last open Handle that refers to an Object is closed, 50the Object is either destroyed, or put into a final state that may not be undone. 51 52Handles may be moved from one Process to another by writing them into a Channel 53(using [*zx_channel_write()*](syscalls/channel_write.md)), or by using 54[*zx_process_start()*](syscalls/process_start.md) to pass a Handle as the argument 55of the first thread in a new Process. 56 57The actions which may be taken on a Handle or the Object it refers to are governed 58by the Rights associated with that Handle. Two Handles that refer to the same Object 59may have different Rights. 60 61The [*zx_handle_duplicate()*](syscalls/handle_duplicate.md) and 62[*zx_handle_replace()*](syscalls/handle_replace.md) system calls may be used to 63obtain additional Handles referring to the same Object as the Handle passed in, 64optionally with reduced Rights. The [*zx_handle_close()*](syscalls/handle_close.md) 65system call closes a Handle, releasing the Object it refers to, if that Handle is 66the last one for that Object. The [*zx_handle_close_many()*](syscalls/handle_close_many.md) 67system call similarly closes an array of handles. 68 69 70## Kernel Object IDs 71 72Every object in the kernel has a "kernel object id" or "koid" for short. 73It is a 64 bit unsigned integer that can be used to identify the object 74and is unique for the lifetime of the running system. 75This means in particular that koids are never reused. 76 77There are two special koid values: 78 79*ZX_KOID_INVALID* Has the value zero and is used as a "null" sentinel. 80 81*ZX_KOID_KERNEL* There is only one kernel, and it has its own koid. 82 83 84## Running Code: Jobs, Processes, and Threads. 85 86Threads represent threads of execution (CPU registers, stack, etc) within an 87address space which is owned by the Process in which they exist. Processes are 88owned by Jobs, which define various resource limitations. Jobs are owned by 89parent Jobs, all the way up to the Root Job which was created by the kernel at 90boot and passed to [`userboot`, the first userspace Process to begin execution](userboot.md). 91 92Without a Job Handle, it is not possible for a Thread within a Process to create another 93Process or another Job. 94 95[Program loading](program_loading.md) is provided by userspace facilities and 96protocols above the kernel layer. 97 98See: [process_create](syscalls/process_create.md), 99[process_start](syscalls/process_start.md), 100[thread_create](syscalls/thread_create.md), 101and [thread_start](syscalls/thread_start.md). 102 103 104## Message Passing: Sockets and Channels 105 106Both Sockets and Channels are IPC Objects which are bi-directional and two-ended. 107Creating a Socket or a Channel will return two Handles, one referring to each endpoint 108of the Object. 109 110Sockets are stream-oriented and data may be written into or read out of them in units 111of one or more bytes. Short writes (if the Socket's buffers are full) and short reads 112(if more data is requested than in the buffers) are possible. 113 114Channels are datagram-oriented and have a maximum message size of 64K (subject to change, 115likely to be smaller) and may also have up to 1024 Handles attached to a message (also 116subject to change, also likely to be smaller). They do not support short reads or writes -- 117either a message fits or it does not. 118 119When Handles are written into a Channel, they are removed from the sending Process. 120When a message with Handles is read from a Channel, the Handles are added to the receiving 121Process. Between these two events, the Handles continue to exist (ensuring the Objects 122they refer to continue to exist), unless the end of the Channel which they have been written 123towards is closed -- at which point messages in flight to that endpoint are discarded and 124any Handles they contained are closed. 125 126See: [channel_create](syscalls/channel_create.md), 127[channel_read](syscalls/channel_read.md), 128[channel_write](syscalls/channel_write.md), 129[channel_call](syscalls/channel_call.md), 130[socket_create](syscalls/socket_create.md), 131[socket_read](syscalls/socket_read.md), 132and [socket_write](syscalls/socket_write.md). 133 134## Objects and Signals 135 136Objects may have up to 32 signals (represented by the zx_signals_t type and the ZX_*_SIGNAL_* 137defines) which represent a piece of information about their current state. Channels and Sockets, 138for example, may be READABLE or WRITABLE. Processes or Threads may be TERMINATED. And so on. 139 140Threads may wait for signals to become active on one or more Objects. 141 142See [signals](signals.md) for more information. 143 144## Waiting: Wait One, Wait Many, and Ports 145 146A Thread may use [*zx_object_wait_one()*](syscalls/object_wait_one.md) 147to wait for a signal to be active on a single handle or 148[*zx_object_wait_many()*](syscalls/object_wait_many.md) to wait for 149signals on multiple handles. Both calls allow for a timeout after 150which they'll return even if no signals are pending. 151 152If a Thread is going to wait on a large set of handles, it is more efficient to use 153a Port, which is an Object that other Objects may be bound to such that when signals 154are asserted on them, the Port receives a packet containing information about the 155pending Signals. 156 157See: [port_create](syscalls/port_create.md), 158[port_queue](syscalls/port_queue.md), 159[port_wait](syscalls/port_wait.md), 160[port_cancel](syscalls/port_cancel.md). 161 162 163## Events, Event Pairs. 164 165An Event is the simplest Object, having no other state than its collection of active Signals. 166 167An Event Pair is one of a pair of Events that may signal each other. A useful property of 168Event Pairs is that when one side of a pair goes away (all Handles to it have been 169closed), the PEER_CLOSED signal is asserted on the other side. 170 171See: [event_create](syscalls/event_create.md), 172and [eventpair_create](syscalls/eventpair_create.md). 173 174 175## Shared Memory: Virtual Memory Objects (VMOs) 176 177Virtual Memory Objects represent a set of physical pages of memory, or the *potential* 178for pages (which will be created/filled lazily, on-demand). 179 180They may be mapped into the address space of a Process with 181[*zx_vmar_map()*](syscalls/vmar_map.md) and unmapped with 182[*zx_vmar_unmap()*](syscalls/vmar_unmap.md). Permissions of 183mapped pages may be adjusted with [*zx_vmar_protect()*](syscalls/vmar_protect.md). 184 185VMOs may also be read from and written to directly with 186[*zx_vmo_read()*](syscalls/vmo_read.md) and [*zx_vmo_write()*](syscalls/vmo_write.md). 187Thus the cost of mapping them into an address space may be avoided for one-shot operations 188like "create a VMO, write a dataset into it, and hand it to another Process to use." 189 190## Address Space Management 191 192Virtual Memory Address Regions (VMARs) provide an abstraction for managing a 193process's address space. At process creation time, a handle to the root VMAR 194is given to the process creator. That handle refers to a VMAR that spans the 195entire address space. This space can be carved up via the 196[*zx_vmar_map()*](syscalls/vmar_map.md) and 197[*zx_vmar_allocate()*](syscalls/vmar_allocate.md) interfaces. 198[*zx_vmar_allocate()*](syscalls/vmar_allocate.md) can be used to generate new 199VMARs (called subregions or children) which can be used to group together 200parts of the address space. 201 202See: [vmar_map](syscalls/vmar_map.md), 203[vmar_allocate](syscalls/vmar_allocate.md), 204[vmar_protect](syscalls/vmar_protect.md), 205[vmar_unmap](syscalls/vmar_unmap.md), 206[vmar_destroy](syscalls/vmar_destroy.md), 207 208## Futexes 209 210Futexes are kernel primitives used with userspace atomic operations to implement 211efficient synchronization primitives -- for example, Mutexes which only need to make 212a syscall in the contended case. Usually they are only of interest to implementers of 213standard libraries. Zircon's libc and libc++ provide C11, C++, and pthread APIs for 214mutexes, condition variables, etc, implemented in terms of Futexes. 215 216See: [futex_wait](syscalls/futex_wait.md), 217[futex_wake](syscalls/futex_wake.md), 218[futex_requeue](syscalls/futex_requeue.md). 219