NOVA User-Level Environment  Version testbox/changed-memory-timing-317-g320d8b5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
4.1 Sigma0 - Partition Manager

4.1.1 Basic operation

Sigma0 is the root task (i.e. it runs in a root protection domain and it is the first task run by the hypervisor). Its initialization is controlled by command line parameters. Every parameter basically describe the operations to be performed on startup. In Sigma0 sources, every parameter is defined with PARAM_HANDLER() macro. Its first argument is the name of the parameter, the second argument is the code to be performed when the parameter is encountered in the script and the rest of arguments are lines of the help text.

After all parameters are processed, the main thread blocks and Sigma0 is controlled only through inter-process communication (IPC).

4.1.2 Provided services

4.1.3 Entry point

The entry point of sigma0 is the symbol start, which is defined to be the same as static method Sigma0::start() in sigma0.cc. This function is called from program.h, which defines __start symbol (an entry point defined in the linker script).

4.1.4 Memory management

Sigma0 class inherits _free_virt members, which is a region list used to manage free virtual memory for later delegation to children. Initially, all memory is put into this list.

4.1.5 Memory mapping

Memory mapping is only possible during IPC. Therefore, to map the memory from hypervisor sigma0 calls itself through "echo portal". This is implemented in map_self() method. The actual mapping is performed by hypervisor during reply to the echo call. It cannot be done during the call, because utcb->crd of receiving thread must correspond the mapping and the caller cannot easily manipulate utcb->crd of the receiving thread.

4.1.6 Memory allocation

Memory allocations (operator new) is implemented in library called service (file simplemalloc.cc). The implementation simply calls the function pointed out by memalloc pointer, whose value defaults to memalloc_mempool().

Sigma0 uses a more sofisticated memory allocator defined in sigma0_memalloc(). It allocates physical memory by consulting _free_phys region list and then maps the memory to its address space.

Memory freeing (memfree pointer) is not currently implemented.

At some places, NUL uses an uncommon new syntax, e.g.:

new (0x1000) char[0x1000]

The parameters in parentheses after new are passed as additional parameters to the overloaded operator new. In case of NUL, the additional parameter specifies the alignment of the memory block.

4.1.7 Portals

Portal wrapper functions cannot be greped - they are defined with PT_FUNC() or PT_FUNC_NORETURN() macros.

4.1.8 Capability selector allocation

TODO How are capability selectors allocated?

Capability indicesUse
0 – 0x10000reserved by program.h
0xffparent id - parent identifies us by translation of this capability to its PD
0x100 – 0x1ffMAC_CPUS??? - new parent protocol.
0x200semaphore to block the main thread after initialization is done
0x10000 – 0xffffffff(CLIENT_PT_OFFSET, CLIENT_PT_ORDER)

The following is the excerpt from a boot log on a 2-CPU system sorted by the capability selector (idx*). Note that these events are not normally logged; these messages were only added for the purpose of this list. It lists the objects created in sigma0, their selectors and other parameters. Memory mapping selectors are not included in this list.

