Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 1 | .. _kernelobjects: |
| 2 | |
| 3 | Kernel Objects |
| 4 | ############## |
| 5 | |
| 6 | A kernel object can be one of three classes of data: |
| 7 | |
| 8 | * A core kernel object, such as a semaphore, thread, pipe, etc. |
Fabio Utzig | c79d2ce | 2020-08-20 14:29:47 -0300 | [diff] [blame] | 9 | * A thread stack, which is an array of :c:struct:`z_thread_stack_element` |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 10 | and declared with :c:macro:`K_THREAD_STACK_DEFINE()` |
Tomasz Bursztyka | c0bcfd2 | 2020-08-18 09:22:14 +0200 | [diff] [blame] | 11 | * A device driver instance (const struct device) that belongs to one of a defined |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 12 | set of subsystems |
| 13 | |
| 14 | The set of known kernel objects and driver subsystems is defined in |
Fabio Utzig | bb93b33 | 2020-08-11 14:03:00 -0300 | [diff] [blame] | 15 | include/kernel.h as :c:enum:`k_objects`. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 16 | |
| 17 | Kernel objects are completely opaque to user threads. User threads work |
| 18 | with addresses to kernel objects when making API calls, but may never |
| 19 | dereference these addresses, doing so will cause a memory protection fault. |
| 20 | All kernel objects must be placed in memory that is not accessible by |
| 21 | user threads. |
| 22 | |
| 23 | Since user threads may not directly manipulate kernel objects, all use of |
| 24 | them must go through system calls. In order to perform a system call on |
| 25 | a kernel object, checks are performed by system call handler functions |
| 26 | that the kernel object address is valid and that the calling thread |
| 27 | has sufficient permissions to work with it. |
| 28 | |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 29 | Permission on an object also has the semantics of a reference to an object. |
| 30 | This is significant for certain object APIs which do temporary allocations, |
| 31 | or objects which themselves have been allocated from a runtime memory pool. |
| 32 | |
| 33 | If an object loses all references, two events may happen: |
| 34 | |
| 35 | * If the object has an associated cleanup function, the cleanup function |
| 36 | may be called to release any runtime-allocated buffers the object was using. |
| 37 | |
| 38 | * If the object itself was dynamically allocated, the memory for the object |
| 39 | will be freed. |
| 40 | |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 41 | Object Placement |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 42 | **************** |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 43 | |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 44 | Kernel objects that are only used by supervisor threads have no restrictions |
| 45 | and can be located anywhere in the binary, or even declared on stacks. However, |
| 46 | to prevent accidental or intentional corruption by user threads, they must |
| 47 | not be located in any memory that user threads have direct access to. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 48 | |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 49 | In order for a static kernel object to be usable by a user thread via system |
| 50 | call APIs, several conditions must be met on how the kernel object is declared: |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 51 | |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 52 | * The object must be declared as a top-level global at build time, such that it |
| 53 | appears in the ELF symbol table. It is permitted to declare kernel objects |
David B. Kinder | 17299f0 | 2019-05-31 15:39:39 -0700 | [diff] [blame] | 54 | with static scope. The post-build script :ref:`gen_kobject_list.py` scans the |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 55 | generated ELF file to find kernel objects and places their memory addresses |
| 56 | in a special table of kernel object metadata. Kernel objects may be members |
| 57 | of arrays or embedded within other data structures. |
| 58 | |
Andrew Boie | 41f6011 | 2019-01-31 15:53:24 -0800 | [diff] [blame] | 59 | * Kernel objects must be located in memory reserved for the kernel. They |
| 60 | must not be located in any memory partitions that are user-accessible. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 61 | |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 62 | * Any memory reserved for a kernel object must be used exclusively for that |
| 63 | object. Kernel objects may not be members of a union data type. |
| 64 | |
| 65 | Kernel objects that are found but do not meet the above conditions will not be |
| 66 | included in the generated table that is used to validate kernel object pointers |
| 67 | passed in from user mode. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 68 | |
David B. Kinder | 17299f0 | 2019-05-31 15:39:39 -0700 | [diff] [blame] | 69 | The debug output of the :ref:`gen_kobject_list.py` script may be useful when |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 70 | debugging why some object was unexpectedly not being tracked. This |
| 71 | information will be printed if the script is run with the ``--verbose`` flag, |
| 72 | or if the build system is invoked with verbose output. |
| 73 | |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 74 | Dynamic Objects |
| 75 | *************** |
| 76 | |
| 77 | Kernel objects may also be allocated at runtime if |
Gerard Marull-Paretas | 260decc | 2022-02-07 17:27:43 +0100 | [diff] [blame] | 78 | :kconfig:option:`CONFIG_DYNAMIC_OBJECTS` is enabled. In this case, the |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 79 | :c:func:`k_object_alloc` API may be used to instantiate an object from |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 80 | the calling thread's resource pool. Such allocations may be freed in two |
| 81 | ways: |
| 82 | |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 83 | * Supervisor threads may call :c:func:`k_object_free` to force a dynamic |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 84 | object to be released. |
| 85 | |
| 86 | * If an object's references drop to zero (which happens when no threads have |
| 87 | permissions on it) the object will be automatically freed. User threads |
| 88 | may drop their own permission on an object with |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 89 | :c:func:`k_object_release`, and their permissions are automatically |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 90 | cleared when a thread terminates. Supervisor threads may additionally |
| 91 | revoke references for another thread using |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 92 | :c:func:`k_object_access_revoke`. |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 93 | |
| 94 | Because permissions are also used for reference counting, it is important for |
| 95 | supervisor threads to acquire permissions on objects they are using even though |
| 96 | the access control aspects of the permission system are not enforced. |
| 97 | |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 98 | Implementation Details |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 99 | ====================== |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 100 | |
David B. Kinder | 17299f0 | 2019-05-31 15:39:39 -0700 | [diff] [blame] | 101 | The :ref:`gen_kobject_list.py` script is a post-build step which finds all the |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 102 | valid kernel object instances in the binary. It accomplishes this by parsing |
| 103 | the DWARF debug information present in the generated ELF file for the kernel. |
| 104 | |
| 105 | Any instances of structs or arrays corresponding to kernel objects that meet |
| 106 | the object placement criteria will have their memory addresses placed in a |
| 107 | special perfect hash table of kernel objects generated by the 'gperf' tool. |
| 108 | When a system call is made and the kernel is presented with a memory address |
| 109 | of what may or may not be a valid kernel object, the address can be validated |
| 110 | with a constant-time lookup in this table. |
| 111 | |
Fabio Utzig | c79d2ce | 2020-08-20 14:29:47 -0300 | [diff] [blame] | 112 | Drivers are a special case. All drivers are instances of :c:struct:`device`, but |
Anas Nashif | 0ff33d1 | 2020-07-13 20:21:56 -0400 | [diff] [blame] | 113 | it is important to know what subsystem a driver belongs to so that |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 114 | incorrect operations, such as calling a UART API on a sensor driver object, can |
| 115 | be prevented. When a device struct is found, its API pointer is examined to |
| 116 | determine what subsystem the driver belongs to. |
| 117 | |
| 118 | The table itself maps kernel object memory addresses to instances of |
Fabio Utzig | c79d2ce | 2020-08-20 14:29:47 -0300 | [diff] [blame] | 119 | :c:struct:`z_object`, which has all the metadata for that object. This |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 120 | includes: |
| 121 | |
| 122 | * A bitfield indicating permissions on that object. All threads have a |
| 123 | numerical ID assigned to them at build time, used to index the permission |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 124 | bitfield for an object to see if that thread has permission on it. The size |
Gerard Marull-Paretas | 260decc | 2022-02-07 17:27:43 +0100 | [diff] [blame] | 125 | of this bitfield is controlled by the :kconfig:option:`CONFIG_MAX_THREAD_BYTES` |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 126 | option and the build system will generate an error if this value is too low. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 127 | * A type field indicating what kind of object this is, which is some |
Fabio Utzig | bb93b33 | 2020-08-11 14:03:00 -0300 | [diff] [blame] | 128 | instance of :c:enum:`k_objects`. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 129 | * A set of flags for that object. This is currently used to track |
| 130 | initialization state and whether an object is public or not. |
Andrew Boie | f2734ab | 2020-03-11 06:37:42 -0700 | [diff] [blame] | 131 | * An extra data field. The semantics of this field vary by object type, see |
Fabio Utzig | 43133c9 | 2020-08-12 09:36:01 -0300 | [diff] [blame] | 132 | the definition of :c:union:`z_object_data`. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 133 | |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 134 | Dynamic objects allocated at runtime are tracked in a runtime red/black tree |
| 135 | which is used in parallel to the gperf table when validating object pointers. |
| 136 | |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 137 | Supervisor Thread Access Permission |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 138 | *********************************** |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 139 | |
| 140 | Supervisor threads can access any kernel object. However, permissions for |
| 141 | supervisor threads are still tracked for two reasons: |
| 142 | |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 143 | * If a supervisor thread calls :c:func:`k_thread_user_mode_enter`, the |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 144 | thread will then run in user mode with any permissions it had been granted |
| 145 | (in many cases, by itself) when it was a supervisor thread. |
| 146 | |
| 147 | * If a supervisor thread creates a user thread with the |
| 148 | :c:macro:`K_INHERIT_PERMS` option, the child thread will be granted the |
| 149 | same permissions as the parent thread, except the parent thread object. |
| 150 | |
| 151 | User Thread Access Permission |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 152 | ***************************** |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 153 | |
| 154 | By default, when a user thread is created, it will only have access permissions |
| 155 | on its own thread object. Other kernel objects by default are not usable. |
| 156 | Access to them needs to be explicitly or implicitly granted. There are several |
| 157 | ways to do this. |
| 158 | |
| 159 | * If a thread is created with the :c:macro:`K_INHERIT_PERMS`, that thread |
| 160 | will inherit all the permissions of the parent thread, except the parent |
| 161 | thread object. |
| 162 | |
| 163 | * A thread that has permission on an object, or is running in supervisor mode, |
| 164 | may grant permission on that object to another thread via the |
Peter Bigot | cf01737 | 2020-11-21 12:01:26 -0600 | [diff] [blame] | 165 | :c:func:`k_object_access_grant` API. The convenience pseudo-function |
| 166 | :c:func:`k_thread_access_grant` may also be used, which accepts an arbitrary |
| 167 | number of pointers to kernel objects and calls |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 168 | :c:func:`k_object_access_grant` on each of them. The thread being granted |
Peter Bigot | cf01737 | 2020-11-21 12:01:26 -0600 | [diff] [blame] | 169 | permission, or the object whose access is being granted, do not need to be |
| 170 | in an initialized state. If the caller is from user mode, the caller must |
| 171 | have permissions on both the kernel object and the target thread object. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 172 | |
| 173 | * Supervisor threads may declare a particular kernel object to be a public |
| 174 | object, usable by all current and future threads with the |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 175 | :c:func:`k_object_access_all_grant` API. You must assume that any |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 176 | untrusted or exploited code will then be able to access the object. Use |
| 177 | this API with caution! |
| 178 | |
| 179 | * If a thread was declared statically with :c:macro:`K_THREAD_DEFINE()`, |
| 180 | then the :c:macro:`K_THREAD_ACCESS_GRANT()` may be used to grant that thread |
| 181 | access to a set of kernel objects at boot time. |
| 182 | |
| 183 | Once a thread has been granted access to an object, such access may be |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 184 | removed with the :c:func:`k_object_access_revoke` API. This API is not |
Andrew Boie | e9cfc54 | 2018-04-13 13:15:28 -0700 | [diff] [blame] | 185 | available to user threads, however user threads may use |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 186 | :c:func:`k_object_release` to relinquish their own permissions on an |
Andrew Boie | e9cfc54 | 2018-04-13 13:15:28 -0700 | [diff] [blame] | 187 | object. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 188 | |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 189 | API calls from supervisor mode to set permissions on kernel objects that are |
| 190 | not being tracked by the kernel will be no-ops. Doing the same from user mode |
| 191 | will result in a fatal error for the calling thread. |
| 192 | |
Fabio Utzig | 53fd5ff | 2020-08-24 11:35:45 -0300 | [diff] [blame] | 193 | Objects allocated with :c:func:`k_object_alloc` implicitly grant |
Andrew Boie | 97bf001 | 2018-04-24 17:01:37 -0700 | [diff] [blame] | 194 | permission on the allocated object to the calling thread. |
| 195 | |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 196 | Initialization State |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 197 | ******************** |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 198 | |
| 199 | Most operations on kernel objects will fail if the object is considered to be |
| 200 | in an uninitialized state. The appropriate init function for the object must |
| 201 | be performed first. |
| 202 | |
| 203 | Some objects will be implicitly initialized at boot: |
| 204 | |
| 205 | * Kernel objects that were declared with static initialization macros |
| 206 | (such as :c:macro:`K_SEM_DEFINE` for semaphores) will be in an initialized |
| 207 | state at build time. |
| 208 | |
| 209 | * Device driver objects are considered initialized after their init function |
| 210 | is run by the kernel early in the boot process. |
| 211 | |
Andrew Boie | ae8acff | 2020-03-11 07:19:16 -0700 | [diff] [blame] | 212 | If a kernel object is initialized with a private static initializer, the object |
Anas Nashif | c91cad7 | 2023-09-26 21:32:13 +0000 | [diff] [blame] | 213 | must have :c:func:`k_object_init` called on it at some point by a supervisor |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 214 | thread, otherwise the kernel will consider the object uninitialized if accessed |
| 215 | by a user thread. This is very uncommon, typically only for kernel objects that |
| 216 | are embedded within some larger struct and initialized statically. |
| 217 | |
| 218 | .. code-block:: c |
| 219 | |
| 220 | struct foo { |
| 221 | struct k_sem sem; |
| 222 | ... |
| 223 | }; |
| 224 | |
Andrew Boie | 41f6011 | 2019-01-31 15:53:24 -0800 | [diff] [blame] | 225 | struct foo my_foo = { |
Anas Nashif | 45a1d8a | 2020-04-24 11:29:17 -0400 | [diff] [blame] | 226 | .sem = Z_SEM_INITIALIZER(my_foo.sem, 0, 1), |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 227 | ... |
| 228 | }; |
| 229 | |
| 230 | ... |
Anas Nashif | c91cad7 | 2023-09-26 21:32:13 +0000 | [diff] [blame] | 231 | k_object_init(&my_foo.sem); |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 232 | ... |
| 233 | |
| 234 | |
| 235 | Creating New Kernel Object Types |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 236 | ******************************** |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 237 | |
| 238 | When implementing new kernel features or driver subsystems, it may be necessary |
| 239 | to define some new kernel object types. There are different steps needed |
| 240 | for creating core kernel objects and new driver subsystems. |
| 241 | |
| 242 | Creating New Core Kernel Objects |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 243 | ================================ |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 244 | |
Anas Nashif | efbadbb | 2022-07-11 10:53:29 -0400 | [diff] [blame] | 245 | * In ``scripts/build/gen_kobject_list.py``, add the name of the struct to the |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 246 | :py:data:`kobjects` list. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 247 | |
| 248 | Instances of the new struct should now be tracked. |
| 249 | |
| 250 | Creating New Driver Subsystem Kernel Objects |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 251 | ============================================ |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 252 | |
Fabio Utzig | c79d2ce | 2020-08-20 14:29:47 -0300 | [diff] [blame] | 253 | All driver instances are :c:struct:`device`. They are differentiated by |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 254 | what API struct they are set to. |
| 255 | |
Anas Nashif | efbadbb | 2022-07-11 10:53:29 -0400 | [diff] [blame] | 256 | * In ``scripts/build/gen_kobject_list.py``, add the name of the API struct for the |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 257 | new subsystem to the :py:data:`subsystems` list. |
Andrew Boie | 2d2a97b | 2017-11-01 14:40:46 -0700 | [diff] [blame] | 258 | |
| 259 | Driver instances of the new subsystem should now be tracked. |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 260 | |
| 261 | Configuration Options |
David B. Kinder | ec1b1df | 2018-02-01 16:06:21 -0800 | [diff] [blame] | 262 | ********************* |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 263 | |
| 264 | Related configuration options: |
| 265 | |
Gerard Marull-Paretas | 260decc | 2022-02-07 17:27:43 +0100 | [diff] [blame] | 266 | * :kconfig:option:`CONFIG_USERSPACE` |
| 267 | * :kconfig:option:`CONFIG_MAX_THREAD_BYTES` |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 268 | |
Anas Nashif | 4bcb294 | 2019-01-23 23:06:29 -0500 | [diff] [blame] | 269 | API Reference |
| 270 | ************* |
Andrew Boie | 8bffcda | 2017-11-08 11:26:55 -0800 | [diff] [blame] | 271 | |
Anas Nashif | 4bcb294 | 2019-01-23 23:06:29 -0500 | [diff] [blame] | 272 | .. doxygengroup:: usermode_apis |