|
| 1 | +# Modular structure of Embox |
| 2 | + |
| 3 | +Important features of Embox are: **modularity** and **configurability**. |
| 4 | + |
| 5 | +A **modularity** is splitting project into small logical parts that is modules. |
| 6 | + |
| 7 | +And **configurability** is ability to determinate the characteristics of the end system, |
| 8 | +based on list of modules and their parameters. |
| 9 | + |
| 10 | +For this purpose we use "Mybuild" assembly system with a dictionary specification language, |
| 11 | +which allows to describe the modules and system as a whole. |
| 12 | + |
| 13 | +At the same time, programming logic of modules is located separately from a description |
| 14 | +and it's developed on general-purpose programming language. |
| 15 | + |
| 16 | +## The files of module description |
| 17 | +### The packages of modules |
| 18 | +Modules are organized into hierarhical groups (namespace). |
| 19 | +This structure allows to avoid mess in names of modules and makes them short. |
| 20 | + |
| 21 | +As usual, package name coincides with the path in the file system. |
| 22 | +It relieves search for module files in source code tree. |
| 23 | + |
| 24 | +The example of package naming: |
| 25 | +```java |
| 26 | + package embox.arch |
| 27 | +``` |
| 28 | +### Interfaces and abstract modules |
| 29 | +Interfaces for modules are direct analogues of abstract classes and interfaces in OOP. |
| 30 | + |
| 31 | +**Module description language** supports **interface** that allows to to introduce the next points: |
| 32 | + |
| 33 | +* the **interface** concept (modules without implementation) |
| 34 | +* **abstract modules** (modules with partial implementation) |
| 35 | + |
| 36 | +This method allows you to choose from the list of modules (that implement the same interface, but have different algorithms) the needed one. |
| 37 | + |
| 38 | +To mark a module as inherited, you need to use the `abstract` keyword. |
| 39 | +The example of module declaration: |
| 40 | +```java |
| 41 | + package embox.arch |
| 42 | + //... |
| 43 | + abstract module interrupt {} |
| 44 | + //... |
| 45 | +``` |
| 46 | +To point at inheritance, we use `extends` keyword. |
| 47 | +The instance of inheritance from the abstract module: |
| 48 | +```java |
| 49 | + module interrupt_stub extends embox.arch.interrupt { |
| 50 | + //... |
| 51 | + } |
| 52 | +``` |
| 53 | +### Attributes of modules |
| 54 | +Description of every module consists of several possible attributes: |
| 55 | + |
| 56 | +* **files of source code** |
| 57 | +* **options** |
| 58 | +* **dependencies** |
| 59 | + |
| 60 | +#### Files of source code |
| 61 | +A module can point at list of file, which you need to compile and to add in a final image. |
| 62 | + |
| 63 | +Except **"ordinary" files** in C and assembler, it's possible to include **header files** and **additional linker scripts**. |
| 64 | + |
| 65 | +**Types of files differ according to file extension: ".c/.S", ".h", ".lds.S".** |
| 66 | + |
| 67 | +**".c/.S"** is a **source code**, written in C or assembler. In the assembly process it's compelled and included in final image of system. |
| 68 | +During the compilation it's possible to get values of options of module that connected with files of source code. |
| 69 | + |
| 70 | +**".h"** is a **header file** containing the definitions, needed for implementation of interface. |
| 71 | +During the building of module the special header file is generated. It has all listed .h-files of this module. |
| 72 | + |
| 73 | +It allows you to use different implementations of some interface without changing the source code of the modules that use it. |
| 74 | +Such way of abstraction is necessary, because different implementations can define one or the other structure in different ways |
| 75 | +while this structure can be used by other modules without knowledge about details of implementation. |
| 76 | + |
| 77 | +**".lds.S"** are **linker scripts** that allow you to affect on loading the modules in final image. The typical using is an addition of new sections. |
| 78 | + |
| 79 | +The example of adding the **".h-file"** to the module: |
| 80 | +```java |
| 81 | + module interrupt_stub extends embox.arch.interrupt { |
| 82 | + source "interrupt_stub.h" |
| 83 | + } |
| 84 | +``` |
| 85 | +The instance of adding the **".lds.S-file"** and **".c-file"** to the module: |
| 86 | +```java |
| 87 | + module static_heap extends heap_place { |
| 88 | + //... |
| 89 | + source "heap.lds.S" |
| 90 | + source "static_heap.c" |
| 91 | + //... |
| 92 | + |
| 93 | + } |
| 94 | +``` |
| 95 | + |
| 96 | +#### Options |
| 97 | +**The characteristics of options:** |
| 98 | +* allow you to define numerical, boolean and string parameters at the configuration stage |
| 99 | +* can have default value, if the value doesn't exist -- ad it to your configuration |
| 100 | + |
| 101 | +Options allow you to define **numerical**, **boolean** and **string parameters** at the configuration stage. |
| 102 | + |
| 103 | +These **parameters can affect how the module is assembled, initialized** and **how it works**. |
| 104 | + |
| 105 | +To define a type of some options, it's needed to write it after the `option` keyword. |
| 106 | + |
| 107 | +To get a value of some option during the compilation of source code, it's used the next **special macros**: |
| 108 | +* **OPTION_STRING_GET** is for string options |
| 109 | +* **OPTION_NUMBER_GET** is for numerical options |
| 110 | +* **OPTION_BOOLEAN_GET** is for boolean options |
| 111 | +The argument of macro is option name defined in **my-file**. |
| 112 | + |
| 113 | +#### Dependencies |
| 114 | +**Dependencies** are the way to show to the assembly system that the correct module working is impossible without other ones. |
| 115 | + |
| 116 | +The **list of dependencies** can include some interfaces. |
| 117 | +It means that only one module implemented required interface can be included in a building. |
| 118 | + |
| 119 | +Use the **"depends"** attribute to define dependencies between modules. |
| 120 | +You can count modules and interfaces in value of this attribute. |
| 121 | + |
| 122 | +Assembly system guarantees that the dependencies of specific module will be added when this module is included in the system. |
| 123 | + |
| 124 | +In some cases you just need **to add a module** what you need **without changing the loading order**. |
| 125 | +This method is used for such global modules as, **for example**: **"multiprocessing support"**, **"logging"**, **"debug statement" (assert)**. |
| 126 | + |
| 127 | +Due to the fact that these **modules don't have a status** in the usual sence (such as **"loaded"** or **"unloaded"**), |
| 128 | +it's required to add the ***@NoRuntime*** annotation to the **"depends"** attribute. |
| 129 | + |
| 130 | +In this case, the dependencies will be used during the building , but won't determine module loading order. |
| 131 | + |
| 132 | +### Annotations |
| 133 | +**The characteristics of annotations:** |
| 134 | +* are used for changing the semantics of description elements |
| 135 | +* allow to extend description language without changing the grammar |
| 136 | +* make description language more flexible |
| 137 | + |
| 138 | +The instance of implementation the abstract module with help of the annotation: |
| 139 | +```java |
| 140 | + @DefaultImpl(embox.arch.generic.interrupt_stub) |
| 141 | + abstract module interrupt {} |
| 142 | +``` |
| 143 | + |
| 144 | +## Configuration description |
| 145 | +**Module description** is used to create a target image. |
| 146 | + |
| 147 | +During the configuration the assembly system allows to merge modules of system (e. g. kernel modules, drivers, tests, applications) |
| 148 | +and to install parameters for these, and also to define additional parameters to create an image for different hardware platforms. |
| 149 | + |
| 150 | +### The structure of configuration |
| 151 | +Image configuration is running through file editing in the **"conf/"** directory. |
| 152 | +It contains the following: |
| 153 | +* **"lds.conf"** -- contains the definition of memory card, which is used by specific hardware platforms |
| 154 | +* **"mods.conf"** -- contains names and options of modules, which will be included in OS image. |
| 155 | +Also you can set every modules in this file to new values |
| 156 | +* **"rootfs"** -- contains files, which will be included into the file system |
| 157 | + |
| 158 | +### Configuration process |
| 159 | +To use some module in OS image means to add it into some OS configuration. |
| 160 | + |
| 161 | +#### Basic configuration |
| 162 | +A preparation any configuration to building is a long process. A basic configuration is used to save your time. |
| 163 | + |
| 164 | +OS has several configuration that intended to be used as basic. |
| 165 | +Several configurations with different properties have been prepared for each platform. |
| 166 | + |
| 167 | +For example, to get a basic configuration to support x86 platform, use the next command: |
| 168 | +``` |
| 169 | + make confload-x86/qemu |
| 170 | +``` |
| 171 | +This command loads basic "qemu" configuration for x86 platform in the **"conf/"** directory. |
| 172 | + |
| 173 | +The list of basic configurations you can see and choose the needed one, type: |
| 174 | +``` |
| 175 | + make confload |
| 176 | +``` |
| 177 | + |
| 178 | +#### Inclusion of module into configurations |
| 179 | +The list of modules (that you can include in your configuration) locates in the "conf/mods.conf". |
| 180 | +This file has the next structure: |
| 181 | +``` |
| 182 | + package genconfig |
| 183 | +
|
| 184 | + configuration conf { |
| 185 | + [module_list] |
| 186 | + } |
| 187 | +``` |
| 188 | +Where **[module_list]** defines the position of set of strings, each of the last ones is responsible for inclusion. |
| 189 | + |
| 190 | +Add a new line to the module list: |
| 191 | +``` |
| 192 | + include pkg.new_package.empty |
| 193 | +``` |
| 194 | +To get the following: |
| 195 | +``` |
| 196 | + package genconfig |
| 197 | +
|
| 198 | + configuration conf { |
| 199 | + [module_list] |
| 200 | + include pkg.new_package.empty |
| 201 | + } |
| 202 | +``` |
| 203 | +Then the "empty" module from "pkg.new_package" will be included in the building. |
| 204 | + |
| 205 | +To check the consistency of received building and to create OS image, type: |
| 206 | +``` |
| 207 | + make |
| 208 | +``` |
| 209 | +If everything was completed successful, you'll see the "Build complete" message on your screen. |
| 210 | + |
| 211 | +To be confident that new module appeared in OS, do the following: |
| 212 | +``` |
| 213 | + lsmod -n empty |
| 214 | +``` |
| 215 | +We typed the "lsmod" command with the "-n" and "empty" parameters in the line above. |
| 216 | +This command displays the list of module list, which have in their names "empty" substring. |
| 217 | + |
| 218 | +The result of "lsmod" is below: |
| 219 | +``` |
| 220 | + * pkg.new_package.empty |
| 221 | +``` |
| 222 | +This output tells us that the "pkg.new_package.empty" is in the system, and the `*` symbol -- that at this moment the module is loaded and it works. |
0 commit comments