Хочу осуществить низкоуровневый вывод на экран (как в SoftIce). Возникли некоторые трудности. Во первых не ясно в какую область памяти записывать данные - у меня на GeForce 7300 их три (тройная буферизация?). Но самое главное - при обращении к этим адресам происходит краш с кодом 50h PAGE_FAULT_IN_NONPAGED_AREA. Как же этого добились в NuMega SoftIce? "Самокомпилирующийся" bat-файл ;@echo off ;goto make .386 .model flat, stdcall option casemap:none include include\w2k\ntoskrnl.inc includelib lib\w2k\ntoskrnl.lib .data lolimit dw 0FFFFh ;структура дескриптора с базой 0 и лимитом 4Гб lobase dw 0 db 0 flags1 db 10010011b hilmit db 11001111b hibase db 0 SelectorArray dd 0 .code DriverEntry: ;Создаю дескриптор invoke KeI386AllocateGdtSelectors,addr SelectorArray,1 invoke KeI386SetGdtSelector,SelectorArray,addr lolimit ;записываю в видеопамять push es push edi mov es,SelectorArray mov edi,0E0000000h ;этот адрес выводится в свойствах видеокарты mov ecx,16000 fill: ;для надежности не стал ипользовать rep stosd mov es:[edi],eax ;потому, что не уверен, как это работает add edi,4 ;в защищенном режиме loop fill pop edi pop es xor eax,eax ;означает, что драйвер зарегистрирован без ошибок retn 8 ;у DriverEntry 2 параметра по 4 байта end DriverEntry :make set drv=drv bin\ml /nologo /c /coff %drv%.bat bin\link /nologo /driver /base:0x10000 /align:4 /out:%drv%.sys /subsystem:native %drv%.obj del %drv%.obj echo. pause
murder адрес (0xE0000000) то ты получил физический (скорее всего) но интерпретируется он как виртуальный
Дык нельзя обращаться по такому виртуальному адресу! Ведь память еще надо промапить и получить виртуальный адрес, который будет транслироваться в такой физический
murder Я немного от жизни отстаю. Обычно там два диапозона. Один это видео память. Другой регистры видео карты отоброженные в память через которые видеться программирование 2D и 3D ускорителей и прочего правда эта область спецефична для каждой видео карты.
Эти области памяти по 16 МБ, то есть это точно не регистры. Great Чет не понял. Смотри: я создаю новый дескриптор с базой ноль и делаю смещение относительно него. Получается 0+0E0000000h. Помоему никаких преобразований не надо. В принципе совсем не обязательно вывести изображение таким способом. Для меня важно реализовать интерфейс пользователя из режима ядра. Может существуют какие-нибудь функции для вывода графики в драйверах? PS 0E0000000h - это не физический адрес. У меня 768 RAM + 256 VRAM, а адрес указывает на 3,5 Гб.
murder как раз таки это физический адрес физически процессор (32-ух разрядный) может адресовать до 4GB (ну или до 64GB с PAE) все это адресное пространство разбито на области: внешняя память отображена на одну область адресного пространства CPU, PCI устройства (в том числе твоя видеокарта), APIC - на другие области и т. д вообщем, физический адрес - совсем не обязательно относится к внешней памяти
murder Регистры. Просто NVidia любят резервировать под них побольше памяти(вернее диапозон адрессов), а задействована там только небольшая часть. 0E0000000h - это физический адресс. А в дескрипторе у тебя лежит линейный. Так что тебе требуется создать страницу которая отоброзит физический адрес на линейный. Видео память распологается в конце 4Гб диапозона плюс из за выравнивания будет браться удвоенное значение. 100000000h= 4ГБ 10000000h=256МБ 100000000h-2*10000000h=0E0000000h
Отнюдь. Видеопамять аппаратно проецируется на физадреса и процу по боку, есть ли там RAM или нету + про страничное преобразование я уже сказал, что надо создать страницу виртуальную, которая будет спроецирвана на этот адрес
Pavia Это значит, что на разных видеокартах разные диапазоны адресов? Подскажите функции для реализации этого или может поделитесь ссылкой?
Про апишки хала такие я не знаю, глянь в MSDN, а про аппаратную часть вот: http://www.wasm.ru/article.php?article=pipm06
Great Хм, интересно... Раньше я пропускал эту главу т.к. считал, что страничная адресация связана с файлом подкачки, а к невыгружаемым драйверам это не относится. В "хале" помойму нет ничего интересного, а вот в ntoskrnl.exe много функций, имена которых содержат слово "page". Что может означать AllocatePagesForMdl? Очень рассмешила такая фраза После неё идёт список недокументированых функций
виртуальная память - это фундаментальное понятие а то, что она может использоваться для реализации подкачки, это уже второе...
К подкачке она никаким раком не относится почти что ) Самое главное - это виртуализация адресного пространства.. Насколько я помню, есть функция MmMapIoSpace, которая вроде бы как раз проецирует физстраницы на виртуальное пространство... только я точно не помню. Почитай MSDN. На крайняк оперируй структурами сам, получая адрес через CR3
Да на разных видео картах разне диапозоны. Дак же на разных системах с одинаковыми видео картами диапозоны могут отличаться.
Great Адрес в CR3 - физический, то есть круг опять замкнётся! Ммм... MmMapIoSpace, говоришь? Я обязательно попробую. То есть надо просто вызвать эту функцию и всё? А как же преобразование линейного адреса в страничный?
Тебе система выдаст виртуальный адрес, соответствующий твоему физическому адресу видеобуфера. Дальше обращайся по этому виртуальному адресу и все.
При вызове invoke MmMapIoSpace,0E0000000h,65536,0,MmCached компьютер просто перезагружается Вот прототип MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress,IN ULONG NumberOfBytes,IN MEMORY_CACHING_TYPE CacheType); в ntoskrnl.inc определено 16 байт параметров. Я не знаком с C, ULONG - это 8 байт? Нужно ли вызывать MmUnmapIoSpace?
как это ты так передаешь я чета не врубил. и почему адрес физический у тебя 10000E0000000, а не E0000000 ? И число байт = 0 имхо, invoke MmMapIoSpace, 0E0000000h, 0, 65536, MmCached.
Great У меня непонятки с параметрами. Передаю так Физ. адрес - 4 байта число байт - 8 байт флажки - 4 байта Ты хочешь сказать что физ. адрес - 8 байт? Через какой селектор мне потом обращаться по полученому смещению? Через тот, который я создал с базой=0?
Great Ты как всегда прав. Вот что я выяснил экспериментальным путём: 0E0000000h - регистры или какие-нибудь управляющие структуры (при записи в них монитор отключается) 0D0000000h - видеопамять 0E1000000h - не проверял Помоги решить проблему переносимости. Я вот, что думаю: 1) В реестре есть ветка HKEY_LOCAL_MACHINE\HARDWARE\RESOURCEMAP\PnP Manager\PnPManager В нём 2 ключа: \Device\Video1.Raw и \Device\Video1.Translated Их значения остаются для меня загадкой. Может быть они содержат информацию о адресах памяти? 2) Можно использовать VBE сервисы для переключения в VGA-режим. В VGA режиме скорее всего память начинается с 0A0000h. Для восстановления предыдущего режима вроде-бы тоже есть спец функции. Но я работал с VBE только в реальном режиме через прерывание 10h. В защищёнке по-мойму используется прерывание 31h для эмуляции прерываний реального режима, но я не понял, как им пользоваться. PS Искал в реестре параметр со значением "D0000000", а также в двоичной и десятичной системах, ничего не найдено.