Contents
Building a KasperskyOS-based solution
This section contains the following information:
- Description of the KasperskyOS-based solution build process.
- Descriptions of the scripts, libraries and build templates provided in KasperskyOS Community Edition.
- Information on how to use dynamic libraries in a KasperskyOS-based solution.
Building a solution image
A KasperskyOS-based solution consists of system software (including the KasperskyOS kernel and Kaspersky Security Module) and application software integrated for operation within a software/hardware system.
For more details, refer to Structure and startup of a KasperskyOS-based solution.
System programs and application software
Programs are divided into two types according to their purpose:
- System programs create the infrastructure for application software. For example, they facilitate hardware operations, support the IPC mechanism, and implement file systems and network protocols. System programs are included in KasperskyOS Community Edition. If necessary, you can develop your own system programs.
- Application software is designed for interaction with a solution user and for performing user tasks. Application software is not included in KasperskyOS Community Edition.
Building programs during the solution build process
During a solution build, programs are divided into the following two types:
- System programs provided as executable files in KasperskyOS Community Edition.
- System programs or application software that requires linking to an executable file.
Programs that require linking are divided into the following types:
- System programs that implement an IPC interface whose ready-to-use transport libraries are provided in KasperskyOS Community Edition.
- Application software that implements its own IPC interface. To build this software, transport methods and types need to be generated by using the NK compiler.
- Client programs that do not provide endpoints.
Building a solution image
KasperskyOS Community Edition provides an image of the KasperskyOS kernel and the executable files of some system programs and driver applications that are ready to use in a solution.
A specialized Einit program intended for starting all other programs, and a Kaspersky Security Module are built for each specific solution and are therefore not already provided in KasperskyOS Community Edition. Instead, the toolchain provided in KasperskyOS Community Edition includes the tools for building these resources.
The general step-by-step build scenario is described in the article titled Build process overview. A solution image can be built as follows:
- [Recommended] Using scripts of the
CMake
build system, which is provided in KasperskyOS Community Edition. - [Without CMake] Using other automated build systems or manually with scripts and compilers provided in KasperskyOS Community Edition.
Build process overview
To build a solution image, the following is required:
- Prepare EDL, CDL and IDL descriptions of applications, an init description file (
init.yaml
by default), and files containing a description of the solution security policy (security.psl
by default).When building with
CMake
, an EDL description can be generated by using thegenerate_edl_file()
command. - Generate *.edl.h files for all programs except the system programs provided in KasperskyOS Community Edition.
- When building with
CMake
, thenk_build_edl_files()
command is used for this purpose. - When building without
CMake
, the NK compiler must be used for this.
- When building with
- For programs that implement their own IPC interface, generate code of the transport methods and types that are used for generating, sending, receiving and processing IPC messages.
- When building with
CMake
, thenk_build_idl_files()
andnk_build_cdl_files()
commands are used for these purposes. - When building without
CMake
, the NK compiler must be used for this.
- When building with
- Build all programs that are part of the solution, and link them to the transport libraries of system programs or applications if necessary. To build applications that implement their own IPC interface, you will need the code containing transport methods and types that was generated at step 3.
- When building with
CMake
, standard build commands are used for this purpose. The necessary cross-compilation configuration is done automatically. - When building without
CMake
, the cross compilers included in KasperskyOS Community Edition must be manually used for this purpose.
- When building with
- Build the Einit initializing program.
- When building with
CMake
, theEinit
program is built during the solution image build process using thebuild_kos_qemu_image()
andbuild_kos_hw_image()
commands. - When building without
CMake
, the einit tool must be used to generate the code of theEinit
program. Then theEinit
application must be built using the cross compiler that is provided in KasperskyOS Community Edition.
- When building with
- Build the Kaspersky Security Module.
- When building with
CMake
, the security module is built during the solution image build process using thebuild_kos_qemu_image()
andbuild_kos_hw_image()
commands. - When building without
CMake
, themakekss
script must be used for this purpose.
- When building with
- Create the solution image.
- When building with
CMake
, thebuild_kos_qemu_image()
andbuild_kos_hw_image()
commands are used for this purpose. - When building without
CMake
, themakeimg
script must be used for this.
- When building with
Example 1
For the basic hello
example included in KasperskyOS Community Edition that contains one application that does not provide any services, the build scenario looks as follows:
Example 2
The echo
example included in KasperskyOS Community Edition describes a basic case of interaction between two programs via an IPC mechanism. To set up this interaction, you will need to implement an interface with the Ping
method on a server and put the Ping
service into a new component (for example, Responder
), and an instance of this component needs to be put into the EDL description of the Server
program.
If a solution contains programs that utilize an IPC mechanism, the build scenario looks as follows:
Using CMake from the contents of KasperskyOS Community Edition
To automate the process of preparing the solution image, you need to configure the CMake
build system. You can base this system on the build system parameters used in the examples from KasperskyOS Community Edition.
CMakeLists.txt
files use the standard CMake
syntax, and commands and macros from libraries provided in KasperskyOS Community Edition.
Recommended structure of project directories
When creating a KasperskyOS-based solution, it is recommended to use the following directory structure in a project:
- In the project root, create a CMakeLists.txt boot file containing the general build instructions for the entire solution.
- The source code of each program being developed should be placed into a separate directory within the
src
subdirectory. - Create CMakeLists.txt files for building each application in the corresponding directories.
- To generate the source code of the
Einit
program, you should create a separateeinit
directory containing thesrc
subdirectory in which you should put the init.yaml.in and security.psl.in templates.Any other files that need to be included in the solution image can also be put into this directory.
- Create a CMakeLists.txt file for building the
Einit
program in theeinit
directory. - The files of EDL, CDL and IDL descriptions should be put into the
resources
directory in the project root.
Example structure of project directories
Building a solution image
To build a solution image, you must use the cmake
tool (the toolchain/bin/cmake
executable file from KasperskyOS Community Edition).
Build script example:
build.sh
CMakeLists.txt root file
The CMakeLists.txt
boot file contains general build instructions for the entire solution.
The CMakeLists.txt
boot file must contain the following commands:
cmake_minimum_required (VERSION 3.25)
indicates the minimum supported version ofCMake
.For a KasperskyOS-based solution build,
CMake
version 3.25 or later is required.The required version of
CMake
is provided in KasperskyOS Community Edition and is used by default.include (platform)
connects theplatform
library ofCMake
.initialize_platform()
initializes theplatform
library.project_header_default("STANDARD_GNU_11:YES" "STRICT_WARNINGS:NO")
sets the flags of the compiler and linker.- [Optional] Connect and configure packages for the provided system programs and drivers that need to be included in the solution:
- A package is connected by using the
find_package()
command. - After connecting a package, you must add the package-related directories to the list of search directories by using the
include_directories()
command. - For some packages, you must also set the values of properties by using the
set_target_properties()
command.
CMake
descriptions of system programs and drivers provided in KasperskyOS Community Edition, and descriptions of their exported variables and properties are located in the corresponding files at/opt/KasperskyOS-Community-Edition-<version>/sysroot-aarch64-kos/lib/cmake/<program name>/<program name>-config.cmake
- A package is connected by using the
- The
Einit
initializing program must be built using theadd_subdirectory(einit)
command. - All applications to be built must be added by using the
add_subdirectory(<program directory name>)
command.
Example CMakeLists.txt boot file
CMakeLists.txt
CMakeLists.txt files for building applications
The CMakeLists.txt
file for building an application must contain the following commands:
include (platform/nk)
connects theCMake
library for working with the NK compiler.project_header_default ("STANDARD_GNU_11:YES" "STRICT_WARNINGS:NO"
) sets the flags of the compiler and linker.- An EDL description of a process class for a program can be generated by using the
generate_edl_file()
command. - If the program provides endpoints using an IPC mechanism, the following transport code must be generated:
- idl.h files are generated by the
nk_build_idl_files()
command - cdl.h files are generated by the
nk_build_cdl_files()
command - edl.h files are generated by the
nk_build_edl_files()
command
- idl.h files are generated by the
add_executable (<program name> "<path to the file containing the program source code>")
adds the program build target.add_dependencies (<program name> <name of the edl.h file build target>
) adds a program build dependency on edl.h file generation.target_link_libraries (<program name> <list of libraries>)
determines the libraries that need to be linked with the program during the build.For example, if the program uses file I/O or network I/O, it must be linked with the
${vfs_CLIENT_LIB}
transport library.CMake
descriptions of system programs and drivers provided in KasperskyOS Community Edition, and descriptions of their exported variables and properties are located in the corresponding files at/opt/KasperskyOS-Community-Edition-<version>/sysroot-aarch64-kos/lib/cmake/<program name>/<program name>-config.cmake
- To automatically add descriptions of IPC channels to the
init.yaml
file when building a solution, you must define theEXTRA_CONNECTIONS
property and assign it a value with descriptions of the relevant IPC channels.Please note the indentations at the beginning of strings in the
EXTRA_CONNECTIONS
property. These indentations are necessary to correctly insert values into theinit.yaml
file and must comply with its syntax requirements.Example of creating an IPC channel between a
Client
process and aServer
process:set_target_properties (Client PROPERTIES EXTRA_CONNECTIONS " - target: Server id: server_connection")When building this solution, the description of this IPC channel will be automatically added to the
init.yaml
file when processing macros of the init.yaml.in template. - To automatically add a list of arguments for the
main()
function and a dictionary of environment variables to theinit.yaml
file when building a solution, you must define theEXTRA_ARGS
andEXTRA_ENV
properties and assign the appropriate values to them.Note the indentations at the beginning of strings in the
EXTRA_ARGS
andEXTRA_ENV
properties. These indentations are necessary to correctly insert values into theinit.yaml
file and must comply with its syntax requirements.Example of sending the
Client
program the"-v"
argument of themain()
function and the environment variableVAR1
set toVALUE1
:set_target_properties (Client PROPERTIES EXTRA_ARGS " - \"-v\"" EXTRA_ENV " VAR1: VALUE1")When building this solution, the description of the
main()
function argument and the environment variable value will be automatically added to theinit.yaml
file when processing macros of the init.yaml.in template.
Example CMakeLists.txt file for building a simple application
CMakeLists.txt
CMakeLists.txt file for building the Einit program
The CMakeLists.txt
file for building the Einit
initializing program must contain the following commands:
include (platform/image)
connects theCMake
library that contains the solution image build scripts.project_header_default ("STANDARD_GNU_11:YES" "STRICT_WARNINGS:NO"
) sets the flags of the compiler and linker.- Configure the packages of system programs and drivers that need to be included in the solution.
- A package is connected by using the
find_package ()
command. - For some packages, you must also set the values of properties by using the
set_target_properties ()
command.
CMake
descriptions of system programs and drivers provided in KasperskyOS Community Edition, and descriptions of their exported variables and properties are located in the corresponding files at/opt/KasperskyOS-Community-Edition-<version>/sysroot-aarch64-kos/lib/cmake/<program name>/<program name>-config.cmake
- A package is connected by using the
- To automatically add descriptions of IPC channels between processes of system programs to the
init.yaml
file when building a solution, you must add these channels to theEXTRA_CONNECTIONS
property for the corresponding programs.Please note the indentations at the beginning of strings in the
EXTRA_CONNECTIONS
property. These indentations are necessary to correctly insert values into theinit.yaml
file and must comply with its syntax requirements.For example, the
VFS
program does not have a channel for connecting to theEnv
program by default. To automatically add a description of this channel to the init.yaml file during a solution build, you must add the following call to theCMakeLists.txt
file for building theEinit
program:set_target_properties (${vfs_ENTITY} PROPERTIES EXTRA_CONNECTIONS " - target: env.Env id: {var: ENV_SERVICE_NAME, include: env/env.h}"When building this solution, the description of this IPC channel will be automatically added to the
init.yaml
file when processing macros of the init.yaml.in template. - To automatically add a list of arguments for the
main()
function and a dictionary of environment variables to theinit.yaml
file when building a solution, you must define theEXTRA_ARGS
andEXTRA_ENV
properties and assign the appropriate values to them.Note the indentations at the beginning of strings in the
EXTRA_ARGS
andEXTRA_ENV
properties. These indentations are necessary to correctly insert values into theinit.yaml
file and must comply with its syntax requirements.
Example of sending the VfsEntity
program the "-f fstab"
argument of the main()
function and the environment variable ROOTFS
set to ramdisk0,0 / ext2 0
:
When building this solution, the description of the main()
function argument and the environment variable value will be automatically added to the init.yaml
file when processing macros of the init.yaml.in template.
set(ENTITIES <full list of programs included in the solution>)
defines theENTITIES
variable containing a list of executable files of all programs included in the solution.- One or both commands for building the solution image:
- build_kos_hw_image() creates the target for building a solution image for the hardware platform.
- build_kos_qemu_image() creates the target for building a solution image for QEMU.
Example CMakeLists.txt file for building the Einit program
CMakeLists.txt
init.yaml.in template
The init.yaml.in
template is used to automatically generate a part of the init.yaml
file prior to building the Einit
program using CMake
tools.
When using the init.yaml.in
template, you do not have to manually add descriptions of system programs and the IPC channels for connecting to them to the init.yaml
file.
The init.yaml.in
template must contain the following data:
- Root
entities
key. - List of all applications included in the solution.
- For applications that use an IPC mechanism, you must specify a list of IPC channels that connect this application to other applications.
The IPC channels that connect this application to other applications are either indicated manually or specified in the CMakeLists.txt file for this application using the
EXTRA_CONNECTIONS
property.To specify a list of IPC channels that connect this application to system programs that are included in KasperskyOS Community Edition, the following macros are used:
@INIT_<program name>_ENTITY_CONNECTIONS@
– during the build, this is replaced with the list of IPC channels containing all system programs that are linked to the application. Thetarget
andid
fields are filled according to theconnect.yaml
files from KasperskyOS Community Edition located in/opt/KasperskyOS-Community-Edition-<version>/sysroot-aarch64-kos/include/<system program name>
).This macro needs to be used if the application does not have connections to other applications but instead connects only to system programs. This macro adds the root
connections
key.@INIT_<program name>_ENTITY_CONNECTIONS+@
– during the build, the list of IPC channels containing all system programs that are linked to the application is added to the manually defined list of IPC channels. This macro does not add the rootconnections
key.This macro needs to be used if the application has connections to other applications that were manually indicated in the
init.yaml.in
template.
- The
@INIT_<program name>_ENTITY_CONNECTIONS@
and@INIT_<program name>_ENTITY_CONNECTIONS+@
macros also add the list of connections for each program defined in theEXTRA_CONNECTIONS
property when building this program. - If you need to pass
main()
function arguments defined in theEXTRA_ARGS
property to a program when building this program, you need to use the following macros:@INIT_<program name>_ENTITY_ARGS@
– during the build, this is replaced with the list of arguments of themain()
function defined in theEXTRA_ARGS
property. This macro adds the rootargs
key.@INIT_<program name>_ENTITY_ARGS+@
– during the build, this macro adds the list ofmain()
function arguments defined in theEXTRA_ARGS
property to the list of manually defined arguments. This macro does not add the rootargs
key.
- If you need to pass the values of environment variables defined in the
EXTRA_ENV
property to a program when building this program, you need to use the following macros:@INIT_<program name>_ENTITY_ENV@
– during the build, this is replaced with the dictionary of environment variables and their values defined in theEXTRA_ENV
property. This macro adds the rootenv
key.@INIT_<program name>_ENTITY_ENV+@
– during the build, this macro adds the dictionary of environment variables and their values defined in theEXTRA_ENV
property to the manually defined variables. This macro does not add the rootenv
key.
@INIT_EXTERNAL_ENTITIES@
– during the build, this macro is replaced with the list of system programs linked to the application and their IPC channels,main()
function arguments, and values of environment variables.
Example init.yaml.in template
init.yaml.in
When building the Einit
program from this template, the following init.yaml file will be generated:
init.yaml
security.psl.in template
The security.psl.in
template is used to automatically generate a part of the security.psl
file prior to building the Einit
program using CMake
tools.
The security.psl
file contains part of the solution security policy description.
When using the security.psl.in
template, you do not have to manually add EDL descriptions of system programs to the security.psl
file.
The security.psl.in
template must contain a manually created solution security policy description, including the following declarations:
- Set the global parameters of a solution security policy
- Include PSL files in a solution security policy description
- Include EDL files of application software in a solution security policy description
- Create security model objects
- Bind methods of security models to security events
- Create security audit profiles
To automatically include system programs, the @INIT_EXTERNAL_ENTITIES@
macro must be used.
Example security.psl.in template
security.psl.in
CMake libraries in KasperskyOS Community Edition
This section contains a description of the libraries that are provided in KasperskyOS Community Edition for automatically building a KasperskyOS-based solution.
platform library
The platform
library contains the following commands:
initialize_platform()
is the command for initializing theplatform
library.The
initialize_platform()
command can be called with theFORCE_STATIC
parameter, which enables forced static linking of executable files:- By default, if the toolchain in the KasperskyOS SDK supports dynamic linking, the
initialize_platform()
command causes the-rdynamic
flag to be used automatically for building all executable files defined viaCMake
add_executable()
commands. - When calling
initialize_platform (FORCE_STATIC)
in theCMakeLists.txt
root file, the toolchain supporting dynamic linking performs static linking of executable files.
The
initialize_platform()
command can be called with theNO_NEW_VERSION_CHECK
parameter, which disables the check for SDK updates and transmission of the SDK version to the Kaspersky server.To disable the check for SDK updates and transmission of SDK version data to the Kaspersky server, use the following call during the solution build:
initialize_platform(NO_NEW_VERSION_CHECK)
. For more details about the data provision policy, see Data provision.- By default, if the toolchain in the KasperskyOS SDK supports dynamic linking, the
project_static_executable_header_default()
is the command for enabling forced static linking of executable files defined via subsequentCMake
add_executable()
commands in oneCMakeLists.txt
file. The toolchain that supports dynamic linking performs static linking of these executable files.platform_target_force_static()
is the command for enabling forced static linking of an executable file defined via theCMake
add_executable()
command. The toolchain that supports dynamic linking performs static linking of this executable file. For example, if theCMake
commandsadd_executable(client "src/client.c")
andplatform_target_force_static(client)
are called, static linking is performed for theclient
program.project_header_default()
is the command for setting compile flags.Command parameters are defined in pairs consisting of a compile flag and its value:
"FLAG_1:VALUE_1"
"FLAG_2:VALUE_2"
..."FLAG_N:VALUE_N"
. TheCMake
platform
library converts these pairs into compiler parameters. Frequently used compile flags for C and C++ compilers from the GCC set and the values of these flags are presented in the table below.Compile flags
YES
valueNO
valueDefault value
STANDARD_ANSI
The ISO C90 and 1998 ISO C++ standards are used.
For C and C++ compilers, the value is converted into the parameter
-ansi
.The ISO C90 and 1998 ISO C++ standards are not used.
STANDARD_ANSI:NO
STANDARD_C99
The ISO C99 standard is used.
For a C compiler, the value is converted into the parameter
-std=c99
.The ISO C99 standard is not used.
STANDARD_C99:NO
STANDARD_GNU_C99
The ISO C99 standard with GNU extensions is used.
For a C compiler, the value is converted into the parameter
-std=gnu99
.The ISO C99 standard with GNU extensions is not used.
STANDARD_GNU_C99:NO
STANDARD_11
The ISO C11 and 2011 ISO C++ standards are used.
For a C compiler, the value is converted into the parameter
-std=c11
or-std=c1x
depending on the compiler version.For a C++ compiler, the value is converted into the parameter
-std=c++11
or-std=c++0x
depending on the compiler version.The ISO C11 and 2011 ISO C++ standards are not used.
STANDARD_11:NO
STANDARD_GNU_11
The ISO C11 and 2011 ISO C++ standards with GNU extensions are used.
For a C compiler, the value is converted into the parameter
-std=gnu1x
or-std=gnu11
depending on the compiler version.For a C++ compiler, the value is converted into the parameter
-std=gnu++0x
or-std=gnu++11
depending on the compiler version.The ISO C11 and 2011 ISO C++ standards with GNU extensions are not used.
STANDARD_GNU_11:NO
STANDARD_14
The 2014 ISO C++ standard is used.
For a C++ compiler, the value is converted into the parameter
-std=c++14
.The 2014 ISO C++ standard is not used.
STANDARD_14:NO
STANDARD_GNU_14
The 2014 ISO C++ standard with GNU extensions is used.
For a C++ compiler, the value is converted into the parameter
-std=gnu++14
.The 2014 ISO C++ standard with GNU extensions is not used.
STANDARD_GNU_14:NO
STANDARD_17
The ISO C17 and 2017 ISO C++ standards are used.
For a C compiler, the value is converted into the parameter
-std=c17
.For a C++ compiler, the value is converted into the parameter
-std=c++17
.The ISO C17 and 2017 ISO C++ standards are not used.
STANDARD_17:NO
STANDARD_GNU_17
The ISO C17 and 2017 ISO C++ standards with GNU extensions are used.
For a C compiler, the value is converted into the parameter
-std=gnu17
.For a C++ compiler, the value is converted into the parameter
-std=gnu++17
.The ISO C17 and 2017 ISO C++ standards with GNU extensions are not used.
STANDARD_GNU_17:NO
STRICT_WARNINGS
Warnings are enabled for the detection of potential issues and errors in code written in C and C++.
For C and C++ compilers, the value is converted into the following parameters:
-Wcast-qual
,-Wcast-align
,-Wundef
.For a C compiler, the parameter
-Wmissing-prototypes
is additionally used.Warnings are disabled.
STRICT_WARNINGS:YES
If compiler flags in the format
STANDART_*
are not defined through command parameters, the parameterSTANDARD_GNU_17:YES
is used by default.
When using the initialize_platform(FORCE_STATIC)
, project_static_executable_header_default()
and platform_target_force_static()
commands, you may encounter linking errors if the static variants of the required libraries are missing (for example, if they were not built or are not included in the KasperskyOS SDK). Even if the static variants of the required libraries are available, these errors may still occur because the build system searches for the dynamic variants of required libraries by default instead of the expected static variants when using the initialize_platform(FORCE_STATIC)
, project_static_executable_header_default()
and platform_target_force_static()
commands. To avoid errors, first make sure that the static variants are available. Then configure the build system to search for static libraries (although this capability may not be available for some libraries), or explicitly define linking with static libraries.
Examples of configuring the build system to search for static libraries:
Example that explicitly defines linking with a static library:
For more details about using dynamic libraries, see "Using dynamic libraries".
These commands are used in CMakeLists.txt
files for the Einit program and application software.
nk library
This section contains a description of the commands and macros of the CMake
library for working with the NK compiler.
generate_edl_file()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command generates an EDL file containing a description of the process class.
Parameters:
NAME
– name of the EDL file being created. Required parameter.PREFIX
– parameter in which you need to specify the name of the process class, excluding the name of the EDL file. For example, if the name of the process class for which the EDL file is being created is defined askl.core.NameServer
, thePREFIX
parameter must pass the valuekl.core
.EDL_COMPONENTS
– name of the component and its instance that will be included in the EDL file. For example:EDL_COMPONENTS "env: kl.Env"
. To include multiple components, you need to use multipleEDL_COMPONENTS
parameters.SECURITY
– qualified name of the security interface method that will be included in the EDL file.OUTPUT_DIR
– directory in which the EDL file will be created. The default directory is${CMAKE_CURRENT_BINARY_DIR}
.
As a result of this command, the EDL_FILE
variable is exported and contains the path to the generated EDL file.
Example call:
For an example of using this command, see the article titled "CMakeLists.txt files for building application software".
Page topnk_build_idl_files()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating .idl.h
files for one or more defined IDL files using the NK compiler.
Parameters:
NAME
– name of theCMake
target for building.idl.h
files. If a target has not yet been created, it will be created by usingadd_library()
with the specified name. Required parameter.NOINSTALL
– if this option is specified, files will only be generated in the working directory and will not be installed in global directories:${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}
.NK_MODULE
– parameter in which you need to specify the package name, excluding the name of the IDL file. For example, if the package name in the IDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.WORKING_DIRECTORY
– working directory for calling the NK compiler, which is${CMAKE_CURRENT_BINARY_DIR}
by default.DEPENDS
– additional build targets on which the IDL file depends.To add multiple targets, you need to use multiple
DEPENDS
parameters.IDL
– path to the IDL file for which the idl.h file is being generated. Required parameter.To add multiple IDL files, you need to use multiple
IDL
parameters.If one IDL file imports another IDL file, idl.h files need to be generated in the order necessary for compliance with dependencies (with the most deeply nested first).
NK_FLAGS
– additional flags for the NK compiler.
Example call:
For an example of using this command, see the article titled "CMakeLists.txt files for building application software".
Page topnk_build_cdl_files()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating .cdl.h
files for one or more defined CDL files using the NK compiler.
Parameters:
NAME
– name of theCMake
target for building.cdl.h
files. If a target has not yet been created, it will be created by usingadd_library()
with the specified name. Required parameter.NOINSTALL
– if this option is specified, files will only be generated in the working directory and are not installed in global directories:${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}
.IDL_TARGET
– target when building.idl.h
files for IDL files containing descriptions of endpoints provided by components described in CDL files.NK_MODULE
– parameter in which you need to specify the component name, excluding the name of the CDL file. For example, if the component name in the CDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.WORKING_DIRECTORY
– working directory for calling the NK compiler, which is${CMAKE_CURRENT_BINARY_DIR}
by default.DEPENDS
– additional build targets on which the CDL file depends.To add multiple targets, you need to use multiple
DEPENDS
parameters.CDL
– path to the CDL file for which the.cdl.h
file is being generated. Required parameter.To add multiple CDL files, you need to use multiple
CDL
parameters.NK_FLAGS
– additional flags for the NK compiler.
Example call:
For an example of using this command, see the article titled "CMakeLists.txt files for building application software".
Page topnk_build_edl_files()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating an .edl.h
file for one defined EDL file using the NK compiler.
Parameters:
NAME
– name of theCMake
target for building an.edl.h
file. If a target has not yet been created, it will be created by usingadd_library()
with the specified name. Required parameter.NOINSTALL
– if this option is specified, files will only be generated in the working directory and are not installed in global directories:${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}
.CDL_TARGET
– target when building.cdl.h
files for CDL files containing descriptions of components of the EDL file for which the build is being performed.IDL_TARGET
– target when building .idl.h files for IDL files containing descriptions of interfaces of the EDL file for which the build is being performed.NK_MODULE
– parameter in which you need to specify the name of the process class, excluding the name of the EDL file. For example, if the process class name in the EDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.WORKING_DIRECTORY
– working directory for calling the NK compiler, which is${CMAKE_CURRENT_BINARY_DIR}
by default.DEPENDS
– additional build targets on which the EDL file depends.To add multiple targets, you need to use multiple
DEPENDS
parameters.EDL
– path to the EDL file for which the edl.h file is being generated. Required parameter.NK_FLAGS
– additional flags for the NK compiler.
Example calls:
For an example of using this command, see the article titled "CMakeLists.txt files for building application software".
Page topGenerating transport code for development in C++
The CMake
commands add_nk_idl(), add_nk_cdl() and add_nk_edl() are used to generate transport proxy objects and stubs using the nkppmeta
compiler when building a solution.
add_nk_idl()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating a *.idl.cpp.h
header file for a defined IDL file using the nkppmeta
compiler. The command also creates a library containing the transport code for the defined interface. To link to this library, use the bind_nk_targets()
command.
The generated header files contain a C++ representation for the interface and data types described in the IDL file, and the methods required for use of proxy objects and stubs.
Parameters:
NAME
— name of theCMake
target. Required parameter.IDL_FILE
— path to the IDL file. Required parameter.NK_MODULE
– parameter in which you need to specify the package name, excluding the name of the IDL file. For example, if the package name in the IDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.LANG
– parameter in which you need to specify theCXX
value.
Example call:
add_nk_cdl()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating a *.cdl.cpp.h
file for a defined CDL file using the nkppmeta
compiler. The command also creates a library containing the transport code for the defined component. To link to this library, use the bind_nk_targets()
command.
The *.cdl.cpp.h
file contains the tree of embedded components and endpoints provided by the component described in the CDL file.
Parameters:
NAME
— name of theCMake
target. Required parameter.CDL_FILE
— path to the CDL file. Required parameter.NK_MODULE
– parameter in which you need to specify the component name, excluding the name of the CDL file. For example, if the component name in the CDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.LANG
– parameter in which you need to specify theCXX
value.
Example call:
add_nk_edl()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake
.
This command creates a CMake
target for generating a *.edl.cpp.h
file for a defined EDL file using the nkppmeta
compiler. The command also creates a library containing the transport code for the server or client program. To link to this library, use the bind_nk_targets()
command.
The *.edl.cpp.h
file contains the tree of embedded components and endpoints provided by the process class described in the EDL file.
Parameters:
NAME
— name of theCMake
target. Required parameter.EDL_FILE
— path to the EDL file. Required parameter.NK_MODULE
– parameter in which you need to specify the name of the process class, excluding the name of the EDL file. For example, if the process class name in the EDL description is defined askl.core.NameServer
, thekl.core
value must be passed in theNK_MODULE
parameter.LANG
– parameter in which you need to specify theCXX
value.
Example call:
image library
This section contains a description of the commands and macros of the CMake
library named image
that is included in KasperskyOS Community Edition and contains solution image build scripts.
build_kos_qemu_image()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/image.cmake
.
The command creates a CMake
target for building a solution image for QEMU.
Parameters:
NAME
– name of theCMake
target for building a solution image. Required parameter.PERFCNT_KERNEL
– use the kernel with performance counters if it is available in KasperskyOS Community Edition.EINIT_ENTITY
– name of the executable file that will be used to start theEinit
program.EXTRA_XDL_DIR
– additional directories to include when building theEinit
program.CONNECTIONS_CFG
– path to theinit.yaml
file or init.yaml.in template.SECURITY_PSL
– path to thesecurity.psl
file or security.psl.in template.KLOG_ENTITY
– target for building theKlog
system program, which is responsible for the security audit. If the target is not specified, the audit is not performed.QEMU_FLAGS
– additional flags for running QEMU.IMAGE_BINARY_DIR_BIN
– directory for the final image and other artifacts. It matchesCMAKE_CURRENT_BINARY_DIR
by default.NO_AUTO_BLOB_CONTAINER
– solution image will not include theBlobContainer
program that is required for working with dynamic libraries in shared memory. For more details, refer to "Including the BlobContainer system program in a KasperskyOS-based solution".PACK_DEPS
,PACK_DEPS_COPY_ONLY
,PACK_DEPS_LIBS_PATH
, andPACK_DEPS_COPY_TARGET
– parameters that define the method used to add dynamic libraries to the solution image.IMAGE_FILES
– executable files of applications and system programs (except theEinit
program) and any other files to be added to the ROMFS image.To add multiple applications or files, you can use multiple
IMAGE_FILES
parameters.<path to files>
– free parameters likeIMAGE_FILES
.
Example call:
For an example of using this command, see the article titled "CMakeLists.txt files for building the Einit program".
Page topbuild_kos_hw_image()
This command is declared in the file /opt/KasperskyOS-Community-Edition-<version>toolchain/share/cmake/Modules/platform/image.cmake
.
The command creates a CMake
target for building a solution image for the hardware platform.
Parameters:
NAME
– name of theCMake
target for building a solution image. Required parameter.PERFCNT_KERNEL
– use the kernel with performance counters if it is available in KasperskyOS Community Edition.EINIT_ENTITY
– name of the executable file that will be used to start theEinit
program.EXTRA_XDL_DIR
– additional directories to include when building theEinit
program.CONNECTIONS_CFG
– path to the init.yaml file or init.yaml.in template.SECURITY_PSL
– path to the security.psl file or security.psl.in template.KLOG_ENTITY
– target for building theKlog
system program, which is responsible for the security audit. If the target is not specified, the audit is not performed.IMAGE_BINARY_DIR_BIN
– directory for the final image and other artifacts. The default directory isCMAKE_CURRENT_BINARY_DIR
.NO_AUTO_BLOB_CONTAINER
– solution image will not include theBlobContainer
program that is required for working with dynamic libraries in shared memory. For more details, refer to "Including the BlobContainer system program in a KasperskyOS-based solution".PACK_DEPS
,PACK_DEPS_COPY_ONLY
,PACK_DEPS_LIBS_PATH
, andPACK_DEPS_COPY_TARGET
– parameters that define the method used to add dynamic libraries to the solution image.IMAGE_FILES
– executable files of applications and system programs (except theEinit
program) and any other files to be added to the ROMFS image.To add multiple applications or files, you can use multiple
IMAGE_FILES
parameters.<path to files>
– free parameters likeIMAGE_FILES
.
Example call:
For an example of using this command, see the article titled "CMakeLists.txt files for building the Einit program".
Page topBuilding without CMake
This section contains a description of the scripts, tools, compilers and build templates provided in KasperskyOS Community Edition.
These tools can be used:
- In other build systems.
- To perform individual steps of the build.
- To analyze the build specifications and write a custom build system.
The general scenario for building a solution image is described in the article titled Build process overview.
Tools for building a solution
This section contains a description of the scripts, tools, compilers and build templates provided in KasperskyOS Community Edition.
Build scripts and tools
KasperskyOS Community Edition includes the following build scripts and tools:
- nk-gen-c
The NK compiler (
nk-gen-c
) generates transport code based on the IDL, CDL, and EDL descriptions. Transport code is needed for generating, sending, receiving, and processing IPC messages. - nk-psl-gen-c
The
nk-psl-gen-c
compiler generates the C-language source code of the Kaspersky Security Module based on the solution security policy description and the IDL, CDL, and EDL descriptions. Thenk-psl-gen-c
compiler also generates the C-language source code of solution security policy tests based on solution security policy tests in PAL. - einit
The
einit
tool automates the creation of code for theEinit
initializing program. This program is the first to start when KasperskyOS is loaded. Then it starts all other programs and creates IPC channels between them. - makekss
The
makekss
script creates the Kaspersky Security Module. - makeimg
The
makeimg
script creates the final boot image of the KasperskyOS-based solution with all programs to be started and the Kaspersky Security Module.
nk-gen-c
The NK compiler (nk-gen-c
) generates transport code based on the IDL, CDL, and EDL descriptions.
The nk-gen-c
compiler receives the IDL, CDL or EDL file and creates the following files:
- A
*.*dl.h
file containing the transport code. - A
*.*dl.nk.d
file that lists the created*.*dl.h
file's dependencies on the IDL and CDL files. The*.*dl.nk.d
file is created for the build system.
Syntax of the shell command for starting the nk-gen-c
compiler:
Basic parameters:
FILE
Path to the IDL, CDL, or EDL file for which you need to generate transport code.
-I
<PATH
>These parameters are used to define the paths to directories containing the auxiliary files required for generating transport code. (The auxiliary files are located in the
sysroot-*-kos/include
directory from the KasperskyOS SDK.) These parameters can also be used to define the paths to directories containing IDL and CDL files that are referenced by the file defined via theFILE
parameter.-o
<PATH
>Path to an existing directory where the created files will be placed. If this parameter is not specified, the created files will be put into the current directory.
-h
|--help
Prints the Help text.
--version
Prints the version of the
nk-gen-c
compiler.--extended-errors
This parameter provides the capability to use interface methods with one or more error parameters of user-defined IDL types. (The client works with error parameters like it works with output parameters.)
If the
--extended-errors
parameter is not specified, you can use interface methods only with onestatus
error parameter of the IDL typeUInt16
whose value is passed to the client via return code of the interface method. This mechanism is obsolete and will no longer be supported in the future, so you are advised to always specify the--extended-errors
parameter.
Selective generation of transport code
To reduce the volume of generated transport code, you can use flags for selective generation of transport code. For example, you can use the --server
flag for programs that implement endpoints, and use the --client
flag for programs that utilize the endpoints.
If no selective generation flag for transport code is specified, the nk-gen-c
compiler generates transport code with all possible methods and types for the defined IDL, CDL, or EDL file.
Flags for selective generation of transport code for an IDL file:
--types
The transport code includes the types corresponding to the IDL types from the defined IDL file, and the types corresponding to this file's imported IDL types that are used in IDL types of the defined IDL file. However, the types corresponding to imported IDL constants and to the aliases of imported IDL types are not included in the
*.idl.h
file. To use the types corresponding to imported IDL constants and to the aliases of imported IDL types, you must separately generate the transport code for the IDL files from which you are importing.--interface
The transport code corresponds to the
--types
flag, and includes the types of structures of the constant part of IPC requests and IPC responses for interface methods whose signatures are specified in the defined IDL file. In addition, the transport code contains constants indicating the sizes of IPC message arenas.--client
The transport code corresponds to the
--interface
flag, and includes the proxy object type, proxy object initialization method, and the interface methods specified in the defined IDL file.--server
The transport code corresponds to the
--interface
flag, and includes the types and dispatcher (dispatch method) used to process IPC requests corresponding to the interface methods specified in the defined IDL file.
Flags for selective generation of transport code for a CDL or EDL file:
--types
The transport code includes the types corresponding to the IDL types that are used in the method parameters of endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file).
--endpoints
The transport code corresponds to the
--types
flag, and includes the types of structures of the constant part of IPC requests and IPC responses for the methods of endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file). In addition, the transport code contains constants indicating the sizes of IPC message arenas.--client
The transport code corresponds to the
--types
flag, and includes the types of structures of the constant part of IPC requests and IPC responses for the methods of endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file). In addition, the transport code contains constants indicating the sizes of IPC message arenas, and the proxy object types, proxy object initialization methods, and methods of endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file).--server
The transport code corresponds to the
--types
flag, and includes the types and dispatchers (dispatch methods) used to process IPC requests corresponding to the endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file). In addition, the transport code contains constants indicating the sizes of IPC message arenas, and the stub types, stub initialization methods, and the types of structures of the constant part of IPC requests and IPC responses for the methods of endpoints provided by the component (for the defined CDL file) or process class (for the defined EDL file).
Printing diagnostic information about sending and receiving IPC messages
Transport code can generate diagnostic information about sending and receiving IPC messages and print this data via standard error. To generate transport code with these capabilities, use the following parameters:
--trace-client-ipc
{headers
|dump
}The code for printing diagnostic information is executed directly before the
Call()
system call is executed and immediately after it is executed. If theheaders
value is specified, the diagnostic information includes the endpoint method ID (MID), the endpoint ID (RIID), the size of the constant part of the IPC message (in bytes), the contents of the IPC message arena handle, the size of the IPC message arena (in bytes), and the size of the utilized part of the IPC message arena (in bytes). If thedump
value is specified, the diagnostic information additionally includes the contents of the constant part and arena of the IPC message in hexadecimal format.When using this parameter, you must either specify the selective generation flag for transport code
--client
or refrain from specifying a selective generation flag for transport code.--trace-server-ipc
{headers
|dump
}The code for printing diagnostic information is executed directly before calling the function that implements the interface method, and immediately after the completion of this function. In other words, it is executed when the dispatcher (dispatch method) is called in the interval between execution of the
Recv()
andReply()
system calls. If theheaders
value is specified, the diagnostic information includes the endpoint method ID (MID), the endpoint ID (RIID), the size of the constant part of the IPC message (in bytes), the contents of the IPC message arena handle, the size of the IPC message arena (in bytes), and the size of the utilized part of the IPC message arena (in bytes). If thedump
value is specified, the diagnostic information additionally includes the contents of the constant part and arena of the IPC message in hexadecimal format.When using this parameter, you must either specify the selective generation flag for transport code
--server
or refrain from specifying a selective generation flag for transport code.--ipc-trace-method-filter
<METHOD
>[,METHOD
]...Diagnostic information is printed if only the defined interface methods are called. For the
METHOD
value, you can use the interface method name or the construct <package name
>:
<interface method name
>. The package name and interface method name are specified in the IDL file.If this parameter is not specified, diagnostic information is printed when any interface method is called.
This parameter can be specified multiple times. For example, you can specify all required interface methods in one parameter or specify each required interface method in a separate parameter.
nk-psl-gen-c
The nk-psl-gen-c
compiler generates the C-language source code of the Kaspersky Security Module based on the solution security policy description and the IDL, CDL, and EDL descriptions. This code is used by the makekss script.
The nk-psl-gen-c
compiler can also generate the C-language source code of solution security policy tests based on solution security policy tests in PAL.
Syntax of the shell command for starting the nk-psl-gen-c
compiler:
Parameters:
INPUT
Path to the top-level file of the solution security policy description. This is normally the
security.psl
file.- {
-I
|--include-dir
}DIR
>These parameters are used to define the paths to directories containing IDL, CDL, and EDL files pertaining to the solution, and the paths to directories containing auxiliary files from the KasperskyOS SDK (
common
,sysroot-*-kos/include
,toolchain/include
). - {
-o
|--output
}FILE
>Path to the file that will save the source code of the Kaspersky Security Module and (optionally) the source code of solution security policy tests. The path must include existing directories.
--out-tests
<FILE
>Path to the file that will save the source code of the solution security policy tests.
- {
-t
|--tests
}ARG
>Defines whether the source code of solution security policy tests must be generated.
ARG
can take the following values:skip:
– source code of tests is not generated. This value is used by default if the-t, --tests
<ARG
> parameter is not specified.generate:
– source code of tests is generated. If the source code of tests is generated, you are advised to use the--out-tests
<FILE
> parameter. Otherwise, the source code of tests will be saved in the same file containing the source code of the Kaspersky Security Module, which may lead to errors during the build.
- {
-a
|--audit
}FILE
>Path to the file that will save the C-language source code of the audit decoder.
-h
|--help
Prints the Help text.
--version
Prints the version of the
nk-psl-gen-c
compiler.
einit
The einit
tool automates the creation of code for the Einit initializing program.
The einit
tool receives the solution initialization description (the init.yaml
file by default) and EDL, CDL and IDL descriptions, and creates a file containing the source code of the Einit
initializing program. Then the Einit
program must be built using the C-language cross compiler that is provided in KasperskyOS Community Edition.
Syntax for using the einit
tool:
Parameters:
FILE
Path to the
init.yaml
file.-I PATH
Path to the directory containing the auxiliary files (including EDL, CDL and IDL descriptions) required for generating the initializing program. By default, these files are located in the directory
/opt/KasperskyOS-Community-Edition-<version>/sysroot-aarch64-kos/include
.-o, --out-file PATH
Path to the created .c file containing the code of the initializing program.
-h, --help
Displays the Help text.
makekss
The makekss
script creates the Kaspersky Security Module.
The script calls the nk-psl-gen-c compiler to generate the source code of the security module, then compiles the resulting code by calling the C compiler that is provided in KasperskyOS Community Edition.
The script creates the security module from the solution security policy description.
Syntax for using the makekss
script:
Parameters:
FILE
Path to the top-level file of the solution security policy description.
--target=ARCH
Processor architecture for which the build is intended.
--module=-lPATH
Path to the
ksm_kss
library. This key is passed to the C compiler for linking to this library.--with-nk=PATH
Path to the
nk-psl-gen-c
compiler that will be used to generate the source code of the security module. By default, the compiler is located in/opt/KasperskyOS-Community-Edition-<version>/toolchain/bin/nk-psl-gen-c
.--with-nktype="TYPE"
Indicates the type of NK compiler that will be used. To use the
nk-psl-gen-c
compiler, indicate thepsl
type.--with-nkflags="FLAGS"
Parameters used when calling the
nk-psl-gen-c
compiler.The
nk-psl-gen-c
compiler will require access to all EDL, CDL and IDL descriptions. To enable thenk-psl-gen-c
compiler to find these descriptions, you need to pass the paths to these descriptions in the--with-nkflags
parameter by using the-I
switch of thenk-psl-gen-c
compiler.--output=PATH
Path to the created security module file.
--with-cc=PATH
Path to the C compiler that will be used to build the security module. The compiler provided in KasperskyOS Community Edition is used by default.
--with-cflags=FLAGS
Parameters used when calling the C compiler.
-h, --help
Displays the Help text.
makeimg
The makeimg
script creates the final boot image of the KasperskyOS-based solution with all executable files of programs and the Kaspersky Security Module.
The script receives a list of files, including the executable files of all applications that need to be added to ROMFS of the loaded image, and creates the following files:
- Solution image
- Solution image without character tables (
.stripped
) - Solution image with debug character tables (
.dbg.syms
)
Syntax for using the makeimg script:
Parameters:
FILES
List of paths to files, including the executable files of all applications that need to be added to ROMFS.
The security module (
ksm.module
) must be explicitly specified, or else it will not be included in the solution image. TheEinit
application does not need to be indicated because it will be automatically included in the solution image.--target=ARCH
Architecture for which the build is intended.
--sys-root=PATH
Path to the root directory sysroot. By default, this directory is located in
/opt/KasperskyOS-Community-Edition-version/sysroot-aarch64-kos/
.--with-toolchain=PATH
Path to the set of auxiliary tools required for the solution build. By default, these tools are located in
/opt/KasperskyOS-Community-Edition-<version>/toolchain/
.--ldscript=PATH
Path to the linker script required for the solution build. By default, this script is located in
/opt/KasperskyOS-Community-Edition-<version>/libexec/aarch64-kos/
.--img-src=PATH
Path to the precompiled KasperskyOS kernel. By default, the kernel is located in
/opt/KasperskyOS-Community-Edition-<version>/libexec/aarch64-kos/
.--img-dst=PATH
Path to the created image file.
--with-init=PATH
Path to the executable file of the
Einit
initializing program.--with-extra-asflags=FLAGS
Additional flags for the AS Assembler.
--with-extra-ldflags=FLAGS
Additional flags for the LD Linker.
-h, --help
Displays the Help text.
Cross compilers
The toolchain provided in the KasperskyOS SDK includes one or more GCC compilers. The toolchain/bin
directory contains the following files:
- Executable files of compilers (for example,
x86_64-pc-kos-gcc
,arm-kos-g++
) - Executable files of linkers (for example,
x86_64-pc-kos-ld
,arm-kos-ld
) - Executable files of assemblers (for example,
x86_64-pc-kos-as
,arm-kos-as
)
In addition to standard macros, an additional macro __KOS__=1
is defined in GCC. Use of this macro lets you simplify porting of the software code to KasperskyOS, and also simplifies development of platform-independent programs.
To view the list of standard macros of GCC, run the following command:
Linker operation specifics
When building the executable file of an application, by default the linker links the following libraries in the specified order:
- libc is the standard C library.
- libm is the library that implements the mathematical functions of the standard C language library.
- libvfs_stubs is the library that contains stubs of I/O functions (for example,
open
,socket
,read
,write
). - libkos is the library for accessing the KasperskyOS core endpoints.
- libenv is the library of the subsystem for configuring the environment of applications (environment variables, arguments of the
main
function, and custom configurations). - libsrvtransport-u is the library that supports IPC between processes and the kernel.
Example build without using CMake
Below is an example of a script for building a basic example. This example contains a single application called Hello
, which does not provide any endpoints.
The provided script is intended only for demonstrating the build commands being used.
build.sh