commit 81859663a98909f9217482f5205d2d7ab2bbfa90
parent f4f16ed465bd95aee21e3d52b7e8488e77f181da
Author: alex <alex@022568fa-442e-4ef8-a3e8-54dcafdb011a>
Date: Wed, 16 Jan 2008 09:39:40 +0000
Add 'recode-fw.scm' file, so that new firmware can be extracted where
necessary, instead of hunting the file down in other places.
git-svn-id: http://svn.mediati.org/svn/r5u870/trunk@32 022568fa-442e-4ef8-a3e8-54dcafdb011a
Diffstat:
A | recode-fw.scm | | | 93 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 93 insertions(+), 0 deletions(-)
diff --git a/recode-fw.scm b/recode-fw.scm
@@ -0,0 +1,92 @@
+#!/usr/bin/guile -s
+!#
+;; script to extract the firmware from a windows driver file
+;; (c) uuh 2007, herewith put into public domain
+;;
+;; inspection showed that the windows driver file
+;; SYSFILE contains blobs of firmware data mixed with the URB request data
+;;
+;; <1-octet transfer length> for TransferBufferLength
+;; <2-octet lsb dest value> for Value slot of request
+;; <1-octet index> for Index slot of request
+;; For the .fw files that we use we need the 4th octet thrown out,
+;; and leave the length in place (since INDEX is always 0x00)
+
+;; the file that contains the firmware
+(define *driverfile* "R5U870FLx86.sys")
+;; where to put the result
+(define *destfile* "r5u870_183b.fw")
+;; start address of firmware data in *DRIVERFILE*
+(define *start* 46224)
+;; length of data
+(define *length* 16981)
+
+(define *expected-md5sum* #f)
+
+;;; no user-serviceable parts below
+
+
+;; make sure we get sane byte behaviour
+(setlocale LC_ALL "C")
+
+(use-modules (ice-9 format))
+
+(define (read-N-bytes count)
+ "Read N bytes from CURRENT-INPUT-PORT, failing hard if not enough are there."
+ (with-output-to-string
+ (lambda ()
+ (let loop ((remaining count))
+ (if (> remaining 0)
+ (begin (write-char (read-char))
+ (loop (- remaining 1))))))))
+
+(define (write-N-bytes count data)
+ "Write N bytes from DATA to CURRENT-OUTPUT-PORT, failing hard if not enough are there."
+ (with-input-from-string data
+ (lambda ()
+ (let loop ((remaining count))
+ (if (> remaining 0)
+ (begin (write-char (read-char))
+ (loop (- remaining 1))))))))
+
+(define (driversegment->fw string)
+ "Read chunks of <len-byte> <low address byte> <high address byte> <index byte> <LEN bytes data chunk> from FILE and return a string where the <index-byte> has been dropped."
+ (with-output-to-string
+ (lambda ()
+ (with-input-from-string string
+ (lambda ()
+ (let loop ()
+ (if (eof-object? (peek-char))
+ (format (current-error-port) "done~%")
+ (begin
+ (let* ((lenbyte (read-char))
+ (lenint (char->integer lenbyte))
+ (addrbyte1 (read-char))
+ (addrbyte2 (read-char))
+ (ignoredbyte (read-char))
+ (data (read-N-bytes lenint)))
+ (format (current-error-port)
+ "~d -> ~x; " lenint
+ (logior (char->integer addrbyte1)
+ (* 256 (char->integer addrbyte2))))
+ (format #t "~c~c~c" lenbyte addrbyte1 addrbyte2)
+ (write-N-bytes lenint data)
+ (loop))))))))))
+
+(define (extract-slice file start length)
+ "Return bytes START through START+LENGTH from FILE as a string"
+ (with-input-from-file file
+ (lambda ()
+ (seek (current-input-port) start SEEK_SET)
+ (read-N-bytes length))))
+
+;; main:
+(format (current-error-port)
+ "Decoding firmware from ~A into ~A:~%" *driverfile* *destfile*)
+(with-output-to-file *destfile*
+ (lambda ()
+ (let ((extracted-data (driversegment->fw
+ (extract-slice *driverfile* *start* *length*))))
+ (format (current-error-port)
+ "Result has length ~d~%" (string-length extracted-data) )
+ (write-N-bytes (string-length extracted-data) extracted-data))))
+\ No newline at end of file