Содержание
Использование DMA (dma.h)
API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/dma.h
из состава KasperskyOS SDK.
API предназначен для организации обмена данными между устройствами и оперативной памятью в режиме прямого доступа к памяти (англ. Direct Memory Access, DMA), при котором процессор не используется.
Сведения о функциях API приведены в таблице ниже.
Использование API
Типовой сценарий использования API включает следующие шаги:
- Создание буфера DMA.
Буфер DMA –это буфер, состоящий из одного или нескольких регионов физической памяти (блоков), используемых для DMA. Буфер DMA, состоящий из нескольких блоков, можно использовать, если устройство поддерживает режим "scatter/gather DMA". Буфер DMA, состоящий из одного блока, можно использовать, если устройство поддерживает режим "scatter/gather DMA" или "continuous DMA". Вероятность создать буфер DMA, состоящий из одного большого блока, ниже, чем вероятность создать буфер DMA, состоящий из нескольких небольших блоков. Это особенно актуально при высокой фрагментации физической памяти.
Если устройство поддерживает только режим "continuous DMA", то даже при задействовании IOMMU нужно использовать буфер DMA, состоящий из одного блока.
Чтобы выполнить этот шаг, нужно вызвать функцию
KnIoDmaCreate()
илиKnIoDmaCreateContinuous()
. ФункцияKnIoDmaCreateContinuous()
создает буфер DMA, состоящий из одного блока. ФункцияKnIoDmaCreate()
создает буфер DMA, состоящий из одного блока, если значение 2^order равно значению size/размер страницы памяти, или значение 2^order является ближайшим большим к значению size/размер страницы памяти в упорядоченном по возрастанию множестве {2^(order-1);size/размер страницы памяти;2^order}. Если значение size/размер страницы памяти больше значения 2^order, функцияKnIoDmaCreate()
может создать буфер DMA, состоящий из нескольких блоков.Дескриптор буфера DMA можно передать другому процессу через IPC.
- Отображение буфера DMA на память процессов.
Один буфер DMA может быть отображен на несколько регионов виртуальной памяти одного или нескольких процессов, которые владеют дескриптором этого буфера DMA. В результате отображения процессы получают доступ к буферу DMA на чтение и/или запись.
Чтобы зарезервировать регион виртуальной памяти и отобразить на него буфер DMA, нужно вызвать функцию
KnIoDmaMap()
.Дескриптор, полученный при вызове функции
KnIoDmaMap()
, нельзя передать другому процессу через IPC. - Открытие доступа к буферу DMA для устройства вызовом функции
KnIoDmaBegin()
.Вызов функции
KnIoDmaBegin()
необходим, чтобы создать объект ядра, содержащий адреса и размеры блоков, из которых состоит буфер DMA. Эти сведения необходимы устройству, чтобы использовать буфер DMA. Устройство может работать как с физическими, так и с виртуальными адресами в зависимости от того, задействован ли IOMMU. Если IOMMU задействован, объект содержит виртуальные адреса блоков. В противном случае объект содержит физические адреса блоков.Дескриптор, полученный при вызове функции
KnIoDmaBegin()
, нельзя передать другому процессу через IPC. - Получение сведений о буфере DMA.
На этом шаге нужно получить адреса и размеры блоков из объекта ядра, созданного вызовом функции
KnIoDmaBegin()
. Полученные адреса и размеры в дальнейшем требуется передать устройству, используя, например, MMIO. После получения этих сведений устройство может записывать в буфер DMA и/или читать из него (при задействовании IOMMU устройство на шине PCIe должно быть прикреплено к домену IOMMU).Чтобы выполнить этот шаг, нужно вызвать функцию
KnIoDmaGetInfo()
илиKnIoDmaContinuousGetDmaAddr()
. ФункцияKnIoDmaGetInfo()
позволяет получить номер страницы памяти (frame
) и порядок (order
) для каждого блока. (Номер страницы памяти, умноженный на размер страницы памяти, дает адрес блока. Значение 2^order представляет собой размер блока в страницах памяти.) ФункциюKnIoDmaContinuousGetDmaAddr()
можно использовать, если буфер DMA состоит из одного блока. Эта функция позволяет получить адрес блока. (В качестве размера блока нужно принять размер буфера DMA, заданный при его создании.)
Закрытие доступа к буферу DMA для устройства
Если удалить объект ядра, созданный при вызове функции KnIoDmaBegin()
, то при задействовании IOMMU доступ устройства к буферу DMA будет запрещен. Чтобы удалить этот объект, нужно вызвать функцию KnHandleClose()
, указав дескриптор, который был получен при вызове функции KnIoDmaBegin()
. (Функция KnHandleClose()
объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h
из состава KasperskyOS SDK.)
Удаление буфера DMA
Чтобы удалить буфер DMA, нужно выполнить следующие шаги:
- Освободить регионы виртуальной памяти, зарезервированные при вызовах функции
KnIoDmaMap()
.Чтобы выполнить этот шаг, нужно использовать функцию
KnHandleClose()
, указывая дескрипторы, которые были получены при вызовах функцииKnIoDmaMap()
. (ФункцияKnHandleClose()
объявлена в заголовочном файлеsysroot-*-kos/include/coresrv/handle/handle_api.h
из состава KasperskyOS SDK.)Этот шаг нужно выполнить для всех процессов, на память которых отображен буфер DMA.
- Удалить объект ядра, созданный вызовом функции
KnIoDmaBegin()
.Чтобы выполнить этот шаг, нужно вызвать функцию
KnHandleClose()
, указав дескриптор, который был получен при вызове функцииKnIoDmaBegin()
. - Закрыть или отозвать каждый дескриптор буфера DMA во всех процессах, которые владеют этими дескрипторами.
Чтобы выполнить этот шаг, нужно использовать функцию
KnHandleClose()
и/илиKnHandleRevoke()
, которые объявлены в заголовочном файлеsysroot-*-kos/include/coresrv/handle/handle_api.h
из состава KasperskyOS SDK.
Сведения о функциях API
Функции dma.h
Функция |
Сведения о функции |
---|---|
|
Назначение Создает буфер DMA. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Создает буфер DMA, состоящий из одного блока. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Резервирует регион виртуальной памяти и отображает на него буфер DMA. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Изменяет параметры кеширования буфера DMA. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Функцию можно использовать, если выполняются следующие условия:
В параметре
|
|
Назначение Позволяет получить сведения о буфере DMA. Сведения включают адреса и размеры блоков. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить адрес блока для буфера DMA, состоящего из одного блока. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Открывает доступ к буферу DMA для устройства. Параметры
Возвращаемые значения В случае успеха возвращает |