nova_create_pt(idx_pt=0x00000100, idx_ec=0x00000227, eip=0x0040c7a8, mtd=0x00000000, dstpd=0x00000020) // parent portal CPU0
nova_create_pt(idx_pt=0x00000101, idx_ec=0x0000024e, eip=0x0040c7a8, mtd=0x00000000, dstpd=0x00000020) // parent portal CPU1
nova_create_sm(idx_sm=0x00000200, initial=0, dstpd=0x00000020) // _cap_block (program.h)
nova_create_sm(idx_sm=0x00000201, initial=0, dstpd=0x00000020) // _lock_gsi
nova_create_sm(idx_sm=0x00000202, initial=0, dstpd=0x00000020) // _lock_mem
nova_create_ec(idx_ec=0x00000203, utcb=0x3fe000, esp=0x43dff4, cpunr=0, excpt_base=0x00000000, dstpd=0x00000020) // do_map portal
// Exception handling portals CPU0
nova_create_pt(idx_pt=0x00000204, idx_ec=0x00000203, eip=0x0041128a, mtd=0x00000000, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000205, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000206, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000207, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000208, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000209, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020a, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020b, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020c, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020d, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020e, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000020f, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000210, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000211, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000212, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000213, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000214, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000215, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000216, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000217, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000218, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000219, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021a, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021b, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021c, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021d, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021e, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000021f, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000220, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000221, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000222, idx_ec=0x00000203, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000223, idx_ec=0x00000203, eip=0x00408755, mtd=0x0000000c, dstpd=0x00000020) // do_thread_startup
nova_create_ec(idx_ec=0x00000225, utcb=0x3fb000, esp=0x43cff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020) // ec_echo
nova_create_ec(idx_ec=0x00000227, utcb=0x3f8000, esp=0x43bff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sm(idx_sm=0x00000229, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x0000022a, utcb=0x2fc000, esp=0x2faff4, cpunr=1, excpt_base=0x00000000, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000022b, idx_ec=0x0000022a, eip=0x0041128a, mtd=0x00000000, dstpd=0x00000020)
// Exception handling portals CPU1
nova_create_pt(idx_pt=0x0000022c, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000022d, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000022e, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000022f, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000230, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000231, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000232, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000233, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000234, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000235, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000236, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000237, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000238, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000239, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023a, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023b, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023c, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023d, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023e, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000023f, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000240, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000241, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000242, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000243, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000244, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000245, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000246, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000247, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000248, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000249, idx_ec=0x0000022a, eip=0x00408d78, mtd=0x000effff, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000024a, idx_ec=0x0000022a, eip=0x00408755, mtd=0x0000000c, dstpd=0x00000020) // do_thread_startup
nova_create_ec(idx_ec=0x0000024c, utcb=0x2f8000, esp=0x2f6ff4, cpunr=1, excpt_base=0x0000022c, dstpd=0x00000020)
nova_create_ec(idx_ec=0x0000024e, utcb=0x2f4000, esp=0x2f2ff4, cpunr=1, excpt_base=0x0000022c, dstpd=0x00000020)
nova_create_sm(idx_sm=0x00000250, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000251, utcb=0x2e9000, esp=0xbfbf6ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000252, idx_ec=0x00000251, eip=0x00402bfe, mtd=0x00000000, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000253, utcb=0x2e6000, esp=0xbfbf5ff4, cpunr=1, excpt_base=0x0000022c, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000254, idx_ec=0x00000253, eip=0x00402bfe, mtd=0x00000000, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000255, utcb=0x2e3000, esp=0xbfbf3ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000256, idx_ec=0x00000255, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000257, utcb=0x2e0000, esp=0xbfbf1ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000258, idx_ec=0x00000257, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000259, utcb=0x2dd000, esp=0xbfbf0ff4, cpunr=1, excpt_base=0x0000022c, dstpd=0x00000020)
nova_create_sc(idx_sc=0x0000025a, idx_ec=0x00000259, dstpd=0x00000020)
nova_create_ec(idx_ec=0x0000025c, utcb=0x2da000, esp=0xbfbeeff4, cpunr=0, excpt_base=0x00000000, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000025d, idx_ec=0x0000025c, eip=0x004045e6, mtd=0x00000000, dstpd=0x00000020)
nova_create_sm(idx_sm=0x0000025f, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000261, utcb=0x2d7000, esp=0xbfbecff4, cpunr=1, excpt_base=0x00000000, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000262, idx_ec=0x00000261, eip=0x004045e6, mtd=0x00000000, dstpd=0x00000020)
nova_create_sm(idx_sm=0x00000264, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000267, utcb=0x2d4000, esp=0xbfbe9ff4, cpunr=0, excpt_base=0x000fefe0, dstpd=0x00000020)
nova_create_pt(idx_pt=0x00000268, idx_ec=0x00000267, eip=0x00401b21, mtd=0x00000000, dstpd=0x00000020)
nova_create_sm(idx_sm=0x00000269, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x0000026b, utcb=0x2d1000, esp=0xbfbe7ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_ec(idx_ec=0x0000026c, utcb=0x2ce000, esp=0xbfbe6ff4, cpunr=1, excpt_base=0x000fefe4, dstpd=0x00000020)
nova_create_pt(idx_pt=0x0000026d, idx_ec=0x0000026c, eip=0x00401b21, mtd=0x00000000, dstpd=0x00000020)
nova_create_sm(idx_sm=0x0000026e, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000270, utcb=0x2cb000, esp=0xbfbe4ff4, cpunr=1, excpt_base=0x0000022c, dstpd=0x00000020)
nova_create_sm(idx_sm=0x00000271, initial=0, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000272, utcb=0x2c8000, esp=0xbfbd4ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000273, idx_ec=0x00000272, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000274, utcb=0x2c5000, esp=0xbfbd2ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000275, idx_ec=0x00000274, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000276, utcb=0x2c2000, esp=0xbfbd0ff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000277, idx_ec=0x00000276, dstpd=0x00000020)
nova_create_ec(idx_ec=0x00000278, utcb=0x2bf000, esp=0xbfbcfff4, cpunr=0, excpt_base=0x00000205, dstpd=0x00000020)
nova_create_sc(idx_sc=0x00000279, idx_ec=0x00000278, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000100ff, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000fefd7, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000fefdc, initial=0, dstpd=0x00000020)
nova_create_pt(idx_pt=0x000fefee, idx_ec=0x0000026b, eip=0x004016dd, mtd=0x0000800f, dstpd=0x00000020)
nova_create_pt(idx_pt=0x000feff2, idx_ec=0x00000270, eip=0x004016dd, mtd=0x0000800f, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000ff000, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000ff001, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000ff002, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000ff003, initial=0, dstpd=0x00000020)
nova_create_sm(idx_sm=0x000ff005, initial=0, dstpd=0x00000020)

4.1.9 Communication between various parts of Sigma0

The communication is currently handled by means of "devices" interconnected via various "buses". Sigma0 is also a "device". Currently, all the devices live in a single address space and therefore the bus simply pass the messages (sent by calling send_*() method) to receiving devices by calling receive() method of all devices on the bus.

Technically, the receive() methods are called by static methods inherited from StaticReceiver class template. This template generates static methods receive_static() which simply call normal member functions receive(). There might be several of these functions differentiated by the type of the message.

4.1.9.1 Communication diagram

The diagram below tries to express interconnection between the devices (ellipses) and the buses (rectangles). It was created semi-automatically so there might be some inaccuracies. The connections of bus_hostop and bus_hwioin/out were intentionally not included because almost every devices sends the messages there. dot

nova_com.png

4.1.10 TimerService

TimerService is a service that provides timers and time functionality to its clients. It currently runs within Sigma0, but it is planned to run in its own protection domain.

It listens on portal to perform requests from clients. The main services provided are OPEN, REQUEST_TIMER, REQUEST_TIME and CLONE. OPEN operation creates a semaphore which is shared with the client. This semaphore is signaled when a timer, set up with REQUEST_TIMER, fires.

TimerService internally uses motherboard and buses _mymb), similarly as Sigma0, but these seem not to be used for anything useful.

dot

timer_service.png

4.1.11 HostKeyboard

This driver handles keyboard (and probably even mouse) IRQs, translates the scancodes somehow and sends MessageInput messages to bus_input.

The HostKeyboard 0 is special in that it allows switching consoles and reboot host and guest systems. The HostKeyboard 0 is initialized by the following SIgma0 parameter:

hostkeyb:0,0x60,1

4.1.12 Console

I do not yet fully understand how console works, but it seems it might be like this:

The actual virtual consoles are implemented in HostVga. A virtual console is a set of views and the view seems to be basically a bunch of VGA and VGA memory. The emulations seems to provide both text and graphical modes. HostVga worker thread periodically (25Hz) updates the real VGA with the content of the currently selected view.

TODO How is console attached to other protection domains? What is exactly bus_console used to.

4.1.13 HostVga

Listens for MessageInput and uses this for switching the consoles.

4.1.14 Starting programs

Starting of programs other than Sigma0 (let us call them children) is controlled by configuration scripts (text files with .nulconfig extension). The scripts have to be loaded by the bootloader into the memory. Programs can be started either automatically by using script and script_start:<num>:1 Sigma0 parameters or manually by keyboard shortcuts (by default LWin+<num>). The number <num> refers to the num-th .nulconfig script.

The actual spawning of the program is implemented in Sigma0::_start_config(). It involves the following steps:

  1. Allocation of memory and copying the executable to that memory.
  2. Allocation of a console for the new program
  3. Preparation of a new Hypervisor Information Page (HIP) for the program.
  4. Creation of exception handling portals (page-fault and startup).

The portal capability selectors are allocated in the range basebase + 0x400. The base is calculated as CLIENT_PT_OFFSET + (<num>-1)*(1<<CLIENT_PT_SHIFT), i.e. for the first client the range is equal to 0x10000 - 0x10400.

  1. Creation of parent protocol portals, one per CPU, staring at base + 0x100.
  2. Creation of a semaphore, that is used for later identification of the client. The capability selector for this semaphore is base + 0xfd.
  3. Creation of client protection domain, execution context and scheduling context (through 3.7 Admission service).

During the protection domain creation the capabilities in the range described above (base through base + 0x10400) are delegated to the client where they occupy selectors from 0x0 to 0x400. Therefore, the child knows implicitely how to contact the parent and how to idetify itself to the parent (see parent protocol).

4.1.14.1 State of a program after startup

SelectorSymbolCapability
0x00EPage fault handling portal (handled in Sigma0)
0x01EStartup exception handling portal (handled in Sigma0)
0x020NOVA_DEFAULT_PD_CAPChild protection domain
0x0FFParentProtocol::nilIdentifier (a semaphore) the parent uses to distinguish between clients
0x100, 0x101, ...ParentProtocol::nilPer-CPU portals for calling the parent using a [[parent protocol]].

4.1.14.2 Controlling the startup

  • sigma0::cpu specifies the CPU where to create the new program.
  • sigma0::dma TODO

4.1.15 Interrupt handling

TODO