Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема состоит в слудующем: зная виртуальный адрес надо определить физический  (Прочитано 9978 раз)
0 Пользователей и 1 Гость смотрят эту тему.
flashLAV
Гость
« : 18-09-2005 14:30 » 

Добрый день
Суть проблемы:
-есть устройство PCI, которое, при соответствующем программировании, осуществляет передачу данных
в некий буфер, адрес которого я и должен указать ему.
Сразу оговорюсь, устройство является Bus Master-ом, но оно все делает само, т.е., я отношения к DMA не имею
Так вот, нужно:
 - выделить непрерывный участок в памяти и его физический адрес передать в устройство
 - этот же участок памяти должен быть доступен в приложении пользователя (3-е кольцо) для обработки данных, поступающих
от устройства
Пробую делать так:

MmAllocateContigouoseMemory(Size,....)
BuildMDL()
LockMdl
ProbeAndLockPages(...UserMode) - здесь получил адрес буфера в приложении пользователя (соответственно, через IOCTL)

А от какой функции брать теперь MmGetPhysicalAddress Не понял
Или вообще, моя концепция неправильная - может, нужно MmMapIoSpace использовать?
Тогда, от чего его (MmMapIoSpace) брать?
В общем, помогите, кто чем может, а то совсем запутался
С уважением, Алексей Локис
flash2001@newmail.ru

Записан
sn0w
Гость
« Ответ #1 : 18-09-2005 20:47 » 

HalTranslateBusAddress не подходит? )
Записан
flashLAV
Гость
« Ответ #2 : 19-09-2005 06:30 » 

HalTranslateBusAddress не подходит? )
Как я понимаю, не подходит совсем, так как у меня вопрос, никак не связанный с ресурсами платы PCI
У платы, конечно, есть свои ресурсы но они, в данном случае, сами по себе...
Мне нужно выделить самому выделить буфер для данных, получить его ФИЗИЧЕСКИЙ адрес в ПЭВМ и передать его в устройство
Записан
dachny
Гость
« Ответ #3 : 19-09-2005 09:19 » 

IoGetDmaAdapter

причем  девайс дескрипшен выглядит примерно вот так

RtlZeroMemory(&dd, sizeof(dd));
dd.Version = DEVICE_DESCRIPTION_VERSION;
dd.Master = TRUE;
dd.ScatterGather = FALSE;
dd.DemandMode = TRUE;
dd.AutoInitialize = FALSE;
dd.Dma32BitAddresses = TRUE;
dd.IgnoreCount = FALSE;
dd.DmaChannel = 0;
dd.InterfaceType = PCIBus;
dd.DmaWidth = Width32Bits;   // PCI default width
dd.DmaSpeed = Compatible;
dd.MaximumLength = MAX_DMA_LENGTH;

затем
AllocateCommonBuffer
Записан
flashLAV
Гость
« Ответ #4 : 19-09-2005 15:49 » 

Правильно ли я понял, что в любом случае, для таких операций, как пересылка данных от платы через шину PCI в режиме
BusMaster, я должен инициализировать/использовать  обект DMA???

От меня (в плане программированния платы PCI) не требуется никаких действий по обращению к DMA.

Для начала циклической передачи данных от шины в память мне нужен только:
 - адрес ОЗУ;
 - размер вводимых данных
и записать все это по соответствующим адресам (это реализовано).

Все дальнейшие действия по вводу данных плата делает сама
Так вот, можно ли не трогать DMA а просто выделить память?

Сегодня сделал вот что:
virt_mem   = MmAllocateContiguousMemory()
phys_mem = MmGetPhysicalAddress(virt_mem)

phys_mem - физический адрес буфера в ОЗУ

mdl = IoAllocateMdl(virt_mem)
MmBuildMdlForNonPagedPool(mdl)
user_mem = MmMapLockedPages(mdl)

user_mem - адрес буфера в приложении пользователя (Ring 3)

Завтра проверю, phys_mem - та физическая память, которую я ожидал, или нет  Улыбаюсь


Записан
dachny
Гость
« Ответ #5 : 20-09-2005 04:42 » 

>>Правильно ли я понял, что в любом случае, для таких операций, как пересылка данных от платы через шину PCI
>>в режиме BusMaster, я должен инициализировать/использовать  обект DMA???
ДА

>>От меня (в плане программированния платы PCI) не требуется никаких действий по обращению к DMA.
НЕТ и причем все зависит от конкретной аппаратной реализации в плате

Записан
flashLAV
Гость
« Ответ #6 : 20-09-2005 15:42 » 

Таким образом, подтверждаю, что, если есть устройство, которое реализует Bus Master DMA
и не использует при этом системные контроллеры DMA, то ниже приведенный код
обеспечивает нужную функциональность (проверено только в W2000 SP3)

virt_mem   = MmAllocateContiguousMemory()
phys_mem = MmGetPhysicalAddress(virt_mem)

phys_mem - физический адрес буфера в ОЗУ

mdl = IoAllocateMdl(virt_mem)
MmBuildMdlForNonPagedPool(mdl)
user_mem = MmMapLockedPages(mdl)

user_mem - адрес буфера в приложении пользователя (Ring 3)

Результат-то я получил, но теперь возникает другой вопрос: при использовании
эти функций пришлось отказаться от WDM-модели, так как некторые функции есть только
в ntddk.h

Интересно, а можно еще как-то получит неразрывную область памяти и её физический адрес?

C уважением, Алексей Локис

Записан
dachny
Гость
« Ответ #7 : 21-09-2005 04:56 » 

я же уже говорил
AllocateCommonBuffer

>>  которое реализует Bus Master DMA и не использует при этом системные контроллеры DMA
Bus Master DMA по определению не использует системные контроллеры
Записан
flashLAV
Гость
« Ответ #8 : 21-09-2005 14:29 » 

Может быть, когда-то, реализую и через DMA Ага
Записан
flashLAV
Гость
« Ответ #9 : 23-09-2005 17:14 » 

Столкнулся с тем, что на XP SP2 стандартными средствами системы не устанавливается, хотя принудительно - устанавливается и работает
Было два варианта:
 - DDK для Server 2003
 - переписать под WDM (AllocateCommonBuffer из DMA)

Выбрал второй, переписал - работает
Еще раз спасибо всем за помощь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines