Получение физического адреса массива

Тема в разделе "WASM.ZEN", создана пользователем Gerret, 4 апр 2005.

  1. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12
    Задачка такая, надо написать прогу для работы с USB флешкой под ДОС'ом.

    Для USB контроллера надо задать адрес начала списка кадров. Т.е. указатель на массив... но как при загруженом драйвере emm386 и himem получить физический адрес (указатель) этого массива?
     
  2. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    А массив откуда берется?
     
  3. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12
    создается в программе





    P.S. пишу на Borland C++ 3.1
     
  4. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    Ну так если он создается в программе, какая сложность взять указатель?
     
  5. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    1. Точно в emm используется страничная адресация ? Если не используется, то проблемы вообще нет;

    2. Что мешает принудительно разместить блоки в нижней памяти (< 1Мег), для которой точно известен физический адрес ?
     
  6. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12
    для программы, никакой, я смогу по этому указателю просмотреть элементы массива и все прочее...



    Но для USB контроллера я должен передать адрес этого массива в виде числа... и вот получается так что это число не соответствует физическому адресу размещения массива в оперативной памяти (при включенных emm386.sys и himem.sys)...



    Пример создание массива:



    Memory model - Large


    Код (Text):
    1.  
    2. void *Handle = malloc(8192); //выделение 8К для массива
    3.  




    если вывести на экран значение (unsigned long)Handle будет приблизительно так: 0x8FD90004

    вот и хочется узнать как получить ФИЗИЧЕСКИЙ адрес по которому USB контроллер сможет считать информацию (на сколько я понял он использует DMA доступ к памяти).
     
  7. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    По идее если emm, то там используются кадры памяти, значит при выбранном кадре он проецируется на адресное пространство куда-то. Адрес этот физический, т.к. виртуальных в dos'е вроде как нет.

    Про dump'ь память и найди этот кадр.
     
  8. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12


    А можно по подробнее :)
     
  9. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Gerret, а как ты узнал, что физический адрес не совпадает с линейным, если ты не можешь определить этот физический адрес? И причем тут EMM/XMM?



    Функция malloc выделяет блок памяти в хипе (который целиком находится в нижней памяти) и возвращает указатель блока (в твоем примере - 8FD9:0004). himem.sys и emm386.exe манипулируют только дополнительной и верхней памятью, а нижнюю не трогают. Так что для первых 640 килобайт линейный адрес должен совпадать с физическим.
     
  10. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12
    да все понял :)

    созняюсь, ступил...

    я неправильно адрес записывал :)))

    я его писал как есть :)) 8FD90004...



    бывает же...
     
  11. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Если буфер располагается в базовой памяти... тогда физ. адрес буфера можно определить ч/з VCPI (функция 0DE06h). Но, надо полагать, что для нужд USB ~600-500К основной памяти будет маловато. Стандартные средства работы с расширенной памятью как обычно не подходят... работать ч/з отображаемые в 1М страницы с NN мегабайтами расширенной памяти -- это уподобится гинекологу из анекдота, обклеившему квартиру обоями ч/з замочную скважину. Свой собственный ProtMode memory manager писать наверное не в радость. Хороший вариант -- изменение программно-недоступного регистра предела (внутреннего) для какого-нибудь сегментного регистра (например GS). Необязательно с помощью LOADALL386 (которой может и не быть), можно и ч/з скачок в защищенный режим и обратно с пропуском инициализации сегментных регистров. После этого всё работает как обычно, но можно обращаться ко всей памяти, используя этот (допустим GS) сегментный регистр и 32-х разрядные операции. Да, EMM при этом лучше не пользовать. ;)
     
  12. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    _BC_, Кулакова читал? :)

    Можно изменить предел ВСЕХ сегментных регистров, а потом менять их как угодно - предел не изменится (если не входить в защищенный режим).

    Если использовать XMS, то можно узнать физический адрес выделленного блока с помощью функции XMM 0Ch (Lock extended memory block).
     
  13. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    Вот что надо было посоветовать первым -- какой-нить хороший DOS-Extender.





    Нет. ;)

    А зачем ВСЕ менять? Популярные сегментные регистры (типа CS, DS, ES, SS) перезагрузит V86-менеджер, а GS... кому он нафиг сдался этот GS ? ;)
     
  14. Gerret

    Gerret New Member

    Публикаций:
    0
    Регистрация:
    4 апр 2005
    Сообщения:
    12
    _BC_ прав, 500К для USB моловато... так что придется всетаки эксперементировать с линейной адресацией...