KasperskyOS Community Edition 1.3
[Topic sc_application_start]

Обзор: Einit и init.yaml

Инициализирующая программа Einit

При запуске решения ядро KasperskyOS находит в образе решения и запускает исполняемый файл с именем Einit, то есть инициализирующую программу. Инициализирующая программа выполняет следующие действия:

  • создает и запускает процессы при запуске решения;
  • создает IPC-каналы между процессами при запуске решения (статически создает IPC-каналы).

Процесс инициализирующей программы имеет класс Einit.

Генерация исходного кода инициализирующей программы

В составе KasperskyOS SDK поставляется утилита einit, которая позволяет генерировать исходный код инициализирующей программы на языке C. Стандартным способом использования утилиты einit является интеграция ее вызова в один из шагов сборочного скрипта, в результате которого генерируется файл einit.c, содержащий исходный код инициализирующей программы. На одном из следующих шагов сборочного скрипта необходимо скомпилировать файл einit.c в исполняемый файл Einit и включить в образ решения.

Для инициализирующей программы не требуется создавать файлы формальной спецификации. Эти файлы поставляются в составе KasperskyOS SDK и автоматически применяются при сборке решения. Однако класс процесса Einit должен быть указан в файле security.psl.

Утилита einit генерирует исходный код инициализирующей программы основе init-описания, представляющего собой текстовый файл, который обычно имеет имя init.yaml.

Синтаксис init.yaml

Init-описание содержит данные в формате YAML, которые идентифицируют:

  • Процессы, исполнение которых начинается при запуске решения.
  • IPC-каналы, которые создаются при запуске решения и используются процессами для взаимодействия между собой (не с ядром).

Эти данные представляют собой словарь с ключом entities, содержащий список словарей процессов. Ключи словаря процесса приведены в таблице ниже.

Ключи словаря процесса в init-описании

Ключ

Обязательный

Значение

name

Да

Имя класса процесса (из EDL-описания).

task

Нет

Имя процесса. Если его не указать, то будет взято имя класса процесса. У каждого процесса должно быть уникальное имя.

Можно запустить несколько процессов одного класса, но с разными именами.

path

Нет

Имя исполняемого файла в ROMFS (в образе решения). Если его не указать, то будет взято имя класса процесса без префиксов и точек. Например, процессы классов Client и net.Client, для которых не указано имя исполняемого файла, будут запущены из файла Client.

Можно запустить несколько процессов из одного исполняемого файла.

connections

Нет

Список словарей IPC-каналов процесса. Этот список задает статически создаваемые IPC-каналы, клиентскими IPC-дескрипторами которых будет владеть процесс. По умолчанию этот список пуст. (Помимо статически создаваемых IPC-каналов процессы могут использовать динамически создаваемые IPC-каналы.)

args

Нет

Список параметров запуска программы (параметры функции main()). Максимальный размер одного элемента списка составляет 1024 байта.

env

Нет

Словарь переменных окружения программы. Ключами в этом словаре являются имена переменных окружения. Максимальный размер значения переменной окружения составляет 65524 байта.

Ключи словаря IPC-канала процесса приведены в таблице ниже.

Ключи словаря IPC-канала в init-описании

Ключ

Обязательный

Значение

id

Да

Имя IPC-канала, которое может быть задано как конкретным значением, так и ссылкой вида

{var: <имя константы>, include: <путь к заголовочному файлу>}.

target

Да

Имя процесса, который будет владеть серверным дескриптором IPC-канала.

В начало
[Topic einit_overview]

Примеры init-описаний

Здесь приведены примеры init-описаний, демонстрирующие различные аспекты запуска процессов.

Система сборки может автоматически создавать init-описание на основе шаблона init.yaml.in.

Запуск клиента и сервера и создание IPC-канала между ними

В этом примере будут запущены процесс класса Client и процесс класса Server. Имена процессов не указаны, поэтому они будут совпадать с именами классов процессов. Имена исполняемых файлов также не указаны, они также будут совпадать с именами классов процессов. Процессы будут соединены IPC-каналом с именем server_connection.

init.yaml

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

Запуск процессов из заданных исполняемых файлов

В этом примере будут запущены процесс класса Client из исполняемого файла с именем cl, процесс класса ClientServer из исполняемого файла с именем csr и процесс класса MainServer из исполняемого файла с именем msr. Имена процессов не указаны, поэтому они будут совпадать с именами классов процессов.

init.yaml

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

Запуск двух процессов из одного исполняемого файла

В этом примере будут запущены процесс класса Client из исполняемого файла с именем Client, а также два процесса классов MainServer и BkServer из исполняемого файла с именем srv. Имена процессов не указаны, поэтому они будут совпадать с именами классов процессов.

init.yaml

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

Запуск двух серверов одного класса и клиента и создание IPC-каналов между клиентом и серверами

В этом примере будут запущены процесс класса Client (с именем Client) и два процесса класса Server с именами UserServer и PrivilegedServer. Клиент будет соединен с серверами IPC-каналами с именами server_connection_us и server_connection_ps. Имена исполняемых файлов не указаны, поэтому они будут совпадать с именами классов процессов.

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

Установка параметров запуска и переменных окружения программ

В этом примере будут запущены процесс класса VfsFirst (с именем VfsFirst) и процесс класса VfsSecond (с именем VfsSecond). Программа, которая будет исполняться в контексте процесса VfsFirst, будет запущена с параметром -f /etc/fstab, а также получит переменную окружения ROOTFS со значением ramdisk0,0 / ext2 0 и переменную окружения UNMAP_ROMFS со значением 1. Программа, которая будет исполняться в контексте процесса VfsSecond, будет запущена с параметром -l devfs /dev devfs 0. Имена исполняемых файлов не указаны, поэтому они будут совпадать с именами классов процессов.

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
В начало
[Topic using_einit]

Запуск процессов с помощью системной программы ExecutionManager

Компонент ExecutionManager предоставляет интерфейс на языке C++ для создания, запуска и остановки процессов в решениях, построенных на базе KasperskyOS.

Интерфейс компонента ExecutionManager не подходит для использования в коде, написанном на языке C. Для управления процессами на языке C используйте интерфейс task.h библиотеки libkos.

Используя компонент ExecutionManager можно запускать процессы из:

  • исполняемого файла, для которого известно его расположение в файловой системе;
  • исполняемого файла, установленного компонентом PackageManager в решение на базе KasperskyOS из KPA-пакета.

API компонента ExecutionManager представляет собой надстройку над IPC, которая позволяет упростить процесс разработки программ. ExecutionManager является отдельной системной программой, доступ к которой осуществляется через IPC, но при этом разработчикам предоставляется клиентская библиотека, которая скрывает необходимость использования IPC-вызовов напрямую.

Программный интерфейс компонента ExecutionManager описан в статье "Компонент ExecutionManager".

Сценарий использования компонента ExecutionManager

Здесь и далее клиентом называется приложение, использующее API компонента ExecutionManager для управления другими приложениями.

Типовой сценарий использования компонента ExecutionManager включает следующие шаги:

  1. Добавление программы ExecutionManager в решение. Чтобы добавить ExecutionManager в решение, необходимо:
    find_package (execution_manager REQUIRED) include_directories (${execution_manager_INCLUDE}) add_subdirectory (execution_manager)

    Для работы программы ExecutionManager необходима программа BlobContainer. Эта программа автоматически добавляется в решение при добавлении ExecutionManager.

    • Компонент ExecutionManager поставляется в составе SDK в виде набора статических библиотек и заголовочных файлов и собирается под конкретное решение с помощью CMake-команды create_execution_manager_entity() из CMake-библиотеки execution_manager.

      Чтобы собрать программу ExecutionManager, необходимо в корневой директории проекта создать директорию с именем execution_manager, а в ней создать файл CMakeLists.txt, в котором содержится команда create_execution_manager_entity().

      CMake-команда create_execution_manager_entity() принимает следующие параметры:

      Обязательный параметр ENTITY, в котором указывается имя исполняемого файла для программы ExecutionManager.

      Опциональные параметры:

      • DEPENDS - дополнительные зависимости для сборки программы ExecutionManager.
      • MAIN_CONN_NAME - имя IPC-канала для соединения с процессом ExecutionManager. Должно совпадать со значением переменной mainConnection при обращении к API ExecutionManager в коде клиента.
      • ROOT_PATH - путь к корневой директории для служебных файлов программы ExecutionManager, по умолчанию "/ROOT".
      • VFS_CLIENT_LIB - имя клиентской транспортной библиотеки для подключения программы ExecutionManager к программе VFS.
    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})
    • При сборке решения (файл CMakeLists.txt для программы Einit) добавить следующие исполняемые файлы в образ решения:
      • исполняемый файл программы ExecutionManager;
      • исполняемый файл программы BlobContainer.
  2. Компоновка исполняемого файла клиента с клиентской прокси-библиотекой ExecutionManager, для чего необходимо в файле CMakeLists.txt для сборки клиента добавить следующую команду:
    target_link_libraries (<имя CMake-цели для сборки клиента> ${execution_manager_EXECMGR_PROXY})
  3. Добавление разрешений для необходимых событий в описание политики безопасности решения:
    1. Чтобы программа ExecutionManager могла запускать другие процессы, политика безопасности решения должна разрешать следующие взаимодействия для класса процессов execution_manager.ExecMgrEntity:
      • События безопасности вида execute для всех классов запускаемых процессов.
      • Доступ ко всем службам программы VFS.
      • Доступ ко всем службам программы BlobContainer.
      • Доступ к службам ядра Sync, Task, VMM, Thread, HAL, Handle, FS, Notice, CM и Profiler (их описания находятся в директории sysroot-*-kos/include/kl/core из состава SDK).
    2. Чтобы клиент мог обращаться к программе ExecutionManager, политика безопасности решения должна разрешать следующие взаимодействия для класса клиентского процесса:
      • Доступ к соответствующим службам программы ExecutionManager (их описания находятся в директории sysroot-*-kos/include/kl/execution_manager из состава SDK).
  4. Использование API программы ExecutionManager в коде клиента.

    Для этого необходимо использовать заголовочный файл component/execution_manager/kos_ipc/execution_manager_proxy.h. Подробнее см. "Компонент ExecutionManager".

