-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdesign-notes.txt
89 lines (78 loc) · 4.38 KB
/
design-notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Types of page files:
- Files in memory (page cache)
- RAM disk files
- Shared and anonymous memory, backed by swap device
-----
=== Kernel Objects, Capabilities and Memory Allocation ===
Userspace refers to kernel objects and other kernels resources through
descriptors. Each descriptor contains a reference to a kernel resource as well
as a set of permissions on this resource (i.e. it is a capability). Userspace
performs operations on kernel resources through an appropriate descriptor.
Descriptors are specified in the form of an integer, just like Unix file
descriptors.
In addition to being used to perform operations on kernel resources, descriptors
can also be passed to other processes in an IPC message (TBD map vs grant).
Kernel resources can be:
- Memory management:
- A block of physical memory (RAM).
- A page of kernel virtual memory.
- An array to manage a block of kernel virtual memory (one page).
- A slab for allocating kernel objects (one page virtual+physical)
- Capabilities
- A capability
- An array of capability slots (one page virtual+physical)
- An array of pointers to a capability slot array (one page virtual+physical)
- A small array of pointers to a capability slot array (~64 bytes on a slab)
- A small second-level array of pointers (~64 bytes on a slab)
- (TBD) Some sort of L4-style parallel page table structure for memory map
operations.
- Address space management:
- A page table (one page physical only)
- A page directory (one page physical only)
- A PDPT (32 bytes on a slab)
- An IPC endpoint (on slab).
- A thread control block and associated kernel stack and IPC buffer (one page
virtual+physical)
- A process control block (on slab + initial page tables/directory/PDPT).
- (TBD) A process virtual memory region
- (TBD) An IPC buffer for an interrupt or other microkernel-generated message
- (TBD) A synchronization kernel object (mutex, semaphore, monitor, etc.)
- (TBD) An I/O port range
During initialization, the microkernel creates descriptors for all initial
resources (memory, kernel objects, etc.) which it passes to the initial process
(TBD how?).
After initialization is complete, the microkernel never allocates resources
on its own. All resources (e.g. kernel objects) are created by a system call,
and userspace must provide the resources on which it depends (e.g. a memory page).
These allocation system calls can be seen as transforming resources into other
resources, e.g.:
1 physical memory page + 1 kernel virtual page
|
| system call
v
Allocation rights for X IPC endpoints (the system call creates a slab)
|
| system call
v
1 IPC endpoint + Allocation rights for X - 1 IPC endpoints
As in the example above, some descriptors represent allocation right for kernel
objects. These are "counted descriptors", meaning they contain a counter with
the number of objects that can be allocated, and this counter is decremented on
each object allocation. Counted descriptors can be split, and counted
descriptors for identical resources can be merged, both through system calls.
For example, an application that has an allocation right for X > 4 IPC endpoints
can issue a system call to convert it to an allocation right for 4 IPC endpoints
and another allocation right for X - 4 IPC endpoints. It can then pass the
allocation right for the 4 IPC endpoints to another process through an IPC and
keep the rest.
A memory descriptor refers to a block of 2**N pages of physical memory (RAM)
aligned on a 2**N page boundary. A descriptor for such a block of 2**N pages can
be converted (i.e. split) into two blocks of 2**(N-1) pages through a system
call. Similarly, the two resulting descriptors can be converted back (i.e.
merged) into a 2**N-page block. Only the two blocks that were initially part of
a single block (i.e. buddies) can be merged together.
Just like for other resource types, the microkernel creates a list of memory
descriptors from the available physical memory map during initialization and
provides these descriptors to the initial process (TBD how?). No descriptor is
created for any memory allocated to the kernel itself during initialization,
which ensures userspace cannot access kernel memory.