Hi Valery,
thanks for your nice words about the Genode OS Framework.
My question is: Can be the underlying kernel determined under Genode, and then try doing kernel-specific things? Or, maybe, there is a more elegant way to do kernel-specific things?
There the three feasible approaches to integrate kernel-specific code: a separate repository that shadows parts of the other repositories, by using hack-ish preprocessor defines specified via the compiler command line (not recommended), or by using specialized libraries (highly recommended). I will shortly describe each of these ways.
When building, the Genode build system considers all directory trees specified as 'REPOSITORIES' in the '<build-dir>'/etc/build.conf' file. If two files with the same name are present in two repositories, the version of the foremost repository is picked. For example, let's assume you have a custom repository called 'yourrepo' and you want to customize the thread library normally described in 'base-foc/lib/mk/thread.mk', you can just create a custom version of the library description file 'yourrepo/lib/mk/thread.mk'. If the 'REPOSITORIES' declaration has 'yourrepo' listed in front of the 'base-foc' repository, your version will be picked up by the build system. The same shadowing mechanism applies to header files, which enables you to easily replace each original header that come with Genode with a specific version provided by 'yourrepo/include'. You can see this approach at work with the separation of generic base code (located at the 'base' repository) and platform-specific base code (located at the 'base-<platform>' repository). Because 'base-<platform>' is specified in front of 'base' in the 'REPOSITORIES' declaration, the platform-specific code is able to shadow generic code.
The second approach is specifying a '-DHAS_SPECIAL_FEATURE' definition at the compiler's command line and to wrap the kernel-specific code via classical preprocessor directives '#ifdef HAS_SPECIAL_FEATURE'-'#endif'. This is the typical solution as employed in most GNU projects. In principle, it can be used on Genode as well by introducing a new 'SPEC' (see Genode's getting-started documents for more details about the SPECS mechansism). All you need is creating a new file 'yourrepo/mk/spec-your_special_feature.mk'. In this file, extend the compiler arguments by 'CC_OPT += -DHAS_SPECIAL_FEATURE'. Now, you can enable the special feature in your build directory by manually extending the 'SPECS' variable in your '<build-dir>/etc/specs.conf' file: 'SPECS += has_special_feature'. This tells the build system to look for a file called 'spec-your_special_feature.mk' in all 'mk' subdirectories of all repositories. Hence, it will pick up your file with your 'CC_OPT' extension. However, I recommend to avoid '#ifdef'-'#endif' customizations because this facilitates the intermixing of platform-dependent with generic code, leading to code that is hard to maintain and difficult to test.
The actually recommended way is to encapsulate the specialized code in a dedicated library that implements a common interface. For example, at 'os/include/blit/blit.h', you find an interface for a 2D blitting function. There exist two implementations of this interface, a generic version and a version specialized for x86 using MMX instructions. The library description file of the generic version is located at 'os/lib/mk/blit.mk'. So if a program wants to use the blit interface, it just specifies 'LIBS += blit'. Normally, the build system will then process the 'blit.mk' file. However, there exists a second version at 'os/lib/mk/x86_32/blit.mk'. If the 'SPECS' variable defined at the build directory contains 'x86_32', the build system will automatically look in a subdirectory called 'x86_32' within each 'lib/mk' directory for specialized versions. This is a fairly generic mechanism - specialized code is provided by a specialized library that implements a generic interface. At build time, the definition of the 'SPECS' variable tells the build system where to look for specialized library description files. In your particular case, when building for Fiasco.OC, the 'SPECS' variable already contains 'foc'. So you can have a Fiasco.OC specific library implementation by simply providing a 'mk/foc/yourlib.mk' file.
Best regards Norman