Saturday, September 3, 2011

Rebuild of ntmio

I have been using ntmio for many years. I have just rebuild this tool to add a better support for 64 bit OS and some more features. ntmio.exe command is a user mode program. It is not allowed to access the hardware resources in the user mode. In order to perform those privileged operations the ntmio.exe program calls an underlying kernel driver: WINMIO.
Initially ntmio was using a kernel driver called OSAL from Thierry Vuillaume with STM. I enhanced OSAL to support 64 bit OS. However I recently came across the WINIO drivers from Yariv Kaplan with internal.com. I found the code of WINIO is more up to date. With the permission of Yariv, I have modified the driver with finer granularity sizes and access to some CPU registers. The result is called WINMIO for WINdows Memory and IO. The new user application ntmio.exe has version 200 and up. It loads the WINMIO driver during runtime.

Get MMIO base

Another snippet

The calling batch file, gets the MMIO base and adds an offset

echo getting the MMIO base add
set add=
call get_MMIO_base.bat add
hex %add% 2AC
call setvar
echo.
set add=%HEXRET%

The code in get_MMIO_base.bat

@echo off
ntmio i w 8 cd6 24
ntmio i r 8 cd7 k fe
call setvar
set b0=%NTREAD%

ntmio i w 8 cd6 25
ntmio i r 8 cd7
call setvar
set b1=%NTREAD%

ntmio i w 8 cd6 26
ntmio i r 8 cd7
call setvar
set b2=%NTREAD%

ntmio i w 8 cd6 27
ntmio i r 8 cd7
call setvar
set b3=%NTREAD%

echo MMIO base is %b3%%b2%%b1%%b0%
set %1=%b3%%b2%%b1%%b0%

Get a base address from BAR

Here a sample code to get a base address from a PCI BAR register.

Calling program

set EHCI_BASE=0
::EHCI_BASE =  contents of pciconfig - Bus 0 device 18 function 2 register 10h
call get_EHCI_BASE_base EHCI_BASE
echo EHCI_BASE is %EHCI_BASE%

get_EHCI_BASE_base implementation in the file get_EHCI_BASE_base.bat

@echo off
ntmio p r 32 80009210 k fffffff8 > nul
call setvar
set %1=%NTREAD%

Simple loop with hex index

This is the same as the simple loop but the index is in Hexadecimal. It uses a small program hex.exe to increment the index.

@echo off
set count=0

:debut
echo address is DF0F000%count%

:: put your code here

hex %count% 1
call setvar
echo.
set count=%HEXRET%
if %count%.==10. goto the_end

goto debut
:the_end

Simple loop

I use this snippet frequently.

@echo off
set count=0

:debut
echo loop# %count%

:: put your code here

set /a count=%count% +1
if %count%.==100. goto the_end

goto debut
:the_end