Ввод-вывод через память (mmio.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/io/mmio.h из состава KasperskyOS SDK.

API предназначен для работы с памятью MMIO. Память MMIO – это физические адреса, на которые отображены регистры и память устройств. (Для адресации физической памяти и доступа к регистрам и памяти устройств используются части одного пространства физических адресов.)

Сведения о функциях API приведены в таблице ниже.

Использование API

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

  1. Регистрация региона памяти MMIO, соответствующего устройству, с которым нужно работать.

    Чтобы выполнить этот шаг, нужно вызвать функцию KnRegisterPhyMem(). Если один и тот же регион памяти MMIO требуется зарегистрировать несколько раз, то при каждой регистрации этого региона в параметре flags нужно указать флаг MMIO_U_SHARED. Если регистрируемый регион памяти MMIO используется кодом ядра, то нужно указать флаг MMIO_K_SHARED. Если эти флаги не будут указаны, то доступ к региону памяти MMIO получит только тот код, который запросит этот доступ первым (это может быть как код ядра, так и код, исполняющийся в пользовательском режиме). Все последующие попытки регистрации вызовом функции KnRegisterPhyMem() завершатся с ошибкой rcAlreadyExists, и в диагностический вывод будут добавлены сообщения о проблеме совместного доступа к региону памяти MMIO. Если ядру не удастся получиться доступ к региону памяти MMIO из-за того, что этот регион уже зарегистрирован кодом, исполняющимся в пользовательском режиме, то также в диагностический вывод будет добавлено сообщение о проблеме совместного доступа к региону памяти MMIO.

    Дескриптор региона памяти MMIO можно передать другому процессу через IPC.

  2. Отображение региона памяти MMIO на память процесса.

    В один момент времени регион памяти MMIO может быть отображен только на один регион виртуальной памяти только одного процесса. (В разные моменты времени регион памяти MMIO может отображаться на виртуальную память разных процессов, владеющих дескриптором этого региона.) В результате отображения процесс получает доступ к региону памяти MMIO на чтение и/или запись.

    Чтобы зарезервировать регион виртуальной памяти и отобразить на него регион памяти MMIO, нужно вызвать функцию KnIoMapMem().

    Дескриптор, полученный при вызове функции KnIoMapMem(), нельзя передать другому процессу через IPC.

  3. Чтение данных из региона памяти MMIO и запись данных в него через память процесса.

    8-, 16- и 32-битные слова, считанные из региона памяти MMIO или записанные в него, представляют собой значения регистров устройства или содержимое памяти устройства.

    Чтобы выполнить этот шаг, нужно использовать функции IoReadMmReg8|16|32() и IoWriteMmReg8|16|32().

API включает вспомогательные функции KnIoMemHandlesClear() и KnIoMemHandlesClose(). Функция KnIoMemHandlesClear() инициализирует структуру для хранения дескрипторов, которые создаются на шаге 1 и 2. Функция KnIoMemHandlesClose() закрывает дескрипторы, сохраненные в этой структуре (вызывая функцию KnHandleClose() из API handle_api.h), и инициализирует ее. При вызове функции KnIoMemHandlesClose() отсутствие всех или одного дескриптора в структуре не приводит к ошибке, и присутствующий дескриптор будет закрыт. Функции KnIoMemHandlesClear() и KnIoMemHandlesClose() можно использовать следующим образом. Перед выполнением шага 1 инициализировать структуру для хранения дескрипторов вызовом функции KnIoMemHandlesClear(). Затем при выполнении шагов 1 и 2 сохранять дескрипторы в этой структуре. В дальнейшем это позволит закрыть все созданные дескрипторы одним вызовом функции KnIoMemHandlesClose().

Дерегистрация региона памяти MMIO

Чтобы дерегистрировать регион памяти MMIO, нужно выполнить следующие шаги:

  1. Освободить регион виртуальной памяти, выделенный при вызове функции KnIoMapMem().

    Чтобы выполнить этот шаг, нужно закрыть дескриптор, который был получен при вызове функции KnIoMapMem().

  2. Закрыть или отозвать каждый дескриптор региона памяти MMIO во всех процессах, которые владеют этими дескрипторами.

Для закрытия дескрипторов при выполнении этих шагов можно использовать функцию KnIoMemHandlesClose().

Сведения о функциях API

Функции mmio.h

Функция(и)

Сведения о функции(ях)

KnRegisterPhyMem()

Назначение

Регистрирует регион памяти MMIO.

Параметры

  • [in] addr – странично выровненный базовый адрес региона памяти MMIO.
  • [in] size – размер региона памяти MMIO в байтах. Должен быть кратен размеру страницы памяти.
  • [in,optional] flags – флаги, задающие параметры региона памяти MMIO, или 0, если не требуется задавать эти параметры. Флаги определены в заголовочном файле sysroot-*-kos/include/io/io_mmio.h из состава KasperskyOS SDK.
  • [out] outRid – указатель на дескриптор региона памяти MMIO.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • MMIO_K_SHARED – совместный доступ с ядром.
  • MMIO_U_SHARED – совместный доступ при множественных регистрациях.

KnIoMapMem()

Назначение

Резервирует регион виртуальной памяти и отображает на него регион памяти MMIO.

Параметры

  • [in] rid – дескриптор региона памяти MMIO.
  • [in] prot – флаги, задающие права доступа к региону виртуальной памяти. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [in] attr – флаги, задающие параметры кеширования. Флаги определены в заголовочном файле sysroot-*-kos/include/vmm/flags.h из состава KasperskyOS SDK.
  • [out] addr – указатель на базовый адрес региона виртуальной памяти.
  • [out] handle – указатель на дескриптор, который используется для освобождения региона виртуальной памяти.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре prot можно указать следующие флаги:

  • VMM_FLAG_READ – доступ на чтение.
  • VMM_FLAG_WRITE – доступ на запись.

В параметре attr можно указать следующие флаги:

  • VMM_FLAG_WRITE_BACK, VMM_FLAG_WRITE_THROUGH, VMM_FLAG_WRITE_COMBINE, VMM_FLAG_CACHE_DISABLE – управление кешированием.

    Рекомендуется указать флаг VMM_FLAG_CACHE_DISABLE.

IoReadMmReg8()

IoReadMmReg16()

IoReadMmReg32()

Назначение

Позволяют получить 8-, 16- или 32-битное слово из региона памяти MMIO.

Параметры

  • [in] reg – виртуальный адрес для чтения слова.

Возвращаемые значения

8-, 16- или 32-битное слово из региона памяти MMIO.

IoWriteMmReg8()

IoWriteMmReg16()

IoWriteMmReg32()

Назначение

Записывают 8-, 16- или 32-битное слово в регион памяти MMIO.

Параметры

  • [in] reg – виртуальный адрес для записи слова.
  • [in] data – слово для записи.

Возвращаемые значения

Нет.

KnIoMemHandlesClear()

Назначение

Инициализирует структуру для хранения дескрипторов ресурсов, выделенных для обеспечения MMIO.

Параметры

  • [out] handles – указатель на структуру для хранения дескрипторов.

Возвращаемые значения

Нет.

Дополнительные сведения

После инициализации поля структуры принимают значение INVALID_HANDLE.

KnIoMemHandlesClose()

Назначение

Закрывает дескрипторы ресурсов, выделенных для обеспечения MMIO, и инициализирует структуру, в которой эти дескрипторы хранились.

Параметры

  • [in,out] handles – указатель на структуру для хранения дескрипторов.

Возвращаемые значения

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

После инициализации поля структуры принимают значение INVALID_HANDLE.

В начало