Serge
Для APM кроме гашения экрана примеров нет, всё руки не доходят написать что нибудь сносное.
Идея не сохранять ds,es меня тоже посещала, но подумав что какая нибудь функция их использует (аля [ESP+44]/[ESP+48]) идея ушла (нужно проверить все функции). Ещё есть идея уйти от сохранения в стеке и "заворачивания" (зачем - вообще не понятно) всех регистров, т.к. многие функции почти не портят регистры, но для этого нужно перелатать всё ядро.
Fast System Call
Ghost
Я проверил работу без сохранения ds и es. Всё работает. На быстрых вызовах даёт заметный прирост. Сегменты можно было загружать всего один раз если бы не дурацкая осбенность IA32. Все дескрипторы проверяются при загрузке селектора и выдают ошибку сразу, а gdt[0] нельзя использовать но можно загружать без всяких проверок. Приходится в обработчиках прерываний явно перегружать селекторы.
Я проверил работу без сохранения ds и es. Всё работает. На быстрых вызовах даёт заметный прирост. Сегменты можно было загружать всего один раз если бы не дурацкая осбенность IA32. Все дескрипторы проверяются при загрузке селектора и выдают ошибку сразу, а gdt[0] нельзя использовать но можно загружать без всяких проверок. Приходится в обработчиках прерываний явно перегружать селекторы.
Ghost
Пришла в идея как сделать альтернативную точку входа в ядро для программ, сервисов и драйверов пользовательского режима.
Верхние 4 Мб памяти приложения образуют область локальных данных потока. Каждый поток в многопоточном приложении сможет выделить там память для своих локальных переменных которые будут защищены от других потоков.
Вершину этой области займут системные данные. Сверху вниз: каталог таблиц страниц (PDBR), область сохранения FPU, точка входа ядра, стек. Все адреса будут фиксированными (по крайней мере пока ядро загруженно) Кроме того в зависимости от типа приложения на место точки входа будет копироваться соответствующий код. Таким образом каждая программа вызывая прерывание или fastcall попадёт именно на свою точку входа, а ядро сможет безопасно экспортировать для драйверов и сервисов функции к которым обычные программы не должны иметь доступ.
Адреса стека и входа будут опрделяться при загрузке ядра (будут задаваться константами) так что никаких вычислений делать не надо.
Надо подумать над передачей параметров для новых вызовов
Пришла в идея как сделать альтернативную точку входа в ядро для программ, сервисов и драйверов пользовательского режима.
Верхние 4 Мб памяти приложения образуют область локальных данных потока. Каждый поток в многопоточном приложении сможет выделить там память для своих локальных переменных которые будут защищены от других потоков.
Вершину этой области займут системные данные. Сверху вниз: каталог таблиц страниц (PDBR), область сохранения FPU, точка входа ядра, стек. Все адреса будут фиксированными (по крайней мере пока ядро загруженно) Кроме того в зависимости от типа приложения на место точки входа будет копироваться соответствующий код. Таким образом каждая программа вызывая прерывание или fastcall попадёт именно на свою точку входа, а ядро сможет безопасно экспортировать для драйверов и сервисов функции к которым обычные программы не должны иметь доступ.
Адреса стека и входа будут опрделяться при загрузке ядра (будут задаваться константами) так что никаких вычислений делать не надо.
Надо подумать над передачей параметров для новых вызовов
мега-кул, ребята! ваши иследования помогли разобраться в теме int vs sysenter..
вобщем, тоже вот крутилась в голове идея на тему "служебных входов" в kmode в win2k, без особо лишних телодвижений (иногда довольно тесно приходится общаться с железяками, в связке с SoftICE).
И хотя это было не особо актуально - ну какбы усё боле-менее работало через драйвера, а вот решил заюзать прерывания - всетаки, как никак инструкция CPU, а не какие нить, системные функции (в которых я мало рублю, да и так, надебажив, этак с километр, пропадет охота там чето юзать).
что получилось.. поскрёб тут по сусекам в поисках DPL3 backdor'ов, и ага! int 2Ah, вроде как без дела торчит, с софт-айсом выйти на код обработчика, трабл особо никаких. не долго думая меняю обработчик забитый в глубинах
ntoskrnl следующим макаром.
и.. бугага, бугага, бугага, код пашет так как и планировалось - в ring3 проге, обрабатываю прерывания.
Потом мне этого показалось маловато, решил зохавать и sysenter. Вот, нарисовалась тестовая прога.
Wait... int test: 4204, sysenter test: 1031
в принципе, с пивком потянет.
Так, веду кой какие разработки DOSx расширителя (по мотивам WDOSx & FreeDOS32),
вот.. ну а эNTяа2k, довольно ничего так полигон, для обкатки решений..
боле-менее на DOS начал смахивать, (хыы, а вместо Turbo Pascal7 - Turbo Delphi)... вотъ...
вобщем, тоже вот крутилась в голове идея на тему "служебных входов" в kmode в win2k, без особо лишних телодвижений (иногда довольно тесно приходится общаться с железяками, в связке с SoftICE).
И хотя это было не особо актуально - ну какбы усё боле-менее работало через драйвера, а вот решил заюзать прерывания - всетаки, как никак инструкция CPU, а не какие нить, системные функции (в которых я мало рублю, да и так, надебажив, этак с километр, пропадет охота там чето юзать).
что получилось.. поскрёб тут по сусекам в поисках DPL3 backdor'ов, и ага! int 2Ah, вроде как без дела торчит, с софт-айсом выйти на код обработчика, трабл особо никаких. не долго думая меняю обработчик забитый в глубинах
ntoskrnl следующим макаром.
Code: Select all
xchg ecx, esp
jmp ecx
Code: Select all
function int2A (_eax, _edx, _ecx :integer):integer;
asm
pop ecx // eip to return in r3
int $2A
nop
nop
nop
nop
iretd;
end;
результаты (на cel-1300):{$apptype console}
program test; uses windows;
const
count = 20000000;
MSR_SYSENTER_CS = $174;
MSR_SYSENTER_ESP = $175;
MSR_SYSENTER_EIP = $176;
var i, dwStart : integer;
function sys_enter:integer;
asm
sti
sysexit
end;
function sysenter(_eax, _edx, _ecx :integer):integer;
asm
pop edx // eip to return in r3
mov ecx, esp // esp to return in r3
sysenter
end;
function int2A (_eax, _edx, _ecx :integer):integer;
asm
pop ecx // eip to return in r3
int $2A
nop
nop
nop
nop
iretd;
end;
procedure setup_MSR;
asm
pop ecx
mov ebp, esp
int $2A
xor edx, edx
lea eax, sys_enter //загрузить указатель обработчика
mov ecx, MSR_SYSENTER_EIP
wrmsr
mov ecx, MSR_SYSENTER_CS
mov eax, 8 //WinNT kmode selector
wrmsr
mov eax, ebp
mov ecx, MSR_SYSENTER_ESP
wrmsr
iretd
end;
begin
write ('Wait... ');
Setup_MSR;
dwStart := GetTickCount;
for i:= 0 to count do int2A(0,0,0);
Write('int test: ', GetTickCount - dwStart, ', ');
dwStart := GetTickCount;
for i:= 0 to count do sysenter(0,0,0);
Writeln('sysenter test: ', GetTickCount - dwStart);
end.
Wait... int test: 4204, sysenter test: 1031
в принципе, с пивком потянет.
Так, веду кой какие разработки DOSx расширителя (по мотивам WDOSx & FreeDOS32),
вот.. ну а эNTяа2k, довольно ничего так полигон, для обкатки решений..
боле-менее на DOS начал смахивать, (хыы, а вместо Turbo Pascal7 - Turbo Delphi)... вотъ...
ой.. сори очепятался с esp... ну конечно же
смещения для ntoskrnl for win2ksp2 (ProductVersion 5.00.2195.2951)...
реальная тачка несравниться с VMWARE или VirtPC не тот драйв...
Code: Select all
00064DBC: 870C24 xchg ecx,[esp]
00064DBF: FFE1 jmp ecx
00064DC1: 90 nop
реальная тачка несравниться с VMWARE или VirtPC не тот драйв...
N†OSKRNL
Про SYSENTER + win2k : http://www.anticracking.sk/EliCZ/infos/syscall.zip
Это конечно здорово, но в рамках Колибри оффтоп )
Про SYSENTER + win2k : http://www.anticracking.sk/EliCZ/infos/syscall.zip
Это конечно здорово, но в рамках Колибри оффтоп )
Ghost - спасибо, комрад, супер семпл! просто когда темой занялся, гоогл вот к вам забросил, чему я весьма признателен... ну вы монстры!))) Serge - мега респект!
а селекторных регистров , воистину нужно избегать, всеми путями.. да уж
вон скажем, тот же int 2a думал юзать без лишних регистровых
затрат, на передачу тогоже pop ecx .. однако в итоге пришлось таких огородов
городить (навроде откопать указатель из стека, нормализовать данные), что пришлось таки отказаться, от такого казалосьбы, небольшого удобства.. (да и не поместилось оно в очень сжатых рамках обработчика =(((
а селекторных регистров , воистину нужно избегать, всеми путями.. да уж
которые так и прут, особено в экстримальнейших местах, таких как обработка прерываний или исключений.если бы не дурацкая осбенность IA32
вон скажем, тот же int 2a думал юзать без лишних регистровых
затрат, на передачу тогоже pop ecx .. однако в итоге пришлось таких огородов
городить (навроде откопать указатель из стека, нормализовать данные), что пришлось таки отказаться, от такого казалосьбы, небольшого удобства.. (да и не поместилось оно в очень сжатых рамках обработчика =(((
Это глюк или так и должно быть: тест syscal при ядре из файла flat.7z показывает ускорение по сравнению с прерыванием, но в ядре svn 429 syscall уже в несколько раз медленее чем прерывание. При использовании обновленного syscall test выполняется только часть тестов.
Прирост производительности будет только на плоском ядре и на реальном железе.
Это вызвано тем, что размер буфера под данные доски отладки кто-то увеличил до 4096 байт (svn утверждает, что последним к соответствующей строчке прикасался mike.dld в ревизии 373), а приложение board при запуске очищает только 1024 байт.Heavyiron wrote:Кстати, обнаружил некоторую странность: начиная с какой-то ревизии (и в официальном и во flat-kernel) на доске отладки во вкладке USER есть надписи, типа "cess - done", иногда просто буква "e", иногда "New process: loadind" (в зависимости от того, где запускаю). Так и должно быть или это глюк?
Новые тесты с новой ревизией #442 на Barton 2500+ (K7):
69bdc73-> SYSENTER
880128C-> SYSCALL
BDbfC06-> Interrupt
Для сравнения результаты от Heavyiron
тест с новой ревизией #400 на Sempron 2500+ (K7):
880B78B -> SYSENTER
9E0104C -> SYSCALL
DE18A36 -> Interrupt
69bdc73-> SYSENTER
880128C-> SYSCALL
BDbfC06-> Interrupt
Для сравнения результаты от Heavyiron
тест с новой ревизией #400 на Sempron 2500+ (K7):
880B78B -> SYSENTER
9E0104C -> SYSCALL
DE18A36 -> Interrupt
Новые тесты на новом железе:
7F0C850 -> SYSENTER
9D87F5C -> SYSCALL
E6142A9 -> INT 0x40
7F0C850 -> SYSENTER
9D87F5C -> SYSCALL
E6142A9 -> INT 0x40
Все, для выбора варианта компиляции нужно изменить в svn\programs\config.inc значение переменной на "р5", "р6" либо "k6" для вызовов через прерывание, sysenter или syscall соответственно. После этого можно компилить старыми скриптами или же использовать build_all.bat, который спросит и все сделает сам, даже по папкам раскинет в \bin-е
Угу, и скомпилированные с "p6" и "k6" программы вообще не будут работать на старых компах до каких-то-там пней.
Ушёл к умным, знающим и культурным людям.
...и размерчик у выходных файлов с "p6"/"k6" заметно побольше будет...
Who is online
Users browsing this forum: No registered users and 12 guests