r5u870

Ricoh R5U870 Linux Driver
git clone https://logand.com/git/r5u870.git/
Log | Files | Refs | README | LICENSE

recode-fw.scm (3073B)


      1 #!/usr/bin/guile -s
      2 !#
      3 ;; script to extract the firmware from a windows driver file
      4 ;; (c) uuh 2007, herewith put into public domain
      5 ;;
      6 ;; inspection showed that the windows driver file 
      7 ;; SYSFILE contains blobs of firmware data mixed with the URB request data
      8 ;;
      9 ;;  <1-octet transfer length> for TransferBufferLength
     10 ;;  <2-octet lsb dest value>      for Value slot of request
     11 ;;  <1-octet index>           for Index slot of request
     12 ;; For the .fw files that we use we need the 4th octet thrown out, 
     13 ;; and leave the length in place (since INDEX is always 0x00)
     14 
     15 ;; the file that contains the firmware 
     16 (define *driverfile* "R5U870FLx86.sys")
     17 ;; where to put the result
     18 (define *destfile* "r5u870_183b.fw")
     19 ;; start address of firmware data in *DRIVERFILE* 
     20 (define *start* 46224)
     21 ;; length of data
     22 (define *length* 16981)
     23 
     24 (define *expected-md5sum* #f)
     25 
     26 ;;; no user-serviceable parts below
     27 
     28 
     29 ;; make sure we get sane byte behaviour
     30 (setlocale LC_ALL "C")
     31 
     32 (use-modules (ice-9 format))
     33 
     34 (define (read-N-bytes count)
     35   "Read N bytes from CURRENT-INPUT-PORT, failing hard if not enough are there."
     36   (with-output-to-string 
     37     (lambda ()
     38       (let loop ((remaining count))
     39 	(if (> remaining 0)
     40 	    (begin (write-char (read-char))
     41 		   (loop (- remaining 1))))))))
     42 
     43 (define (write-N-bytes count data)
     44   "Write N bytes from DATA to CURRENT-OUTPUT-PORT, failing hard if not enough are there."
     45   (with-input-from-string data
     46     (lambda ()
     47       (let loop ((remaining count))
     48 	(if (> remaining 0)
     49 	    (begin (write-char (read-char))
     50 		   (loop (- remaining 1))))))))
     51 
     52 (define (driversegment->fw string)
     53   "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."
     54   (with-output-to-string 
     55     (lambda ()
     56       (with-input-from-string string
     57 	(lambda ()
     58 	  (let loop ()
     59 	    (if (eof-object? (peek-char))
     60 		(format (current-error-port) "done~%")
     61 		(begin
     62 		  (let* ((lenbyte (read-char))
     63 			 (lenint (char->integer lenbyte))
     64 			 (addrbyte1 (read-char))
     65 			 (addrbyte2 (read-char))
     66 			 (ignoredbyte (read-char))
     67 			 (data (read-N-bytes lenint)))
     68 		    (format (current-error-port)
     69 			    "~d -> ~x; " lenint
     70 			    (logior (char->integer addrbyte1)
     71 				    (* 256 (char->integer addrbyte2))))
     72 		    (format #t "~c~c~c" lenbyte addrbyte1 addrbyte2)
     73 		    (write-N-bytes lenint data)
     74 		    (loop))))))))))
     75 
     76 (define (extract-slice file start length)
     77   "Return bytes START through START+LENGTH from FILE as a string"
     78   (with-input-from-file file
     79     (lambda ()
     80       (seek (current-input-port) start SEEK_SET)
     81       (read-N-bytes length))))
     82 
     83 ;; main:
     84 (format (current-error-port)
     85 	"Decoding firmware from ~A into ~A:~%" *driverfile* *destfile*)
     86 (with-output-to-file *destfile*
     87   (lambda ()
     88     (let ((extracted-data (driversegment->fw
     89 			   (extract-slice *driverfile* *start* *length*))))
     90       (format (current-error-port)
     91 	      "Result has length ~d~%" (string-length extracted-data) )
     92       (write-N-bytes (string-length extracted-data) extracted-data))))