KasperskyOS Community Edition 1.3

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:

Example structure of project directories

example$ tree . ├── CMakeLists.txt ├── hello │ ├── CMakeLists.txt │ ├── src │ │ ├── hello.c ├── einit │ ├── CMakeLists.txt │ ├── src │ │ ├── init.yaml.in │ │ ├── security.psl.in ├── resources │ ├── Hello.idl │ ├── Hello.cdl │ ├── Hello.edl

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

#!/bin/bash # Script to be run in the project root. # You can get information about the cmake tool run parameters # via the shell command cmake --help, and from # the official CMake documentation. export SDK_PREFIX="/opt/KasperskyOS-Community-Edition-<version>" export TARGET="aarch64-kos" export BOARD="RPI4_BCM2711" export CMAKE="$SDK_PREFIX/toolchain/bin/cmake" export BUILD="build" # Initialize the build system $CMAKE \ -G "Unix Makefiles" \ -D CMAKE_BUILD_TYPE:STRING=Release \ -D CMAKE_TOOLCHAIN_FILE=$SDK_PREFIX/toolchain/share/toolchain-$TARGET-clang.cmake \ -D BOARD="$BOARD" \ -S . \ -B $BUILD # Build # To build a solution image for QEMU, you must specify the target defined in the # NAME parameter of the CMake command build_kos_qemu_image() in the CMakeLists.txt file # for building the Einit program. # To build a solution image for the hardware platform, you must specify the target # defined in the NAME parameter of the CMake command build_kos_hw_image() in the # CMakeLists.txt file for building the Einit program. # To build an SD card image for the hardware platform, you must specify the target # defined in the IMAGE_NAME parameter of the CMake command build_sd_image() in the # CMakeLists.txt file for building the Einit program. # To build a solution image for QEMU and start QEMU with this image, you must # specify the sim target. $CMAKE --build $BUILD --target sim

In this section

CMakeLists.txt root file

CMakeLists.txt files for building applications

CMakeLists.txt file for building the Einit program

init.yaml.in template

security.psl.in template

Page top
[Topic cmake_using_sdk_cmake]

CMakeLists.txt root file

The CMakeLists.txt root file contains general build instructions for the entire solution.

