KasperskyOS Community Edition 1.2
[Topic sc_application_start]

Overview: Einit and init.yaml

Einit initializing program

When a solution is started, the KasperskyOS kernel finds the executable file named Einit (initializing program) in the solution image and runs this executable file. The initializing program performs the following operations:

  • Creates and starts processes when a solution is started.
  • Creates IPC channels between processes when a solution is started (statically creates IPC channels).

A process of the initializing program belongs to the Einit class.

Generating the source code of the initializing program

The KasperskyOS SDK includes the einit tool, which generates the C-language source code of the initializing program. The standard way to use the einit tool is to integrate an einit call into one of the steps of the build script, which generates the einit.c file containing the source code of the initializing program. In one of the following steps of the build script, you must compile the einit.c file into the executable file of Einit and include it into the solution image.

You are not required to create formal specification files for the initializing program. These files are provided in the KasperskyOS SDK and are automatically applied during a solution build. However, the Einit process class must be specified in the security.psl file.

The einit tool generates the source code of the initializing program based on the init description, which consists of a text file that is usually named init.yaml.

Syntax of init.yaml

An init description contains data in YAML format. This data identifies the following:

  • Processes that are started when the solution starts.
  • IPC channels that are created when the solution starts and are used by processes to interact with each other (not with the kernel).

This data consists of a dictionary with the entities key containing a list of dictionaries of processes. Process dictionary keys are presented in the table below.

Process dictionary keys in an init description

Key

Required

Value

name

Yes

Process class name (from the EDL description).

task

No

Process name. If this name is not specified, the process class name will be used. Each process must have a unique name.

You can start multiple processes of the same class if they have different names.

path

No

Name of the executable file in ROMFS (in the solution image). If this name is not specified, the process class name (without prefixes and dots) will be used. For example, processes of the Client and net.Client classes for which an executable file name is not specified will be started from the Client file.

You can start multiple processes from the same executable file.

connections

No

Process IPC channel dictionaries list. This list defines the statically created IPC channels whose client IPC handles will be owned by the process. The list is empty by default. (In addition to statically created IPC channels, processes can also use dynamically created IPC channels.)

args

No

List of program startup parameters (main() function parameters). The maximum size of one item on the list is 1024 bytes.

env

No

Dictionary of program environment variables. The keys in this dictionary are the names of environment variables. The maximum size of an environment variable value is 1024 bytes.

Process IPC channel dictionary keys are presented in the table below.

IPC channel dictionary keys in an init description

Key

Required

Value

id

Yes

IPC channel name, which can be defined as a specific value or as a link such as

{var: <constant name>, include: <path to header file>}.

target

Yes

Name of the process that will own the server handle of the IPC channel.

Page top
[Topic einit_overview]

Example init descriptions

This section provides examples of init descriptions that demonstrate various aspects of starting processes.

The build system can automatically create an init description based on the init.yaml.in template.

Starting a client and server and creating an IPC channel between them

In this example, a process of the Client class and a process of the Server class are started. The names of the processes are not specified, so they will match the names of their respective process classes. The names of the executable files are not specified, so they will also match the names of their respective process classes. The processes will be connected by an IPC channel named server_connection.

init.yaml

entities: - name: Client connections: - target: Server id: server_connection - name: Server

Starting processes from defined executable files

This example will start a Client-class process from the executable file named cl, a ClientServer-class process from the executable file named csr, and a MainServer-class process from the executable file named msr. The names of the processes are not specified, so they will match the names of their respective process classes.

init.yaml

entities: - name: Client path: cl - name: ClientServer path: csr - name: MainServer path: msr

Starting two processes from the same executable file

This example will start a Client-class process from the executable file named Client, and two processes of the MainServer and BkServer classes from the executable file named srv. The names of the processes are not specified, so they will match the names of their respective process classes.

init.yaml

entities: - name: Client - name: MainServer path: srv - name: BkServer path: srv

Starting two servers of the same class and a client, and creating IPC channels between the client and servers

This example will start a Client-class process (named Client) and two Server-class processes named UserServer and PrivilegedServer. The client will be connected to the servers via IPC channels named server_connection_us and server_connection_ps. The names of the executable files are not specified, so they will match the names of their respective process classes.

