Module: docs Branch: master Commit: ea74781890720b7f8916dfb189a025331c79fbf2 URL: http://source.winehq.org/git/docs.git/?a=commit;h=ea74781890720b7f8916dfb189...
Author: André Hentschel nerv@dawncrow.de Date: Mon May 17 20:04:34 2010 +0200
winedev: Remove obsolete hardware trace section which may just be confusing.
---
en/winedev-otherdebug.sgml | 233 -------------------------------------------- 1 files changed, 0 insertions(+), 233 deletions(-)
diff --git a/en/winedev-otherdebug.sgml b/en/winedev-otherdebug.sgml index 0454a1f..e484cc9 100644 --- a/en/winedev-otherdebug.sgml +++ b/en/winedev-otherdebug.sgml @@ -1,238 +1,5 @@ <chapter id="otherdebug"> <title>Other debugging techniques</title> - <sect1 id="hardware-trace"> - <title>Doing A Hardware Trace</title> - - <para> - The primary reason to do this is to reverse engineer a - hardware device for which you don't have documentation, but - can get to work under Wine. - </para> - <para> - This lot is aimed at parallel port devices, and in particular - parallel port scanners which are now so cheap they are - virtually being given away. The problem is that few - manufactures will release any programming information which - prevents drivers being written for Sane, and the traditional - technique of using DOSemu to produce the traces does not work - as the scanners invariably only have drivers for Windows. - </para> - <para> - Presuming that you have compiled and installed wine the first - thing to do is to enable direct hardware access to your - parallel port. To do this edit <filename>config</filename> - (usually in <filename>~/.wine/</filename>) and in the - ports section add the following two lines - </para> - <programlisting> -read=0x378,0x379,0x37a,0x37c,0x77a -write=0x378,x379,0x37a,0x37c,0x77a - </programlisting> - <para> - This adds the necessary access required for SPP/PS2/EPP/ECP - parallel port on LPT1. You will need to adjust these number - accordingly if your parallel port is on LPT2 or LPT0. - </para> - <para> - When starting wine use the following command line, where - <literal>XXXX</literal> is the program you need to run in - order to access your scanner, and <literal>YYYY</literal> is - the file your trace will be stored in: - </para> - <programlisting> -WINEDEBUG=+io wine XXXX 2> >(sed 's/^[^:]*:io:[^ ]* //' > YYYY) - </programlisting> - <para> - You will need large amounts of hard disk space (read hundreds - of megabytes if you do a full page scan), and for reasonable - performance a really fast processor and lots of RAM. - </para> - <para> - You will need to postprocess the output into a more manageable - format, using the <command>shrink</command> program. First - you need to compile the source (which is located at the end of - this section): - <programlisting> -cc shrink.c -o shrink - </programlisting> - </para> - <para> - Use the <command>shrink</command> program to reduce the - physical size of the raw log as follows: - </para> - <programlisting> -cat log | shrink > log2 - </programlisting> - <para> - The trace has the basic form of - </para> - <programlisting> -XXXX > YY @ ZZZZ:ZZZZ - </programlisting> - <para> - where <literal>XXXX</literal> is the port in hexadecimal being - accessed, <literal>YY</literal> is the data written (or read) - from the port, and <literal>ZZZZ:ZZZZ</literal> is the address - in memory of the instruction that accessed the port. The - direction of the arrow indicates whether the data was written - or read from the port. - </para> - <programlisting> -> data was written to the port -< data was read from the port - </programlisting> - <para> - My basic tip for interpreting these logs is to pay close - attention to the addresses of the IO instructions. Their - grouping and sometimes proximity should reveal the presence of - subroutines in the driver. By studying the different versions - you should be able to work them out. For example consider the - following section of trace from my UMAX Astra 600P - </para> - <programlisting> -0x378 > 55 @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 -0x378 > aa @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 -0x378 > 00 @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 -0x378 > 00 @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 -0x378 > 00 @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 -0x378 > 00 @ 0297:01ec -0x37a > 05 @ 0297:01f5 -0x379 < 8f @ 0297:01fa -0x37a > 04 @ 0297:0211 - </programlisting> - <para> - As you can see there is a repeating structure starting at - address <literal>0297:01ec</literal> that consists of four io - accesses on the parallel port. Looking at it the first io - access writes a changing byte to the data port the second - always writes the byte <literal>0x05</literal> to the control - port, then a value which always seems to - <literal>0x8f</literal> is read from the status port at which - point a byte <literal>0x04</literal> is written to the control - port. By studying this and other sections of the trace we can - write a C routine that emulates this, shown below with some - macros to make reading/writing on the parallel port easier to - read. - </para> - <programlisting> -#define r_dtr(x) inb(x) -#define r_str(x) inb(x+1) -#define r_ctr(x) inb(x+2) -#define w_dtr(x,y) outb(y, x) -#define w_str(x,y) outb(y, x+1) -#define w_ctr(x,y) outb(y, x+2) - -/* Seems to be sending a command byte to the scanner */ -int udpp_put(int udpp_base, unsigned char command) -{ - int loop, value; - - w_dtr(udpp_base, command); - w_ctr(udpp_base, 0x05); - - for (loop=0; loop < 10; loop++) - if ((value = r_str(udpp_base)) & 0x80) - { - w_ctr(udpp_base, 0x04); - return value & 0xf8; - } - - return (value & 0xf8) | 0x01; -} - </programlisting> - <para> - For the UMAX Astra 600P only seven such routines exist (well - 14 really, seven for SPP and seven for EPP). Whether you - choose to disassemble the driver at this point to verify the - routines is your own choice. If you do, the address from the - trace should help in locating them in the disassembly. - </para> - <para> - You will probably then find it useful to write a script/perl/C - program to analyse the logfile and decode them futher as this - can reveal higher level grouping of the low level routines. - For example from the logs from my UMAX Astra 600P when decoded - further reveal (this is a small snippet) - </para> - <programlisting> -start: -put: 55 8f -put: aa 8f -put: 00 8f -put: 00 8f -put: 00 8f -put: c2 8f -wait: ff -get: af,87 -wait: ff -get: af,87 -end: cc -start: -put: 55 8f -put: aa 8f -put: 00 8f -put: 03 8f -put: 05 8f -put: 84 8f -wait: ff - </programlisting> - <para> - From this it is easy to see that <varname>put</varname> - routine is often grouped together in five successive calls - sending information to the scanner. Once these are understood - it should be possible to process the logs further to show the - higher level routines in an easy to see format. Once the - highest level format that you can derive from this process is - understood, you then need to produce a series of scans varying - only one parameter between them, so you can discover how to - set the various parameters for the scanner. - </para> - - <para> - The following is the <filename>shrink.c</filename> program: - <programlisting> -/* Copyright David Campbell <campbell@torque.net> */ -#include <stdio.h> -#include <string.h> - -int main (void) -{ - char buff[256], lastline[256] = ""; - int count = 0; - - while (!feof (stdin)) - { - fgets (buff, sizeof (buff), stdin); - if (strcmp (buff, lastline)) - { - if (count > 1) - printf ("# Last line repeated %i times #\n", count); - printf ("%s", buff); - strcpy (lastline, buff); - count = 1; - } - else count++; - } - return 0; -} - </programlisting> - </para> - </sect1>
<sect1 id="undoc-func"> <title>Understanding undocumented APIs</title>