Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Выделение диапазона адресов для окна памяти платы


Автор: Veri 27.9.2011, 08:35
Здравствуйте, уважаемые специалисты.
Прошу вашего совета и рекомендации в следующей проблеме:
В наличии есть одноплатный компьютер, работающий с шиной PC-104 и плата ISA, разработанная сторонним специалистом. Тот специалист проводил разработку и тестирование из DOS, благодаря чему сразу встал вопрос о написании драйвера к данному устройству. Так как соответствующего специалиста в отделе нет, то проблема решается готовыми решениями - вроде драйвера PortIO, который замечательно работает с регистрами данной платы. Но кроме задачи доступа к регистрам, требуется доступ к окну памяти в 16 кб, который должен располагаться в диапазоне адресов С8000-DFFFF. Работая из XP, требуется записывать 16кб в диапазон приписанный к плате, а плата разом забирает эти данные - это быстрее, чем через регистры (пишу это заранее, как ответ на вопрос, почему бы не сделать пакетную пересылку).
Мною были осуществлены попытки по написанию драйвера под ISA. Проблема ISA, не являющейся PNP-устройством, в отличие от PCI платы (где благодаря PNP вопросы о выделении памяти и выдаче необходимых указателей решаются системой) именно в том, что нигде я не могу найти нужного механизма описания платы и диапазона адресов, который к ней нужно прицепить. Я рассматривал примеры amcc5933 и pcidrv, но проблема там та же самая (в первом случае драйвер для ISA рассматривает лишь доступ к порту, а во втором - диапазон адресов цепляется через PNP).
Итак, следующие вопросы:
1) Если плата работает с тестами под DOS, хотя при этом в BIOS нет настроек, позволяющих закрепить некий адресный диапазон за PCI (shared memory, shadowing имею в виду), то каким образом правила игры меняются, когда загружается XP со своими кольцами защиты и драйверной моделью? 
2) Каким образом требуется описывать не только порты ISA-платы, но и используемую ей память? 
Любые примеры, рекомендации, указания к действию, слова о том, что я все неправильно понимаю и что все по-другому - с благодарностью принимаются. Но только напишите, как "по-другому" и куда копать 

Заранее спасибо.

Автор: borisbn 27.9.2011, 09:58
Veri, PortIo устарел. Вот на http://www.internals.com/ есть WinIO. Позволяет работать как с портами, так и с физической памятью.
Вот пример работы с WinIO
Код

#include "winio.h"
void main()
{
  DWORD dwPortVal;
  DWORD dwMemVal;
  bool bResult;
  HANDLE hPhysicalMemory;
  PBYTE pbLinAddr;

  bResult = InitializeWinIo();
  if ( bResult ) {
    GetPortVal(0x378, &dwPortVal, 4);
    SetPortVal(0x378, 10, 4);

    // Map physical addresses 0xA0000 - 0xAFFFF into the linear address space of the application.
    pbLinAddr = MapPhysToLin((PBYTE)0xA0000, 65536, &hPhysicalMemory);
    if ( pbLinAddr ) {
      *pbLinAddr = 10;
      UnmapPhysicalMemory(hPhysicalMemory, pbLinAddr);
    }
    ShutdownWinIo();
  }
}


Мало того, парочку действий (сам не догадаешься каких - спрашивай) и ты сможешь использовать твой DOS-овский код под Windows.

Автор: Veri 27.9.2011, 10:12
borisbn, спасибо, я даже уже встречал данный драйвер на волне своих поисков. Говоря по-простому, мне нужно реализовать досовские peek и poke, но перед этим решив следующий вопрос - требуется ли каким-то образом размечать диапазон памяти для системы, что он является ресурсом конкретной платы? Дело в том, что даже используя подобные модули для чтения и записи физической памяти, будь то через драйвер или через device\physicalmemory, участки этого диапазона читаются (и там изначальное пусто), но не пишутся. То есть даже после записи там остаются незаписанные свободные ячейки памяти. При этом на одноплатнике, где не стоит сторонних устройств шины PCI, вся память данного диапазона работает так - читается пустой и не пишется. На рабочем десктопе с вставленными PCI-устройствами некоторые участки данного диапазона и читаются, и пишутся, а некоторые ведут себя аналогично первому. Отсюда возникло подозрение - что если данный диапазон не закреплен за каким-либо устройством, то запись туда и не производится. Но если это так, то кто это курирует, на каком этапе, BIOS, OS или нечто иное?

Автор: borisbn 27.9.2011, 10:26
Цитата(Veri @  27.9.2011,  10:12 Найти цитируемый пост)
Отсюда возникло подозрение - что если данный диапазон не закреплен за каким-либо устройством, то запись туда и не производится

Нет. Это не так. Когда ты пишешь в какую-то ячейку памяти, процессор тупо выставляет соответствующий физический адрес на шину адресов, и данные - на шину данных.
Единственный момент - на плате находится не совсем память в обычном понимании. Плата может принять данные по какому-то адресу, но совершенно не обязательно будет отдавать эти же данные по этому же адресу. Если какому-либо PCI-устройству выделен тот же диапазон адресов, что и твоей ISA-плате, то она будет отдавать свои данные при попытке чтения с этого адреса, и как-то интерпретировать их при попытке записи.

Цитата(Veri @  27.9.2011,  10:12 Найти цитируемый пост)
Но если это так, то кто это курирует, на каком этапе, BIOS, OS или нечто иное?

BIOS. Ос тут не при чём. В BIOS-ах (в некоторых, не во всех) можно выставить, что такой-то диапазон памяти зарезервировать под не PnP-устройства. Тогда его не будут отдавать этим устройствам.

