RMGR acts as a pager for the tasks it starts. It emulates the sigma0 protocol for them (L4 Reference Manual, Appendix B). Moreover, it manages the following system resources: main memory, irq lines and L4 task numbers. Client tasks can request access to these resources using a proprietary protocol, the supervisor protocol (see rmgr_api ).
RMGR can be configured by specifying configuration directives either on the command line or in a configuration file. Which alternative is used depends on the following command line argument:
If this parameter is not specified, configuration directives are taken directly from the command line instead.
RMGR tries to detect the L4 version during startup to find out about the services the L4 kernel and its servers provide. At the moment the only difference that must be handled is the 4MB page extension of L4/Pentium. All other L4/Pentium specific features are no-ops at L4/486 and therefore don't need any special treatment. If we use L4/pentium but want to be able to simulate L4/486 within respect to 4MB page tables, -nopentium forces RMGR to think it is running on L4/486.
See section Configuration for information on configuration directives.
RMGR is compatible with the Multiboot standard proposal. It should be
started as a boot kernel using a Multiboot-compliant boot loader like
GRUB. The L4 µ-kernel should be loaded as the first boot module, and
the RMGR config file (if required) as the second boot module. Any
boot servers intended to be started by RMGR at boot time should be
loaded as further boot modules.
Here is a sample GRUB configuration file (menu.lst) which accomplishes this:
# RMGR is the boot kernel kernel= (fd0)/rmgr -configfile # L4 must be the first boot module module= (fd0)/grubboot.img -nowait # The RMGR config file (if any) must come second module= (fd0)/rmgr.cfg # boot server tasks follow module= (fd0)/glinux.gz root=/dev/sda5 module= (fd0)/hello
After having been loaded in this way, the boot loader will first activate an RMGR initialization routine which first initializes L4's boot configuration table according to section 2.9 of the L4 Reference Manual. (This renders previous methods of patching the boot table before booting in the boot image on disk obsolete.) RMGR makes sure it will be the first user task running under L4 (the booter task or root task in L4-speak).
Because of deficiencies of the L4 µ-kernel, RMGR also parses and processes L4's command line (containing "-nowait" in the example above). RMGR understands the following directives:
Once running under L4, RMGR parses its configuration data (if supplied) and then starts the executable images loaded as further boot modules as child tasks.
Except for the RMGR configuration file (and modules intended to be
passed to sub-tasks as parameters), all boot modules (including
the L4 µ-kernel) must be ELF binaries linked to the absolute RAM
address they should be loaded into. They don't have to be
multiboot-compliant (RMGR doesn't interpret multiboot data structures
imbedded into them) but they will be started in a
multiboot-compliant way, enabling them to make use of a
multiboot_info data structure containing a command line, the
machine's RAM size, and a list of multiboot modules (loaded by the
boot loader and passed on by RMGR using the module option
The configuration data can be specified on RMGR's command line or
in a configuration file (see section Description).
When using a configuration file, the first line of the file should contain only the following text:
In the configuration text, whitespace and newlines are ignored, as is text between the comment character, "#", and the end of the line. Here is the configuration syntax:
configfile := [ rule ... ] [ end ]
rule := taskrule | globalrule | debugrule
taskrule := task [ modname string | number | rmgr | sigma0 ] [ constraint | bootparam ] ... [ module ] ...
module := module [ modname string ]
constraint := child numconstraint ... | memory numconstraint | high_memory numconstraint | small numconstraint | irq maskconstraint ...
numconstraint := max number | in [ number , number ]
maskconstraint := mask number | numconstraint
bootparam := log_mcp number | boot_mcp number | boot_priority number | boot_small number
globalrule := small_space_size number
debugrule := bootwait | verbose | debug | debug_log log_rule
log_rule := number number | verbose_log_rule
verbose_log_rule := verbose_log_stmt verbose_log_rule | verbose_log_stmt
verbose_log_stmt := task_proto | mem_proto | irq_proto | rmgr_proto | task_alloc | task_get | task_free | task_create | task_delete | task_smalltask_get_id | task_create_with_prio | mem_free | mem_free_fp | irq_get | irq_free | rmgr_ping | log | kdebug
The configuration text consists of a sequence of directives; currently, the following types of directives are known: task, small_space_size, bootwait, verbose, debug, debug_log, and end.
The sequence of task directives corresponds to the sequence of bootstrap tasks loaded as boot modules. Alternatively, the modname parameter can be used to select a module by its name: It selects the first module containign string in the "module=" specification. The task directive can also be qualified by an explicit task number or by one of the task specifiers rmgr or sigma0.
For each task, directives can be given to constrain the set of system resources the task can request from RMGR. For subtasks (child) and memory, these constraints are the maximal number of units that can be acquired and the numeric range the units must be part of. For IRQ lines, it is additionally possible to specify a mask which exactly defines which IRQs can be requested. Also, certain bootstrap parameters can be specified.
All constraints specified for a given resource type are logically AND'd, i.e., all constraints must be true for a resource address to be requestable for the corresponding task.
Tasks can also be passed a list of multiboot modules, to be specified using one or more module options.
The small_space_size directive defines the minimal size of the system's small address spaces. If not specified, the system will run with only large address spaces.
The bootwait directive can be used to cause RMGR to pause before actually starting to serve the bootstrapped tasks. It can be used to review the console messages printed by RMGR before they scroll off the screen.
The verbose, debug, and debug_log directives can be used to modify RMGR's logging and debugging behaviour: verbose enables logging of all run-time error messages to the console, debug enables an invokation of the L4 kernel debugger on run-time errors, and debug_log allows to define which protocol should be logged. For further information, UTSL.
The end directive marks the end of the configuration file. All text appearing after end is ignored by RMGR.
Strings are "- or '-separated literals (which cannot contain the separation character). Numbers can be given in decimal, hexadecimal or octal format (using C syntax).
Here is an example configuration file:
#!rmgr task modname "glinux" child max 512 in [10, 531] memory max 0x01000000 in [0, 0x01000000] irq mask 0xffffffe7 end
This manual page:
L4 Reference Manual
Guidelines for Developing OS Servers on Top of L4
GRUB, the Grand Unified Bootloader
Multiboot standard proposal