The SPIN run_program routine is in SpinProgram.c . From the SPIN core perspective, the job of run_program is to prepare for the M3 allocation and garbage collection services. It allocates and map memory for the traced heap, captures the stack pointer and kicks off the Modula-3 runtime.
RTLinker initializes the runtime and calls all the mainbodies of the modules in the system. The SPIN modified RTLinker first initializes all of the runtime and spin core services. Then RTLinker runs all mainbodies and these mainbodies can use all runtime and SPIN core services.
The normal M3 compiler main body calling order cannot be controlled directly by users. It tries to evaluate a graph of dependencies and the resulting order changes and was often incorrect for the SPIN core. Ordering the core init routines in an explicitly called procedure, Init(), worked around this problem.
RTLinker initializes the spin core services by calling SpinStart.Init() which is exported by Boot module. Boot.m3 exports SpinStart. Main's interface cannot be imported or exported.
Initializing the SPIN services early allows regular main bodies to use SPIN services. This allows statically linked code to use main bodies just as the dynamic code does.
Main's main body is called last of all main bodies. This is not changed. It starts the primary scheduler, which is the final bootstrap step.
After the core services initialize, the main bodies can run without restriction, which means they can fork threads, allocate memory and use the m3 library routines. But they cannot block since the scheduler has not started.
The final initialization step is to start the global scheduler. Since Main is the final main body run by the runtime, the scheduler is started there.
The normal source of the extension binaries, the file system or network, do not exist at boot-time so the object files are stashed in the kernel image at link time. The current scheme encapsulates the object files as big arrays in the data segment.
Each extension also has an Encap module generated by m3makefile . This module has the array variables for the encapsulated object files hard coded into it. The Encap module passes these arrays to the Domain interface to create, link and run its extension.
In the current implementation, the Boot module forks an extender thread in BootEncap which will make the actual extension calls. Since the extension may try to block in its initialization code (CAM does), they must be started by the extender thread after the scheduler has started.
The Encap module main bodies run along with all the other main bodies during M3 intialization. The main bodies register their module with the BootEncap module. When the scheduler starts the extender thread, it runs the extender routines registered by the Encap modules, running them in the order they register.
For configuration info, see Boottime Extensions on the extension page.
The kernel/Makefile generates m3statics, which describes the boot-time extensions in quake for m3build. The m3makefile uses mkextender to generate an Encap module for each extension listed in m3statics. It also uses encap to generate the encap_EXTENSION.s files in ALPHA_SPIN to encapsulate the object files for each extension.
The initialization order controlled by importing the extension Encap modules for extensions listed ahead of the current one.