init.yaml

entities: - name: Client connections: - id: server_connection_us target: UserServer - id: server_connection_ps target: PrivilegedServer - task: UserServer name: Server - task: PrivilegedServer name: Server

Setting the startup parameters and environment variables of programs

This example will start a VfsFirst-class process (named VfsFirst) and a VfsSecond-class process (named VfsSecond). The program that will run in the context of the VfsFirst process will be started with the parameter -f /etc/fstab, and will receive the ROOTFS environment variable with the value ramdisk0,0 / ext2 0 and the UNMAP_ROMFS environment variable with the value 1. The program that will run in the context of the VfsSecond process will be started with the -l devfs /dev devfs 0 parameter. The names of the executable files are not specified, so they will match the names of their respective process classes.

init.yaml

entities: - name: VfsFirst args: - -f - /etc/fstab env: ROOTFS: ramdisk0,0 / ext2 0 UNMAP_ROMFS: 1 - name: VfsSecond args: - -l - devfs /dev devfs 0
Page top
[Topic using_einit]

Starting processes using the system program ExecutionManager

The ExecutionManager component provides a C++ interface for creating, starting and stopping processes in solutions that are based on KasperskyOS.

The interface of the ExecutionManager component is not suitable for use in code that is written in C. To manage processes in the C language, use the task.h interface of the libkos library.

The ExecutionManager component API is an add-on over IPC that helps simplify the program development process. ExecutionManager is a separate system program that is accessed through IPC. However, developers are provided with a client library that eliminates the necessity of directly using IPC calls.

The programming interface of the ExecutionManager component is described in the article titled "ExecutionManager component".

ExecutionManager component usage scenario

Hereinafter "the client" refers to the application that uses the ExecutionManager component API to manage other applications.

The typical usage scenario for the ExecutionManager component includes the following steps:

  1. Add the ExecutionManager program to a solution. To add ExecutionManager to a solution:
    find_package (execution_manager REQUIRED) include_directories (${execution_manager_INCLUDE}) add_subdirectory (execution_manager)

    The BlobContainer program is required for the ExecutionManager program to work properly. This program is automatically added to a solution when adding ExecutionManager.

    • The ExecutionManager component is provided in the SDK as a set of static libraries and header files, and is built for a specific solution by using the CMake command create_execution_manager_entity() from the CMake library execution_manager.

      To build the ExecutionManager program, create a directory named execution_manager in the root directory of the project. In the new directory, create a CMakeLists.txt file containing the create_execution_manager_entity() command.

      The CMake command create_execution_manager_entity() takes the following parameters:

      Mandatory ENTITY parameter that specifies the name of the executable file for the ExecutionManager program.

      Optional parameters:

      • DEPENDS – additional dependencies for building the ExecutionManager program.
      • MAIN_CONN_NAME – name of the IPC channel for connecting to the ExecutionManager process. It must match the value of the mainConnection variable when calling the ExecutionManager API in the client code.
      • ROOT_PATH – path to the root directory for service files of the ExecutionManager program. The default root path is "/ROOT".
      • VFS_CLIENT_LIB – name of the client transport library used to connect the ExecutionManager program to the VFS program.
    include (execution_manager/create_execution_manager_entity) create_execution_manager_entity( ENTITY ExecMgrEntity MAIN_CONN_NAME ${ENTITY_NAME} ROOT_PATH "/root" VFS_CLIENT_LIB ${vfs_CLIENT_LIB})
    • When building a solution (CMakeLists.txt file for the Einit program), add the following executable files to the solution image:
      • Executable file of the ExecutionManager program
      • Executable file of the BlobContainer program
  2. Link the client executable file to the client proxy library of ExecutionManager by adding the following command to the CMakeLists.txt file for building the client:
    target_link_libraries (<name of the CMake target for building the client> ${execution_manager_EXECMGR_PROXY})
  3. Add permissions for the necessary events to the solution security policy description:
    1. To enable the ExecutionManager program to run other processes, the solution security policy must allow the following interactions for the execution_manager.ExecMgrEntity process class:
      • Security events of the execute type for all classes of processes that will be run.
      • Access to all endpoints of the VFS program.
      • Access to all endpoints of the BlobContainer program.
      • Access to the core endpoints Sync, Task, VMM, Thread, HAL, Handle, FS, Notice, CM and Profiler (their descriptions are located in the directory sysroot-*-kos/include/kl/core from the SDK).
    2. To enable a client to call the ExecutionManager program, the solution security policy must allow the following interactions for the client process class:
      • Access to the appropriate endpoints of the ExecutionManager program (their descriptions are located in the directory sysroot-*-kos/include/kl/execution_manager from the SDK).
  4. Use of the ExecutionManager program API in the client code.

    Use the header file component/package_manager/kos_ipc/package_manager_proxy.h for this. For more details, refer to "ExecutionManager component".