Автор: Veri 27.9.2011, 10:46
Цитата(borisbn @  27.9.2011,  10:26 Найти цитируемый пост)
Единственный момент - на плате находится не совсем память в обычном понимании. Плата может принять данные по какому-то адресу, но совершенно не обязательно будет отдавать эти же данные по этому же адресу. Если какому-либо PCI-устройству выделен тот же диапазон адресов, что и твоей ISA-плате, то она будет отдавать свои данные при попытке чтения с этого адреса, и как-то интерпретировать их при попытке записи.

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

Спасибо вам большое за ответы, но не могли бы вы разъяснить такой момент - все платы, использующие память компьютера для своей работы должны изначально не скрещиваться друг с другом по используемым диапазонам, ведь bios не занимается тем, что распределяет по своему усмотрению диапазоны памяти, кому и в каком порядке - те просят сами, так? Именно в таком случае выходит, что задавая базовый адрес окна на нашей плате записью этого адреса в регистр, при этом уже находясь в среде XP, мы затем запрашиваем напрямую через драйвер этот диапазон и пишем туда. Признаюсь, я использовал другую библиотеку для записи в память, http://www.zealsoft.com/memaccess/, но проводя все требуемые действия по установке базового адреса окна, записи туда данных, я при чтении получал FF. Поэтому я выискиваю проблему именно в контексте невидимости для какого-либо диспетчера этой связи платы и памяти. Не могли бы вы как-то это прокомментировать?

Автор: borisbn 27.9.2011, 11:00
Цитата(Veri @  27.9.2011,  10:46 Найти цитируемый пост)
все платы, использующие память компьютера для своей работы должны изначально не скрещиваться друг с другом по используемым диапазонам, ведь bios не занимается тем, что распределяет по усмотрению им нужные диапазоны памяти, так?

Для PCI-плат (вернее для PnP) BIOS как раз и занимается тем, чтобы распределить адреса таким образом, чтобы они не пересекались. Для ISA-же плат - полная вакханалия.

Цитата(Veri @  27.9.2011,  10:46 Найти цитируемый пост)
я при чтении получал FF

Повторю, плата не обязана выдавать по какому-либо адресу то, что в этот адрес было записано.
Если такой код
Код
mem[ 0 ] = 42;
bool b = ( mem[ 0 ] == 42 );

всегда выдаёт true, если mem - это указатель на ОЗУ (изменение этой ячейки в другом потоке сейчас не рассматриваем), то совершенно не факт, что, если mem указывает на память платы, результат будет true.

Цитата(Veri @  27.9.2011,  10:46 Найти цитируемый пост)
базовый адрес окна можно выставлять на регистре платы

имеется в виду физически джамперами или базовый адрес задаётся записью в некий порт платы (адрес этого порта ессно должен быть жёстко "прошит") ?

Автор: Veri 27.9.2011, 11:12
Цитата(borisbn @  27.9.2011,  11:00 Найти цитируемый пост)
имеется в виду физически джамперами или базовый адрес задаётся записью в некий порт платы (адрес этого порта ессно должен быть жёстко "прошит") ? 

Нет, не джамперами, а именно в порт. Плата поддерживает лишь диапазон С8000-DFFFF для выбора окна (в целевом же устройстве три таких платы одновременно с выделенным в этом диапазоне окном под каждую из них).

Автор: borisbn 27.9.2011, 11:17
Кстати, ты можешь посмотреть задействованные адреса в диспетчере устройств, если выберешь в меню "Вид" пункт "Ресурсы по типу".
user posted image

Автор: Veri 27.9.2011, 11:24
Условно, говоря, ISA-плата - этой такой варвар, который будет лезть в чужое адресное пространство, причем даже разное, если ему уже из XP постоянно менять базовый адрес окна записью значения в порт? smile

Автор: bsa 27.9.2011, 13:11
Veri, да. именно поэтому необходим грамотный драйвер, который уведомит ОС о том, что есть такой-то диапазон адресов, который используется устройством. После этого ОС исключит этот адрес из "свободного обращения". Если же диапазон памяти уже занят, то ОС вернет ошибку. В этом случае, можно попытаться использовать другой диапазон... И так далее, пока не будет найден свободный. А уже после этого можно включать и инициализировать устройство.

Автор: borisbn 27.9.2011, 13:20
Veri, и всё же посмотри в Setup'е копьютера, есть ли там пункт с примерно таким содержанием: "Зарезервировать следующий диапазон адресов для не PnP-плат". Если есть, то можно обойтись без драйвера.

Автор: xvr 27.9.2011, 17:15
Цитата(Veri @  27.9.2011,  11:24 Найти цитируемый пост)
словно, говоря, ISA-плата - этой такой варвар, который будет лезть в чужое адресное пространство,

Нет, не будет. На PCI машинах ISA шина находится за специальным PCI-ISA мостом, на котором активирован Substractive Decoder. Т.е. обращения пойдут на ISA шину только тогда, когда на всех PCI шинах не найдется никого, кому бы этот адрес понадобился. Так что смотри memory map ( http://forum.vingrad.ru/index.php?showtopic=338755&view=findpost&p=2406830 ) и проверяй. 
А для захвата адресов (и организации обмена) придется писать свой драйвер


Автор: Veri 28.9.2011, 15:55
Спасибо за ответы!
Но при пробе работы WinIO возникает ошибка при запуске процедуры инициализации драйвера WinIO. Это каким-то образом связано с уже наличием UserPort, так как он уже стоял на исходной машине. Для пробы я установил userport на другой машине, где WinIO успешно запускался - и тот перестал инициализироваться. Сталкивался ли кто-либо с такой проблемой и можно ли справиться иным способом, нежели заново развертывать систему?
Само собой, я удалял файл драйвера и ключи в реестре, но что-то упускаю.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)