В начало
[Topic app_static_start]

Обзор: программа Env

Системная программа Env предназначена для установки параметров запуска и переменных окружения программ. Если программа Env включена в решение, то процессы, соединенные IPC-каналом с процессом Env, при своем запуске автоматически отправляют IPC-запросы этой программе и получают параметры запуска и переменные окружения.

Использование системной программы Env является устаревшим способом установки параметров запуска и переменных окружения программ. Установку параметров запуска и переменных окружения программ нужно выполнять через файл init.yaml.in или init.yaml.

Если значение параметра запуска или переменной окружения программы задано как через программу Env, так и через файл init.yaml.in или init.yaml, то будет применяться значение, заданное через программу Env.

Чтобы использовать программу Env в решении, необходимо:

  1. Разработать код программы Env, используя макросы и функции из заголовочного файла sysroot-*-kos/include/env/env.h из состава KasperskyOS SDK.
  2. Собрать исполняемый файл программы Env, скомпоновав его с библиотекой env_server из состава KasperskyOS SDK.
  3. В init-описании указать, что необходимо запустить процесс Env и соединить с ним другие процессы (Env при этом является сервером). Имя IPC-канала задается макросом ENV_SERVICE_NAME, определенным в заголовочном файле env.h.
  4. Включить исполняемый файл Env в образ решения.

Исходный код программы Env

В исходном коде программы Env используются следующие макросы и функции из заголовочного файла env.h:

  • ENV_REGISTER_ARGS(name,argarr) – установить параметры запуска argarr для программы, которая будет исполняться в контексте процесса с именем name.
  • ENV_REGISTER_VARS(name,envarr) – установить переменные окружения envarr для программы, которая будет исполняться в контексте процесса с именем name.
  • ENV_REGISTER_PROGRAM_ENVIRONMENT(name,argarr,envarr) – установить параметры запуска argarr и переменные окружения envarr для программы, которая будет исполняться в контексте процесса с именем name.
  • envServerRun() – инициализировать серверную часть программы Env, чтобы она могла отвечать на IPC-запросы.

Примеры использования программы Env

В начало
[Topic env_overview]

Примеры установки параметров запуска и переменных окружения программ с помощью Env

Использование системной программы Env является устаревшим способом установки параметров запуска и переменных окружения программ. Установку параметров запуска и переменных окружения программ нужно выполнять через файл init.yaml.in или init.yaml.

Если значение параметра запуска или переменной окружения программы задано как через программу Env, так и через файл init.yaml.in или init.yaml, то будет применяться значение, заданное через программу Env.

Пример установки параметров запуска программы

Исходный код программы Env, которая при запуске процесса с именем NetVfs передаст ему два параметра запуска программы: -l devfs /dev devfs 0 и -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; }

Пример установки переменных окружения программы

Исходный код программы Env, которая при запуске процесса с именем Vfs3 передаст ему две переменных окружения программы: ROOTFS=ramdisk0,0 / ext2 0 и 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; }
В начало
[Topic using_env_app]