The CMakeLists.txt root file must contain the following commands:

  • cmake_minimum_required (VERSION 3.25) indicates the minimum supported version of CMake.

    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 the platform library of CMake.
  • initialize_platform() initializes the platform library.
  • project_header_default("STANDARD_GNU_17: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-*-kos/lib/cmake/<program name>/<program name>-config.cmake

  • The Einit initializing program must be built using the add_subdirectory(einit) command.
  • All applications to be built must be added by using the add_subdirectory(<program directory name>) command.

Example CMakeLists.txt root file

CMakeLists.txt

cmake_minimum_required(VERSION 3.25) project (example) # Initializes the CMake library for the KasperskyOS SDK. include (platform) initialize_platform () # Set the linker and compiler flags. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Add package importing components for working with Virtual File System. # Components are imported from the following file: /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/vfs/vfs-config.cmake find_package (vfs REQUIRED COMPONENTS ENTITY CLIENT_LIB) include_directories (${vfs_INCLUDE}) # Build the Hello application. add_subdirectory (hello) # Build the Einit initializing program. add_subdirectory (einit)
Page top
[Topic cmake_lists_root]

CMakeLists.txt files for building applications

The CMakeLists.txt file for building an application must contain the following commands:

  • include (platform/nk) connects the CMake library for working with the NK compiler.
  • project_header_default ("STANDARD_GNU_17: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:
    1. idl.h files are generated by the nk_build_idl_files() command
    2. cdl.h files are generated by the nk_build_cdl_files() command
    3. edl.h files are generated by the nk_build_edl_files() command
  • 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 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-*-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 the EXTRA_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 the init.yaml file and must comply with its syntax requirements.

    Example of creating an IPC channel between a Client process and a Server 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 the init.yaml file when building a solution, you must define the EXTRA_ARGS and EXTRA_ENV properties and assign the appropriate values to them.

    Note the indentations at the beginning of strings in the EXTRA_ARGS and EXTRA_ENV properties. These indentations are necessary to correctly insert values into the init.yaml file and must comply with its syntax requirements.

    Example of sending the Client program the "-v" argument of the main() function and the environment variable VAR1 set to VALUE1:

    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 the init.yaml file when processing macros of the init.yaml.in template.

Example CMakeLists.txt file for building a simple application

CMakeLists.txt

project (hello) # Include the CMake library named nk for working with the NK compiler (nk-gen-c). include (platform/nk) # Set the linker and compiler flags. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Define the name of the project that includes the program. set (LOCAL_MODULE_NAME "example") # Define the program name. set (TASK_NAME "Hello") # Please note the contents of the init.yaml.in and security.psl.in templates # They define program names as ${LOCAL_MODULE_NAME}.${TASK_NAME} # Define the targets that will be used to create the generated files of the program. set (TASK_IDL_TARGET ${TASK_NAME}_idl) set (TASK_CDL_TARGET ${TASK_NAME}_cdl) set (TASK_EDL_TARGET ${TASK_NAME}_edl) # Add the idl.h file build target. nk_build_idl_files (${TASK_IDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} IDL "../resources/Hello.idl" ) # Add the cdl.h file build target. nk_build_cdl_files (${TASK_CDL_TARGET} IDL_TARGET ${TASK_IDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} CDL "../resources/Hello.cdl" ) # Add the EDL file build target.The EDL_FILE variable is exported # and contains the path to the generated EDL file. generate_edl_file (${TASK_NAME} PREFIX ${LOCAL_MODULE_NAME} ) # Add the edl.h file build target. nk_build_edl_files (${TASK_EDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} EDL ${EDL_FILE} ) # Define the target for the program build. add_executable (${TASK_NAME} "src/hello.c") # Libraries that are linked to the program during the build. target_link_libraries (${TASK_NAME} PUBLIC vfs::client # The program uses file I/O # and must be connected as a client to VFS ) # Add a dependency on the Hello_edl target to the Hello target. # The edl.h file must be generated before the Hello target is built. add_dependencies (${TASK_NAME} ${TASK_EDL_TARGET})
Page top
[Topic cmake_lists_applied]

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 the CMake library that contains the solution image build scripts.
  • project_header_default ("STANDARD_GNU_17: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-*-kos/lib/cmake/<program name>/<program name>-config.cmake

  • 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 the EXTRA_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 the init.yaml file and must comply with its syntax requirements.

    For example, the VFS program does not have a channel for connecting to the Env 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 the CMakeLists.txt file for building the Einit program:

    set_target_properties (vfs_entity::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 the init.yaml file when building a solution, you must define the EXTRA_ARGS and EXTRA_ENV properties and assign the appropriate values to them.

    Note the indentations at the beginning of strings in the EXTRA_ARGS and EXTRA_ENV properties. These indentations are necessary to correctly insert values into the init.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:

    set_target_properties (vfs_entity::entity PROPERTIES EXTRA_ARGS " - \"-f\" - \"fstab\"" EXTRA_ENV " ROOTFS: 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 the ENTITIES variable containing a list of executable files of all programs included in the solution.
  • One or more commands for building the solution image:
    • build_kos_hw_image() creates the target for building a solution image for the hardware platform.
    • build_sd_image() – creates the target for building an SD card image for running a solution on 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

project (einit) # Connect the library containing solution image build scripts. include (platform/image) include (${KL_SDK_ROOT_PATH}/common/build-sd-image.cmake) # Set the linker and compiler flags. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Define the CONNECTIONS_CFG_FILE variable containing the path to the init.yaml.in template. set (CONNECTIONS_CFG_FILE "src/init.yaml.in") # Define the SECURITY_PSL variable containing the path to the security.psl.in template. set (SECURITY_PSL "src/security.psl.in") # Configure the VFS program. # By default, the VFS program is not mapped to a program implementing a block device. # If you need to use a block device, such as ata from the ata component, # you must define this device in the blkdev::entity_REPLACEMENT variable # For more information about exported variables and properties of the VFS program, # see /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/vfs/vfs-config.cmake # find_package(ata) # set_target_properties (vfs_entity::entity PROPERTIES blkdev::entity_REPLACEMENT ata::entity) # In the simplest case, you do not need to interact with a drive. # For this reason, we set the value of the blkdev::entity_REPLACEMENT variable equal to an empty string set_target_properties (vfs_entity::entity PROPERTIES blkdev::entity_REPLACEMENT "") # Define the ENTITIES variable with a list of executable files of programs. # It is important to include all programs that are part of the project, except the Einit program. # Please note that the name of the executable file of a program must # match the name of the target indicated in add_executable() in the CMakeLists.txt file for building this program. set(ENTITIES vfs_entity::entity Hello ) # Create the build target named kos-image, which is a solution image for the hardware platform. build_kos_hw_image (kos-image EINIT_ENTITY EinitHw CONNECTIONS_CFG ${CONNECTIONS_CFG_FILE} SECURITY_PSL ${SECURITY_PSL} IMAGE_FILES ${ENTITIES} ) # Create a build target named sd-image that can be used to create an SD-card image # for running a solution on the hardware platform. build_sd_image (sd-image KOS_IMAGE_TARGET kos-image ) # Create the build target named kos-qemu-image, which is a solution image for QEMU. build_kos_qemu_image (kos-qemu-image EINIT_ENTITY EinitQemu CONNECTIONS_CFG ${CONNECTIONS_CFG_FILE} SECURITY_PSL ${SECURITY_PSL} IMAGE_FILES ${ENTITIES} )
Page top
[Topic cmake_lists_einit]

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. The target and id fields are filled according to the connect.yaml files from KasperskyOS Community Edition located in /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-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 root connections 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 the EXTRA_CONNECTIONS property when building this program.
  • If you need to pass main() function arguments defined in the EXTRA_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 the main() function defined in the EXTRA_ARGS property. This macro adds the root args key.
    • @INIT_<program name>_ENTITY_ARGS+@ – during the build, this macro adds the list of main() function arguments defined in the EXTRA_ARGS property to the list of manually defined arguments. This macro does not add the root args 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 the EXTRA_ENV property. This macro adds the root env key.
    • @INIT_<program name>_ENTITY_ENV+@ – during the build, this macro adds the dictionary of environment variables and their values defined in the EXTRA_ENV property to the manually defined variables. This macro does not add the root env 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

entities: - name: ping.Client connections: # The "Client" program can query the "Server" - target: ping.Server id: server_connection @INIT_Client_ENTITY_CONNECTIONS+@ @INIT_Client_ENTITY_ARGS@ @INIT_Client_ENTITY_ENV@ - name: ping.Server @INIT_Server_ENTITY_CONNECTIONS@ @INIT_EXTERNAL_ENTITIES@

When building the Einit program from this template, the following init.yaml file will be generated:

init.yaml

entities: - name: ping.Client connections: # The "Client" program can query the "Server" - target: ping.Server id: server_connection - target: kl.VfsEntity id: {var: _VFS_CONNECTION_ID, include: vfs/defs.h} args: - "-v" env: VAR1: VALUE1 - name: ping.Server connections: - target: kl.VfsEntity id: {var: _VFS_CONNECTION_ID, include: vfs/defs.h} - name: kl.VfsEntity path: VFS args: - "-f" - "fstab" env: ROOTFS: ramdisk0,0 / ext2
Page top
[Topic cmake_yaml_templates]

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

execute: kl.core.Execute use nk.base._ use EDL Einit use EDL kl.core.Core use EDL Client use EDL Server @INIT_EXTERNAL_ENTITIES@ /* Startup of programs is allowed */ execute { grant () } /* Sending and receiving requests, responses and errors is allowed. */ request { grant () } response { grant () } error { grant () } /* Queries via the security interface are ignored. */ security { grant () }
Page top
[Topic cmake_psl_templates]