Followed the kernel physical memory reservation convention
with devices. Devices that are possessable by userspace
are created as boot-time capabilities and placed under the kernel
resources devmem_free capability list. Any userspace container
that is defined with the possession of the device would delete the
device capability making it unavailable to further requests.
Each container was taking up more than 3KB of space at boot-time structures
This was due to having 4 pagers and 32 boot-time capabilities for each. This
caused the boot-time kernel size to vary a lot with capabilities. The new
numbers are optimum.
Particularly we always have a single pager per container, even though the
array structures allow more. Single pager makes container-wide privileges
and management simpler.
Thread ids now contain their container ids in the top 2 nibbles.
Threads on other containers can be addressed by changing those
two nibbles. The addressing of inter-container threads are
subject to capabilities.
We still have to have the pager structs because they possess intermediate
data during boot up such as for transferring of capability lists to
boot stack one-by-one, and then to newly generated ktcbs.
Capabilities will be shared among collection of threads. A pager
will have a right to share its own capabilities with its space,
its thread group and its container.
Currently sharing is possible with only all of the caps. Next,
it will be support for cap splitting, granting, and partial sharing
and granting.
It makes more sense to have a scheduler (or runqueue pair) per-cpu
rather than per-container. This provides more flexible global scheduling
policy that is also simpler due to all scheduling details being controlled
from a single point.