Могу ли я выделить страницы памяти по указанному физическому адресу в модуле ядра?

#linux-kernel #memory-management #device-driver #kernel-module #qemu

#linux-ядро #управление памятью #драйвер устройства #kernel-module #qemu

Вопрос:

Я пишу модуль ядра в гостевой операционной системе, который будет запускаться на виртуальной машине с использованием KVM. Здесь я хочу выделить страницу памяти по определенному физическому адресу. kmalloc() предоставляет мне память, но по физическому адресу, выбранному ОС.

Справочная информация: Я пишу метод эмуляции устройства в qemu, который не завершался бы, когда гость обменивается данными с устройством (он завершается, например, на устройствах с отображением ввода-вывода, а также на устройствах с отображением портов). Основная идея заключается в следующем: драйвер гостевого устройства будет выполнять запись на определенный (гостевой) адрес физической памяти. Поток в процессе qemu будет непрерывно опрашивать его для проверки наличия новых данных (через некоторые биты состояния и т.д.). И предпримет соответствующие действия, не вызывая выхода. Поскольку не существует (существующего) способа, с помощью которого гость может сообщить хосту, какой адрес используется драйвером устройства, я хочу, чтобы для него была выделена предварительно указанная страница памяти.

Комментарии:

1. Есть способ. Это DMA с эмулируемым оборудованием qemu. В гостевой ОС есть драйверы устройств, которые будут настраивать DMA через порты «PCI» или ввода-вывода, и в qemu есть эмулируемые аппаратные устройства (например, жесткий диск, сеть).

2. @osgx Да, но каждый доступ к ячейке памяти со стороны драйвера гостевого устройства приведет к выходу из qemu. Я пытаюсь свести к минимуму эти выходы, чтобы повысить производительность эмуляции устройства

Ответ №1:

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

Комментарии:

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

2. возможно, вместо того, чтобы полагаться на фиксированный адрес, вы можете вызвать still kmalloc() и каким-то образом передать соответствующий физический адрес хосту. Я полагаю, у вас есть какой-то канал связи с кодом хоста.

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

Ответ №2:

Похоже, вам следует атаковать это с другой стороны, зарезервировав диапазон физической памяти на карте памяти, которую BIOS QEMU передает гостевому ядру при загрузке.