API определен в заголовочном файле sysroot-*-kos/include/kos/task.h из состава KasperskyOS SDK.
API позволяет создавать, запускать и завершать процессы, а также статически создавать IPC-каналы и передавать дескрипторы.
Сведения о функциях API приведены в таблице ниже.
Библиотека libkos также предоставляет низкоуровневый API для управления процессами. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.
Создание процесса
Чтобы создать процесс, нужно вызвать одну из следующих функций:
KosTaskCreate();KosTaskInitEx();KosTaskInit();KosTaskInitFromSegEx();KosTaskInitFromSeg();KosTaskLaunch().Эти функции, кроме KosTaskCreate(), принимают параметры создаваемого процесса через входной параметр params. Такой же входной параметр имеет функция KosTaskSetup(), которая позволяет задать параметры процесса, созданного вызовом функции KosTaskCreate(). Через параметр params нужно передать структуру, содержащую следующие поля:
eiid – указатель на имя класса процесса.endpointsCount – число предоставляемых служб.Поле может иметь нулевое значение, если процесс не предоставляет службы.
endpoints – указатель на массив структур, содержащих характеристики предоставляемых служб (имена и идентификаторы служб, имена интерфейсов).Тип структуры определен в заголовочном файле sysroot-*-kos/include/services/handle/if_connection.h из состава KasperskyOS SDK.
Поле может иметь значение RTL_NULL, если процесс не предоставляет службы.
args – указатель на массив адресов параметров запуска программы.Последним элементом массива должно быть значение RTL_NULL.
envs – указатель на массив адресов переменных окружения программы.Переменные окружения должны иметь формат <имя>=<значение>. Последним элементом массива должно быть значение RTL_NULL.
flags – флаги, задающие параметры создания процесса:KOS_TASK_FLAGS_NONE – отсутствуют параметры создания процесса.KOS_TASK_FLAG_DUMPABLE – процесс переходит в "замороженное" состояние в результате необработанного исключения.О "замороженном" состоянии процесса см. "Управление процессами (низкоуровневый API task_api.h)".
KOS_TASK_FLAG_CRITICAL – выключение или перезагрузка аппаратной платформы в результате необработанного исключения в процессе.Флаг может быть недоступен для использования в зависимости от конфигурации ядра KasperskyOS. В случае доступности этого флага конфигурация ядра также задает вариант реакции на необработанное исключение в процессе: выключение или перезагрузка.
Можно указать только один из флагов, задающих параметры создания процесса.
componentTree – указатель на структуру, содержащую сведения из формальной спецификации компонента решения.Тип структуры определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Эта структура является элементом автоматически генерируемого транспортного кода (структура с именем *_component_tree).
Поле может иметь значение RTL_NULL.
При установке параметров процесса через входной параметр params функций KosTaskSetup(), KosTaskInit*() и KosTaskLaunch() нужно учитывать следующие особенности:
KosTaskSetup() игнорирует поля eiid и flags, поскольку соответствующие этим полям параметры процесса задаются при вызове функции KosTaskCreate() через параметры eiid и flags соответственно.componentTree имеет значение, отличное от RTL_NULL, то значение в поле eiid будет проигнорировано функциями KosTaskInit*() и KosTaskLaunch(), а имя класса процесса будет взято из формальной спецификации компонента решения.componentTree имеет значение, отличное от RTL_NULL, то значения в полях endpointsCount и endpoints будут проигнорированы функциями KosTaskSetup(), KosTaskInit*() и KosTaskLaunch(), а параметры предоставляемых служб (включая параметры служб вложенных компонентов) будут взяты из формальной спецификации компонента решения.При вызове функции KosTaskInit() или KosTaskLaunch() в качестве имени процесса и имени исполняемого файла используется одно из следующих значений:
eiid, если значение поля componentTree равно RTL_NULL.componentTree отлично от RTL_NULL.Таким же образом эти значения применяются в качестве имени процесса и/или пути к исполняемому файлу, если вызвать функцию KosTaskInitEx() или KosTaskInitFromSegEx() со значением RTL_NULL в параметре name и/или параметре path. И аналогично эти значения применяются в качестве имени процесса, если вызвать функцию KosTaskInitFromSeg() со значением RTL_NULL в параметре name.
Функции KosTaskCreate() и KosTaskInit*() через выходной параметр outTask передают адрес объекта, описывающего дочерний процесс. Этот объект представляет собой структуру, которая создается в памяти как родительского, так и дочернего процесса. Разработчику решения не требуется выполнять операции с полями этой структуры, но указатель на нее нужно использовать в качестве идентификатора процесса при вызове функций API. Дочерний процесс может получить адрес описывающего его объекта вызовом функции KosTaskGetSelf().
Если для доступа к службам, предоставляемым серверным процессом, используются статически созданные IPC-каналы, то объект, описывающий этот серверный процесс, должен быть связан со структурами, содержащими сведения о службах из формальной спецификации компонента решения. Это необходимо, чтобы при создании статического IPC-канала клиентские процессы получили сведения о службах, предоставляемых серверным процессом. Чтобы связать объект, описывающий дочерний серверный процесс, со структурами, содержащими сведения о службах из формальной спецификации компонента решения, нужно передать эти сведения через поле componentTree параметра params при вызове функций KosTaskCreate(), KosTaskInit*() и KosTaskLaunch(). Серверный процесс, который уже запущен, может связать описывающий его объект со структурами, содержащими сведения о службах из формальной спецификации компонента решения, вызовом функции KosTaskSetComponentTree(). Это требуется, если у запущенного серверного процесса нет родительского процесса.
При вызове функции KosTaskInitEx(), KosTaskInit() или KosTaskLaunch() ELF-образ из заданного исполняемого файла в ROMFS загружается в память создаваемого процесса. Если ELF-образ содержит таблицу символов .symtab и таблицу строк .strtab, то они загружаются в память процесса. Используя эти таблицы, ядро получает имена функций для формирования данных обратной трассировки стека (сведений о стеке вызовов).
Чтобы получить сведения об ELF-образе, загруженном в память процесса, нужно вызвать функцию KosTaskGetElfSegs(). Эта функция применима только к тем процессам, которые созданы с указанием флага KOS_TASK_FLAG_DUMPABLE. При использовании этой функции таблица символов .symtab и таблица строк .strtab считаются загружаемыми сегментами ELF-образа наряду с сегментами типа LOAD.
Функция KosTaskCreate(), в отличие от функций KosTaskInit*() и KosTaskLaunch(), создает "пустой" процесс, то есть процесс, в память которого не загружен ELF-образ программы. Чтобы загрузить сегменты ELF-образа в память процесса, нужно вызвать функцию KosTaskLoadSegments(). Для использования функции KosTaskLoadSegments(), как и функции KosTaskInitFromSegEx(), необходимо, чтобы заранее были созданы буферы MDL, которые содержат загружаемые сегменты ELF-образа. Загружаемые сегменты ELF-образа нужно задать через параметр segs. При этом таблица символов .symtab и таблица строк .strtab также считаются загружаемыми сегментами наряду с сегментами типа LOAD. Через параметры entry и relocBase необходимо задать точку входа в программу и смещение загрузки ELF-образа соответственно. Точка входа в программу представляет собой сумму адреса, указанного в поле e_entry заголовка ELF-образа, и смещения загрузки ELF-образа. (Для ELF-файла типа DYN смещение загрузки ELF-образа должно быть случайным значением с целью поддержки ASLR.) Чтобы получить смещение загрузки ELF-образа, можно вызвать функцию KnTaskVmReserveForElf() из API task_api.h, которая резервирует регион виртуальной памяти для загрузки ELF-образа. Если ELF-файл имеет тип DYN, функция KnTaskVmReserveForElf() передает через выходной параметр relocBase случайное смещение, для ELF-файла другого типа передает нулевое смещение. (Функции KosTaskInitEx(), KosTaskInit() и KosTaskLaunch() также устанавливают случайное смещение для ELF-файла типа DYN и нулевое смещение для ELF-файла другого типа.) Данные, передаваемые функциям KosTaskLoadSegments() и KosTaskInitFromSegEx() через параметры count, segs, entry и параметры, связанные с загрузкой таблицы символов .symtab и таблицы строк .strtab, подготавливаются функцией KnElfCreateVmSegEx() из API elf_api.h.
Функция KosTaskInitFromSeg() является упрощенной версией функции KosTaskInitFromSegEx() и не позволяет загружать в память процесса таблицу символов .symtab и таблицу строк .strtab, а также не позволяет задавать смещение загрузки ELF-образа (устанавливает нулевое смещение).
Функция KosTaskLaunch() создает и сразу запускает процесс без возможности статического создания IPC-каналов.
Функции KosTaskSetArgs() и KosTaskSetEnv() задают параметры запуска и переменные окружения программы соответственно. Эти функции предназначены для использования библиотекой libkos.
Функция KosTaskAddEndpoints() регистрирует службы, предоставляемые процессом. Эта функция предназначена для использования библиотекой libkos.
Статическое создание IPC-каналов
Перед запуском процессов можно создать IPC-каналы между ними. Между одним клиентским и одним серверным процессом можно создать несколько IPC-каналов с разными именами. Между одним серверным и несколькими клиентскими процессами можно создать IPC-каналы с одним именем.
Чтобы создать IPC-канал с именем, соответствующим имени класса серверного процесса, нужно вызвать функцию KosTaskConnect().
Чтобы создать IPC-канал с заданным именем, нужно вызывать функцию KosTaskConnectToService().
Чтобы использовать созданный IPC-канал, на стороне клиентского и серверного процесса нужно получить IPC-дескриптор вызовом функции SLStaticResolveHandle() из API sl-static.h. Через параметр channelName эта функция принимает имя IPC-канала.
Передача дескрипторов дочернему процессу
Родительский процесс может передавать дескрипторы дочернему процессу, который еще не запущен. (Общие сведения о передаче дескрипторов приведены в разделе "Передача дескрипторов".)
Чтобы передать дескриптор дочернему процессу, нужно вызвать функцию KosTaskTransferResource(), указав среди прочего дескриптор объекта контекста передачи ресурса, а также маску прав и условное имя потомка передаваемого дескриптора.
Чтобы найти потомка дескриптора, переданного родительским процессом, нужно вызвать из дочернего процесса функцию KosTaskLookupResource(), указав условное имя потомка дескриптора, которое было задано родительским процессом при вызове функции KosTaskTransferResource().
Запуск процесса
Чтобы создать и сразу запустить процесс без статического создания IPC-каналов, нужно вызвать функцию KosTaskLaunch().
Чтобы запустить уже созданный процесс, перед запуском которого могут быть созданы требуемые этому процессу IPC-каналы, нужно вызвать функцию KosTaskRunEx() или KosTaskRun().
Через параметр fsBackend функции KosTaskRunEx() нужно задать, как по умолчанию осуществляется поддержка файловой системы ROMFS для запускаемого процесса: ядром или системной программой FSUsr (подробнее см. "Использование файловой системы ROMFS (низкоуровневый API fs_api.h)"). В процессе, запускаемом вызовом функции KosTaskRun() или KosTaskLaunch(), по умолчанию поддержка файловой системы ROMFS осуществляется так же, как и в родительском процессе на момент вызова функции KosTaskRun() или KosTaskLaunch(). Чтобы получить сведения о том, как осуществляется поддержка файловой системы ROMFS для процесса, нужно вызвать из этого процесса функцию KosTaskGetSelfFSBackend(). (Функция KosTaskSetSelfFSBackend() записывает в объект, описывающий процесс, сведения о том, как осуществляется поддержка файловой системы ROMFS для вызывающего процесса. Эта функция предназначена для использования библиотекой libkos.)
Родительский процесс может поместить в пользовательское пространство и смонтировать файловую систему ROMFS, которой будет пользоваться дочерний процесс по умолчанию. Для этого родительский процесс вызовом функции KnFsChangeBackend() из API fs_api.h задает, что для него файловую систему ROMFS поддерживает программа FSUsr, и вызовом функции KnFsChange() из API fs_api.h монтирует требуемый образ ROMFS. Затем родительский процесс выполняет запуск дочернего процесса вызовом функции KosTaskRun(), KosTaskRunEx() или KosTaskLaunch(). (При вызове функции KosTaskRunEx() нужно явно указать, что по умолчанию для дочернего процесса файловую систему ROMFS поддерживает программа FSUsr.) В результате дочерний процесс по умолчанию будет использовать файловую систему ROMFS, помещенную в пользовательское пространство родительским процессом.
Если родительскому процессу не требуется завершать дочерний процесс или ожидать его завершения, то после запуска дочернего процесса описывающий его объект нужно удалить, обнулив число ссылок на него с использованием функции KosTaskPut(). Функция KosTaskLaunch() вызывает функцию KosTaskPut() после запуска дочернего процесса.
Завершение процесса
API позволяет завершать и ожидать завершения дочерних процессов.
Чтобы завершить дочерний процесс, нужно вызвать функцию KosTaskStop() или KosTaskStopAndWait().
Чтобы ожидать, пока дочерний процесс завершится по собственной инициативе, нужно вызвать функцию KosTaskWait().
Чтобы объект ядра, который описывает дочерний процесс, был удален после завершения этого процесса, нужно до или после завершения дочернего процесса закрыть его дескриптор в родительском процессе. Дескриптор дочернего процесса закрывается при удалении в памяти родительского процесса объекта, описывающего дочерний процесс. Чтобы удалить объект, описывающий дочерний процесс, нужно обнулить число ссылок на этот объект, используя функцию KosTaskPut(). Функция KosTaskLaunch() вызывает функцию KosTaskPut() после запуска дочернего процесса.
Подробнее о завершении процессов см. "Управление процессами (низкоуровневый API task_api.h)".
Получение дескриптора процесса
Чтобы получить дескриптор процесса, нужно вызвать функцию KosTaskGetHandle().
Дескриптор процесса можно передать другому процессу через IPC.
Дескриптор вызывающего процесса, который получен вызовом функции KosTaskGetHandle(), нельзя закрывать. В случае закрытия этот дескриптор может быть использован для идентификации других ресурсов, что приведет к ошибкам. Потомков этого дескриптора можно закрывать без риска возникновения подобных ошибок.
Получение параметров запуска и переменных окружения программы
Получить параметры запуска программы позволяет функция KosTaskGetArgsList(). Удалить массив адресов параметров запуска программы, полученный вызовом функции KosTaskGetArgsList(), позволяет функция KosTaskFreeArgsList().
Получить переменные окружения программы позволяет функция KosTaskGetEnvList(). Удалить массив адресов переменных окружения программы, полученный вызовом функции KosTaskGetEnvList(), позволяет функция KosTaskFreeEnvList().
Все эти функции предназначены для использования библиотекой libc.
Сведения о функциях API
Функции task.h
Функция |
Сведения о функции |
|---|---|
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Устанавливает параметры процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Загружает сегменты ELF-образа в память процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить сведения об ELF-образе, загруженном в память процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает IPC-канал. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает IPC-канал с заданным именем. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает параметры запуска программы. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить параметры запуска программы. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Удаляет массив адресов параметров запуска программы, полученный вызовом Параметры
Возвращаемые значения Нет. |
|
Назначение Задает переменные окружения программы. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить переменные окружения программы. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Удаляет массив адресов переменных окружения программы, полученный вызовом функции Параметры
Возвращаемые значения Нет. |
|
Назначение Запускает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Запускает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает процесс и ожидает окончания завершения этого процесса. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Ожидает завершения процесса. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Позволяет получить дескриптор процесса. Параметры
Возвращаемые значения Дескриптор процесса. |
|
Назначение Создает и запускает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить адрес объекта, описывающего вызывающий процесс. Параметры Нет. Возвращаемые значения Указатель на объект, описывающий процесс, или Дополнительные сведения Функция увеличивает на единицу число ссылок на объект, описывающий процесс, поэтому после вызова этой функции нужно вызвать функцию |
|
Назначение Уменьшает на единицу число ссылок на объект, описывающий процесс. Параметры
Возвращаемые значения Нет. |
|
Назначение Регистрирует службы. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Записывает в объект, описывающий процесс, сведения о том, как осуществляется поддержка файловой системы ROMFS для вызывающего процесса: ядром или системной программой Параметры
Возвращаемые значения Нет. |
|
Назначение Позволяет получить сведения о том, как осуществляется поддержка файловой системы ROMFS для вызывающего процесса: ядром или системной программой Параметры Нет. Возвращаемые значения Значение, которое отражает, как осуществляется поддержка файловой системы ROMFS: ядром или системной программой |
|
Назначение Создает структуры со сведениями о службах из формальной спецификации компонента решения и связывает эти структуры с объектом, описывающим процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Передает дескриптор процессу, который еще не запущен. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Выполняет поиск дескриптора по имени, заданному функцией Параметры
Возвращаемые значения В случае успеха возвращает дескриптор, иначе возвращает |