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