Page top
[Topic app_static_start]

Overview: Env program

The system program Env is intended for setting startup parameters and environment variables of programs. If the Env program is included in a solution, the processes connected via IPC channel to the Env process will automatically send IPC requests to this program and receive startup parameters and environment variables when these processes are started.

Use of the Env system program is an outdated way of setting startup parameters and environment variables of programs. Instead, you must set the startup parameters and environment variables of programs via the init.yaml.in or init.yaml file.

If the value of a startup parameter or environment variable of a program is defined through the Env program and via the init.yaml.in or init.yaml file, the value defined through the Env program will be applied.

To use the Env program in a solution, you need to do the following:

  1. Develop the code of the Env program using the macros and functions from the header file sysroot-*-kos/include/env/env.h from the KasperskyOS SDK.
  2. Build the executable file of the Env program by linking it to the env_server library from the KasperskyOS SDK.
  3. In the init description, indicate that the Env process must be started and connected to other processes (Env acts as a server in this case). The name of the IPC channel is assigned by the ENV_SERVICE_NAME macro defined in the header file env.h.
  4. Include the Env executable file in the solution image.

Source code of the Env program

The source code of the Env program utilizes the following macros and functions from the header file env.h:

  • ENV_REGISTER_ARGS(name,argarr) sets the argarr startup parameters for the program that will run in the context of the name process.
  • ENV_REGISTER_VARS(name,envarr) sets the envarr environment variables for the program that will run in the context of the name process.
  • ENV_REGISTER_PROGRAM_ENVIRONMENT(name,argarr,envarr) sets the argarr startup parameters and envarr environment variables for the program that will run in the context of the name process.
  • envServerRun() initializes the server part of the Env program so that it can respond to IPC requests.

Env program usage examples

Page top
[Topic env_overview]

Examples of using Env to set the startup parameters and environment variables of programs

Use of the Env system program is an outdated way of setting startup parameters and environment variables of programs. Instead, you must set the startup parameters and environment variables of programs via the init.yaml.in or init.yaml file.

If the value of a startup parameter or environment variable of a program is defined through the Env program and via the init.yaml.in or init.yaml file, the value defined through the Env program will be applied.

Example of setting startup parameters of a program

Source code of the Env program is presented below. When the process named NetVfs starts, the program passes the following two program startup parameters to this process: -l devfs /dev devfs 0 and -l romfs /etc romfs ro:

env.c

#include <env/env.h> #include <stdlib.h> int main(int argc, char** argv) { const char* NetVfsArgs[] = { "-l", "devfs /dev devfs 0", "-l", "romfs /etc romfs ro" }; ENV_REGISTER_ARGS("NetVfs", NetVfsArgs); envServerRun(); return EXIT_SUCCESS; }

Example of setting environment variables of a program

Source code of the Env program is presented below. When the process named Vfs3 starts, the program passes the following two program environment variables to this process: ROOTFS=ramdisk0,0 / ext2 0 and UNMAP_ROMFS=1:

env.c

#include <env/env.h> #include <stdlib.h> int main(int argc, char** argv) { const char* Vfs3Envs[] = { "ROOTFS=ramdisk0,0 / ext2 0", "UNMAP_ROMFS=1" }; ENV_REGISTER_VARS("Vfs3", Vfs3Envs); envServerRun(); return EXIT_SUCCESS; }
Page top
[Topic using_env_app]