#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 передает гостевому ядру при загрузке.