CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
firmware_load.h-Dateireferenz
+ Dieser Graph zeigt, welche Datei direkt oder indirekt diese Datei enthält:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  bufrange
 
struct  firmware
 

Makrodefinitionen

#define MIN(a, b)   ((a) < (b) ? (a) : (b))
 
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
 
#define OS_DRYOS   0
 
#define OS_VXWORKS   1
 

Typdefinitionen

typedef struct bufrange BufRange
 

Funktionen

void load_firmware (firmware *fw, const char *filename, const char *base_addr, const char *alt_base_addr, int os_type)
 
int idx_valid (firmware *fw, int i)
 
uint32_t idx2adr (firmware *fw, int idx)
 
int adr2idx (firmware *fw, uint32_t adr)
 
char * adr2ptr (firmware *fw, uint32_t adr)
 
int idxcorr (firmware *fw, int idx)
 
void set_ignore_errors (int n)
 
uint32_tfwadr (firmware *fw, int i)
 
uint32_t fwval (firmware *fw, int i)
 
int fwRd (firmware *fw, int i)
 
int fwRn (firmware *fw, int i)
 
int fwRnMOV (firmware *fw, int i)
 
int fwOp2 (firmware *fw, int i)
 
int idxFollowBranch (firmware *fw, int fidx, int offset)
 
uint32_t followBranch (firmware *fw, uint32_t fadr, int offset)
 
uint32_t followBranch2 (firmware *fw, uint32_t fadr, int offset)
 
uint32_t LDR2adr (firmware *fw, int offset)
 
uint32_t LDR2idx (firmware *fw, int offset)
 
uint32_t LDR2val (firmware *fw, int offset)
 
uint32_t ADR2adr (firmware *fw, int offset)
 
uint32_t ALUop2 (firmware *fw, int offset)
 
uint32_t ALUop2a (firmware *fw, int offset)
 
int isLDR_PC (firmware *fw, int offset)
 
int isLDR_SP (firmware *fw, int offset)
 
int isLDR_PC_cond (firmware *fw, int offset)
 
int isADR_PC (firmware *fw, int offset)
 
int isADR_PC_cond (firmware *fw, int offset)
 
int isLDMFD (firmware *fw, int offset)
 
int isLDMFD_PC (firmware *fw, int offset)
 
int isLDR (firmware *fw, int offset)
 
int isLDR_cond (firmware *fw, int offset)
 
int isADR (firmware *fw, int offset)
 
int isSTMFD (firmware *fw, int offset)
 
int isSTMFD_LR (firmware *fw, int offset)
 
int isSTR (firmware *fw, int offset)
 
int isSTR_cond (firmware *fw, int offset)
 
int isBX (firmware *fw, int offset)
 
int isBX_LR (firmware *fw, int offset)
 
int isBLX (firmware *fw, int offset)
 
int isBL (firmware *fw, int offset)
 
int isBL_cond (firmware *fw, int offset)
 
int isBLEQ (firmware *fw, int offset)
 
int isB (firmware *fw, int offset)
 
int isBorBL (firmware *fw, int offset)
 
int isCMP (firmware *fw, int offset)
 
int isMOV (firmware *fw, int offset)
 
int isMOV_immed (firmware *fw, int offset)
 
int isORR (firmware *fw, int offset)
 
int isADD (firmware *fw, int offset)
 
int isSUB (firmware *fw, int offset)
 
int isASCIIstring (firmware *fw, uint32_t adr)
 
int find_str (firmware *fw, char *str)
 
int find_Nth_str (firmware *fw, char *str, int N)
 
int find_inst (firmware *fw, int(*inst)(firmware *, int), int idx, int len)
 
int find_inst_rev (firmware *fw, int(*inst)(firmware *, int), int idx, int len)
 
int find_Nth_inst (firmware *fw, int(*inst)(firmware *, int), int idx, int len, int N)
 
int find_Nth_inst_rev (firmware *fw, int(*inst)(firmware *, int), int idx, int len, int N)
 
int find_strptr_ref (firmware *fw, char *str)
 
int find_str_ref (firmware *fw, char *str)
 
int find_nxt_str_ref (firmware *fw, int str_adr, int ofst)
 
int find_nxt_str_ref_alt (firmware *fw, char *str, int ofst, int limit)
 
int find_BL (firmware *fw, int k, uint32_t v1, uint32_t v2)
 
int find_B (firmware *fw, int k, uint32_t v1, uint32_t v2)
 
int search_fw (firmware *fw, int(*func)(firmware *, int, uint32_t, uint32_t), uint32_t v1, uint32_t v2, int len)
 
int search_fw_bytes (firmware *fw, int(*func)(firmware *, int))
 

Makro-Dokumentation

#define MAX (   a,
 
)    ((a) > (b) ? (a) : (b))

Definiert in Zeile 20 der Datei firmware_load.h.

#define MIN (   a,
 
)    ((a) < (b) ? (a) : (b))

Definiert in Zeile 19 der Datei firmware_load.h.

#define OS_DRYOS   0

Definiert in Zeile 30 der Datei firmware_load.h.

#define OS_VXWORKS   1

Definiert in Zeile 31 der Datei firmware_load.h.

Dokumentation der benutzerdefinierten Typen

typedef struct bufrange BufRange

Dokumentation der Funktionen

uint32_t ADR2adr ( firmware fw,
int  offset 
)

Definiert in Zeile 309 der Datei firmware_load.c.

310 {
311  uint32_t inst = fwval(fw,offset);
312  int rot = 32 - ((inst & 0xF00) >> 7);
313  int offst = (inst & 0xFF) <<rot;
314  uint32_t fadr = 0;
315  switch (inst & 0x01E00000)
316  {
317  case 0x00400000: // SUB
318  fadr = idx2adr(fw,offset+2)-offst;
319  break;
320  case 0x00800000: // ADD
321  fadr = idx2adr(fw,offset+2)+offst;
322  break;
323  case 0x01A00000: // MOV
324  //fprintf(stderr,"***** ADR2adr MOV\n");
325  break;
326  case 0x01E00000: // MVN
327  //fprintf(stderr,"***** ADR2adr MVN\n");
328  break;
329  }
330  return fadr;
331 }
int adr2idx ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 165 der Datei firmware_load.c.

166 {
167  if (adr < fw->base)
168  return -((fw->base - adr) >> 2);
169  else
170  return (adr - fw->base) >> 2;
171 }
char* adr2ptr ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 174 der Datei firmware_load.c.

175 {
176  if ((fw->dryos_ver >= 51) && (fw->alt_base) && (adr >= fw->alt_base))
177  {
178  return ((char*)fw->buf) + (adr - fw->alt_base);
179  }
180  if ((fw->dryos_ver >= 50) && (adr < fw->base))
181  {
182  adr = (adr - fw->base2) + fw->base_copied;
183  }
184  return ((char*)fw->buf) + (adr - fw->base);
185 }
uint32_t ALUop2 ( firmware fw,
int  offset 
)

Definiert in Zeile 334 der Datei firmware_load.c.

335 {
336  uint32_t inst = fwval(fw,offset);
337  int rot = 32 - ((inst & 0xF00) >> 7);
338  int offst = (inst & 0xFF) <<rot;
339  uint32_t fadr = 0;
340  switch (inst & 0x03E00000)
341  {
342  case 0x02400000: // SUB Immed
343  case 0x02800000: // ADD Immed
344  case 0x03400000: // CMP Immed
345  case 0x03A00000: // MOV Immed
346  case 0x03C00000: // BIC Immed
347  fadr = offst;
348  break;
349  }
350  return fadr;
351 }
uint32_t ALUop2a ( firmware fw,
int  offset 
)

Definiert in Zeile 354 der Datei firmware_load.c.

355 {
356  uint32_t inst = fwval(fw,offset);
357  uint32_t rot = (inst>>7)&0x1e;
358  uint32_t imm8 = inst & 0xff;
359  uint32_t offst = (imm8>>rot) | (imm8<<(32-rot));
360  uint32_t fadr = 0;
361  switch (inst & 0x03E00000)
362  {
363  case 0x02400000: // SUB Immed
364  case 0x02800000: // ADD Immed
365  case 0x03A00000: // MOV Immed
366  case 0x03C00000: // BIC Immed
367  case 0x03800000: // ORR Immed
368  fadr = offst;
369  break;
370  }
371  return fadr;
372 }
int find_B ( firmware fw,
int  k,
uint32_t  v1,
uint32_t  v2 
)
int find_BL ( firmware fw,
int  k,
uint32_t  v1,
uint32_t  v2 
)
int find_inst ( firmware fw,
int(*)(firmware *, int)  inst,
int  idx,
int  len 
)

Definiert in Zeile 692 der Datei firmware_load.c.

693 {
694  int k;
695  for (k = idx; (k < fw->size) && (k < idx + len); k++)
696  {
697  if (inst(fw, k))
698  return k;
699  }
700  return -1;
701 }
int find_inst_rev ( firmware fw,
int(*)(firmware *, int)  inst,
int  idx,
int  len 
)

Definiert in Zeile 705 der Datei firmware_load.c.

706 {
707  int k;
708  for (k = idx; (k > 0) && (k > idx - len); k--)
709  {
710  if (inst(fw, k))
711  return k;
712  }
713  return -1;
714 }
int find_Nth_inst ( firmware fw,
int(*)(firmware *, int)  inst,
int  idx,
int  len,
int  N 
)

Definiert in Zeile 718 der Datei firmware_load.c.

719 {
720  int k;
721  for (k = idx; (k < fw->size) && (k < idx + len); k++)
722  {
723  if (inst(fw, k))
724  N--;
725  if (N <= 0)
726  return k;
727  }
728  return -1;
729 }
int find_Nth_inst_rev ( firmware fw,
int(*)(firmware *, int)  inst,
int  idx,
int  len,
int  N 
)

Definiert in Zeile 733 der Datei firmware_load.c.

734 {
735  int k;
736  for (k = idx; (k > 0) && (k > idx - len); k--)
737  {
738  if (inst(fw, k))
739  N--;
740  if (N <= 0)
741  return k;
742  }
743  return -1;
744 }
int find_Nth_str ( firmware fw,
char *  str,
int  N 
)

Definiert in Zeile 642 der Datei firmware_load.c.

643 {
644  int nlen = strlen(str);
645  uint32_t nm0 = *((uint32_t*)str);
646  uint32_t *p;
647  int j;
648 
649  BufRange *br = fw->br;
650  while (br)
651  {
652  for (p = br->p, j = 0; j < br->len - nlen/4; j++, p++)
653  {
654  if ((nm0 == *p) && ((nlen<=4) || (memcmp(p+1,str+4,nlen-4) == 0)) )
655  {
656  if (--N == 0)
657  return j+br->off;
658  }
659  }
660  br = br->next;
661  }
662 
663  return -1;
664 }
int find_nxt_str_ref ( firmware fw,
int  str_adr,
int  ofst 
)

Definiert in Zeile 808 der Datei firmware_load.c.

809 {
810  if (str_adr >= fw->lowest_idx)
811  {
812  int k;
813  uint32_t sadr = idx2adr(fw,str_adr); // string address
814  for (k=ofst+1; k<fw->size; k++)
815  {
816  if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
817  {
818  return k;
819  }
820  else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
821  {
822  return k;
823  }
824  }
825  }
826  return -1;
827 }
int find_nxt_str_ref_alt ( firmware fw,
char *  str,
int  ofst,
int  limit 
)

Definiert in Zeile 830 der Datei firmware_load.c.

831 {
832  int k;
833  for (k=ofst; k<ofst+limit; k++)
834  {
835  if (isADR_PC_cond(fw,k) && idx_valid(fw,adr2idx(fw,ADR2adr(fw,k))) && (strcmp(str,adr2ptr(fw,ADR2adr(fw,k))) == 0))
836  {
837  return k;
838  }
839  else if (isLDR_PC_cond(fw,k) && idx_valid(fw,adr2idx(fw,LDR2val(fw,k))) && (strcmp(str,adr2ptr(fw,LDR2val(fw,k))) == 0))
840  {
841  return k;
842  }
843  }
844  return -1;
845 }
int find_str ( firmware fw,
char *  str 
)

Definiert in Zeile 666 der Datei firmware_load.c.

667 {
668  return find_Nth_str(fw, str, 1);
669 }
int find_str_ref ( firmware fw,
char *  str 
)

Definiert in Zeile 786 der Datei firmware_load.c.

787 {
788  int k = find_str(fw, str);
789  if (k >= fw->lowest_idx)
790  {
791  uint32_t sadr = idx2adr(fw,k); // string address
792  for (k=0; k<fw->size; k++)
793  {
794  if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
795  {
796  return k;
797  }
798  else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
799  {
800  return k;
801  }
802  }
803  }
804  return -1;
805 }
int find_strptr_ref ( firmware fw,
char *  str 
)

Definiert in Zeile 753 der Datei firmware_load.c.

754 {
755  uint32_t sadr = find_str_bytes(fw, str); // string address
756  if (sadr > 0)
757  {
758  int k;
759  for (k=0; k<fw->size; k++)
760  {
761  if (fwval(fw,k) == sadr)
762  {
763  uint32_t fadr = idx2adr(fw,k); // string pointer address
764  int j;
765  for (j=0; j<fw->size; j++)
766  {
767  if (isADR_PC_cond(fw,j) && (ADR2adr(fw,j) == fadr))
768  {
769  return j;
770  }
771  else if (isLDR_PC_cond(fw,j) && (LDR2val(fw,j) == fadr))
772  {
773  return j;
774  }
775  }
776  }
777  }
778  }
779  return -1;
780 }
uint32_t followBranch ( firmware fw,
uint32_t  fadr,
int  offset 
)

Definiert in Zeile 406 der Datei firmware_load.c.

407 {
408  if (offset)
409  {
410  uint32_t msk = ~(offset & 0xFF000000);
411  uint32_t fidx = adr2idx(fw,fadr); // function index
412  fidx += ((offset & 0x00FFFFFF) - 1);
413  uint32_t inst = fwval(fw,fidx);
414  if ((inst & (0xFF000000&msk)) == (0xEA000000&msk)) // Branch (B or BL depending on msk)
415  {
416  int o = inst & 0x00FFFFFF;
417  if (o & 0x00800000) o |= 0xFF000000;
418  if (idx_valid(fw,fidx+o+2))
419  fadr = idx2adr(fw,fidx+o+2);
420  }
421  else if ((inst & (0xFFFFF000)) == (0xE51FF000)) // LDR PC,=...
422  {
423  fadr = LDR2val(fw,fidx);
424  }
425  }
426  return fadr;
427 }
uint32_t followBranch2 ( firmware fw,
uint32_t  fadr,
int  offset 
)

Definiert in Zeile 430 der Datei firmware_load.c.

431 {
432  fadr = followBranch(fw, fadr, offset);
433  if ((offset & 0x00FFFFFF) == 1)
434  fadr = followBranch(fw, fadr, offset);
435  return fadr;
436 }
uint32_t* fwadr ( firmware fw,
int  i 
)

Definiert in Zeile 223 der Datei firmware_load.c.

224 {
225  if ((i >= 0) && (i < fw->size))
226  return &fw->buf[i];
227  if ((fw->dryos_ver >= 51) && (fw->alt_base) && (i >= fw->size))
228  {
229  i = ((i * 4) - (fw->alt_base - fw->base)) / 4;
230  if ((i >= 0) && (i < fw->size))
231  return &fw->buf[i];
232  }
233  if ((fw->dryos_ver >= 50) && (i < 0))
234  {
235  i = ((i * 4) + (fw->base - fw->base2)) / 4;
236  if ((i >= 0) && (i < fw->size2))
237  return &fw->buf2[i];
238  }
239  if (ignore_errors)
240  {
241  return &fw->buf[0];
242  }
243  fprintf(stderr,"Invalid firmware offset %d.\n",i);
244  error("\nInvalid firmware offset %d. Possible corrupt firmware or incorrect start address.\n",i);
245  return 0;
246 }
int fwOp2 ( firmware fw,
int  i 
)

Definiert in Zeile 276 der Datei firmware_load.c.

277 {
278  // Operand2
279  return (*fwadr(fw,i) & 0x00000FFF);
280 }
int fwRd ( firmware fw,
int  i 
)

Definiert in Zeile 255 der Datei firmware_load.c.

256 {
257  // Destination register - Rd
258  return (*fwadr(fw,i) & 0x0000F000) >> 12;
259 }
int fwRn ( firmware fw,
int  i 
)

Definiert in Zeile 262 der Datei firmware_load.c.

263 {
264  // Source register - Rn
265  return (*fwadr(fw,i) & 0x000F0000) >> 16;
266 }
int fwRnMOV ( firmware fw,
int  i 
)

Definiert in Zeile 269 der Datei firmware_load.c.

270 {
271  // Source register - Rn
272  return (*fwadr(fw,i) & 0x0000000F);
273 }
uint32_t fwval ( firmware fw,
int  i 
)

Definiert in Zeile 249 der Datei firmware_load.c.

250 {
251  return *fwadr(fw,i);
252 }
uint32_t idx2adr ( firmware fw,
int  idx 
)

Definiert in Zeile 159 der Datei firmware_load.c.

160 {
161  return fw->base + (idx << 2);
162 }
int idx_valid ( firmware fw,
int  i 
)

Definiert in Zeile 136 der Datei firmware_load.c.

137 {
138  if ((i >= 0) && (i < fw->size))
139  return 1;
140  if ((fw->dryos_ver >= 51) && (fw->alt_base) && (i >= fw->size))
141  {
142  i = ((i * 4) - (fw->alt_base - fw->base)) / 4;
143  if ((i >= 0) && (i < fw->size))
144  return 1;
145  }
146  if (fw->dryos_ver >= 50)
147  {
148  int i2 = ((i * 4) + (fw->base - fw->base2)) / 4;
149  if ((i2 >= 0) && (i2 < fw->size2))
150  return 1;
151  // RAM code can also reference ROM, check for that
152  if (idx2adr(fw,i)>=fw->base && idx2adr(fw,i)<(fw->base+fw->size*4))
153  return 1;
154  }
155  return 0;
156 }
int idxcorr ( firmware fw,
int  idx 
)

Definiert in Zeile 188 der Datei firmware_load.c.

189 {
190  static int inited = 0;
191  static int b2oidx, b2idx;
192  if (!inited)
193  {
194  b2oidx = adr2idx(fw, fw->base_copied);
195  b2idx = adr2idx(fw, fw->base2);
196  inited = 1;
197  }
198 
199  if (fw->base2)
200  {
201  if ((idx >= b2oidx) && (idx < b2oidx + fw->size2))
202  {
203  idx = idx - b2oidx + b2idx;
204  }
205  }
206  return idx;
207 }
int idxFollowBranch ( firmware fw,
int  fidx,
int  offset 
)

Definiert in Zeile 383 der Datei firmware_load.c.

384 {
385  if (offset)
386  {
387  uint32_t msk = ~(offset & 0xFF000000);
388  fidx += ((offset & 0x00FFFFFF) - 1);
389  uint32_t inst = fwval(fw,fidx);
390  if ((inst & (0xFF000000&msk)) == (0xEA000000&msk)) // Branch (B or BL depending on msk)
391  {
392  int o = inst & 0x00FFFFFF;
393  if (o & 0x00800000) o |= 0xFF000000;
394  fidx = fidx + o + 2;
395  }
396  else if ((inst & (0xFFFFF000)) == (0xE51FF000)) // LDR PC,=...
397  {
398  fidx = adr2idx(fw,LDR2val(fw,fidx));
399  }
400  }
401  return fidx;
402 }
int isADD ( firmware fw,
int  offset 
)

Definiert in Zeile 605 der Datei firmware_load.c.

606 {
607  return ((fwval(fw,offset) & 0xfff00000) == 0xe2800000);
608 }
int isADR ( firmware fw,
int  offset 
)

Definiert in Zeile 485 der Datei firmware_load.c.

486 {
487  return ((fwval(fw,offset) & 0xFE000000) == 0xE2000000);
488 }
int isADR_PC ( firmware fw,
int  offset 
)

Definiert in Zeile 473 der Datei firmware_load.c.

474 {
475  return ((fwval(fw,offset) & 0xFE0F0000) == 0xE20F0000);
476 }
int isADR_PC_cond ( firmware fw,
int  offset 
)

Definiert in Zeile 479 der Datei firmware_load.c.

480 {
481  return ((fwval(fw,offset) & 0x0E0F0000) == 0x020F0000);
482 }
int isASCIIstring ( firmware fw,
uint32_t  adr 
)

Definiert in Zeile 618 der Datei firmware_load.c.

619 {
620  if (idx_valid(fw, adr2idx(fw, adr)))
621  {
622  unsigned char *p = (unsigned char*)adr2ptr(fw, adr);
623  int i;
624  for (i = 0; (i < 100) && (p[i] != 0); i++)
625  {
626  if (!((p[i] == '\r') || (p[i] == '\n') || (p[i] == '\t') || ((p[i] >= 0x20) && (p[i] <= 0x7f))))
627  {
628  return 0;
629  }
630  }
631  if ((i >= 2) && (p[i] == 0))
632  return 1;
633  }
634  return 0;
635 }
int isB ( firmware fw,
int  offset 
)

Definiert in Zeile 569 der Datei firmware_load.c.

570 {
571  return ((fwval(fw,offset) & 0xFF000000) == 0xEA000000);
572 }
int isBL ( firmware fw,
int  offset 
)

Definiert in Zeile 551 der Datei firmware_load.c.

552 {
553  return ((fwval(fw,offset) & 0xFF000000) == 0xEB000000);
554 }
int isBL_cond ( firmware fw,
int  offset 
)

Definiert in Zeile 557 der Datei firmware_load.c.

558 {
559  return ((fwval(fw,offset) & 0x0F000000) == 0x0B000000);
560 }
int isBLEQ ( firmware fw,
int  offset 
)

Definiert in Zeile 563 der Datei firmware_load.c.

564 {
565  return ((fwval(fw,offset) & 0xFF000000) == 0x0B000000);
566 }
int isBLX ( firmware fw,
int  offset 
)

Definiert in Zeile 545 der Datei firmware_load.c.

546 {
547  return ((fwval(fw,offset) & 0xFFFFFFF0) == 0xE12FFF30);
548 }
int isBorBL ( firmware fw,
int  offset 
)

Definiert in Zeile 575 der Datei firmware_load.c.

576 {
577  return ((fwval(fw,offset) & 0xFE000000) == 0xEA000000);
578 }
int isBX ( firmware fw,
int  offset 
)

Definiert in Zeile 527 der Datei firmware_load.c.

528 {
529  return ((fwval(fw,offset) & 0xFFFFFFF0) == 0xE12FFF10);
530 }
int isBX_LR ( firmware fw,
int  offset 
)

Definiert in Zeile 539 der Datei firmware_load.c.

540 {
541  return (fwval(fw,offset) == 0xE12FFF1E);
542 }
int isCMP ( firmware fw,
int  offset 
)

Definiert in Zeile 581 der Datei firmware_load.c.

582 {
583  return ((fwval(fw,offset) & 0xFFF00000) == 0xE3500000);
584 }
int isLDMFD ( firmware fw,
int  offset 
)

Definiert in Zeile 491 der Datei firmware_load.c.

492 {
493  return ((fwval(fw,offset) & 0xFFFF0000) == 0xE8BD0000);
494 }
int isLDMFD_PC ( firmware fw,
int  offset 
)

Definiert in Zeile 497 der Datei firmware_load.c.

498 {
499  return ((fwval(fw,offset) & 0xFFFF8000) == 0xE8BD8000);
500 }
int isLDR ( firmware fw,
int  offset 
)

Definiert in Zeile 461 der Datei firmware_load.c.

462 {
463  return ((fwval(fw,offset) & 0xFE100000) == 0xE4100000);
464 }
int isLDR_cond ( firmware fw,
int  offset 
)

Definiert in Zeile 467 der Datei firmware_load.c.

468 {
469  return ((fwval(fw,offset) & 0x0E100000) == 0x04100000);
470 }
int isLDR_PC ( firmware fw,
int  offset 
)

Definiert in Zeile 443 der Datei firmware_load.c.

444 {
445  return ((fwval(fw,offset) & 0xFE1F0000) == 0xE41F0000);
446 }
int isLDR_PC_cond ( firmware fw,
int  offset 
)

Definiert in Zeile 449 der Datei firmware_load.c.

450 {
451  return ((fwval(fw,offset) & 0x0E1F0000) == 0x041F0000);
452 }
int isLDR_SP ( firmware fw,
int  offset 
)

Definiert in Zeile 455 der Datei firmware_load.c.

456 {
457  return ((fwval(fw,offset) & 0xFFFF0000) == 0xE59D0000);
458 }
int isMOV ( firmware fw,
int  offset 
)

Definiert in Zeile 587 der Datei firmware_load.c.

588 {
589  return ((fwval(fw,offset) & 0xFFF00000) == 0xE1A00000);
590 }
int isMOV_immed ( firmware fw,
int  offset 
)

Definiert in Zeile 593 der Datei firmware_load.c.

594 {
595  return ((fwval(fw,offset) & 0xFFF00000) == 0xE3A00000);
596 }
int isORR ( firmware fw,
int  offset 
)

Definiert in Zeile 599 der Datei firmware_load.c.

600 {
601  return ((fwval(fw,offset) & 0xFFF00000) == 0xE3800000);
602 }
int isSTMFD ( firmware fw,
int  offset 
)

Definiert in Zeile 503 der Datei firmware_load.c.

504 {
505  return ((fwval(fw,offset) & 0xFFFF0000) == 0xE92D0000);
506 }
int isSTMFD_LR ( firmware fw,
int  offset 
)

Definiert in Zeile 509 der Datei firmware_load.c.

510 {
511  return ((fwval(fw,offset) & 0xFFFF4000) == 0xE92D4000);
512 }
int isSTR ( firmware fw,
int  offset 
)

Definiert in Zeile 515 der Datei firmware_load.c.

516 {
517  return ((fwval(fw,offset) & 0xFE100000) == 0xE4000000);
518 }
int isSTR_cond ( firmware fw,
int  offset 
)

Definiert in Zeile 521 der Datei firmware_load.c.

522 {
523  return ((fwval(fw,offset) & 0x0E100000) == 0x04000000);
524 }
int isSUB ( firmware fw,
int  offset 
)

Definiert in Zeile 611 der Datei firmware_load.c.

612 {
613  return ((fwval(fw,offset) & 0xfff00000) == 0xe2400000);
614 }
uint32_t LDR2adr ( firmware fw,
int  offset 
)

Definiert in Zeile 285 der Datei firmware_load.c.

286 {
287  uint32_t inst = fwval(fw,offset);
288  int offst = (inst & 0xFFF);
289  uint32_t fadr = (inst & 0x00800000)?idx2adr(fw,offset+2)+offst:idx2adr(fw,offset+2)-offst;
290  return fadr;
291 }
uint32_t LDR2idx ( firmware fw,
int  offset 
)

Definiert in Zeile 294 der Datei firmware_load.c.

295 {
296  return adr2idx(fw,LDR2adr(fw,offset));
297 }
uint32_t LDR2val ( firmware fw,
int  offset 
)

Definiert in Zeile 300 der Datei firmware_load.c.

301 {
302  return fwval(fw,adr2idx(fw,LDR2adr(fw,offset)));
303 }
void load_firmware ( firmware fw,
const char *  filename,
const char *  base_addr,
const char *  alt_base_addr,
int  os_type 
)

Definiert in Zeile 923 der Datei firmware_load.c.

924 {
925  // Open file.
926  FILE *f = fopen(filename, "rb");
927  int i, j, k;
928 
929  if (f == NULL)
930  {
931  fprintf(stderr,"Error opening %s\n",filename);
932  usage("firmware open");
933  }
934 
935  // these are used regardless of camera generation, have to be initialized here
936  fw->buf2 = 0;
937  fw->base2 = 0;
938  fw->size2 = 0;
939 
940  fw->os_type = os_type;
941 
942  // File length
943  fseek(f,0,SEEK_END);
944  fw->size = (ftell(f)+3)/4;
945  fseek(f,0,SEEK_SET);
946 
947  // Save base addresses
948  fw->base = strtoul(base_addr, NULL, 0);
949  if (alt_base_addr)
950  fw->alt_base = strtoul(alt_base_addr, NULL, 0);
951  else
952  fw->alt_base = 0;
953 
954  // Max (old) sig size is 32, add extra space at end of buffer and fill with 0xFFFFFFFF
955  // Allows sig matching past end of firmware without checking each time in the inner loop
956  fw->buf = malloc((fw->size+32)*4);
957  k = fread(fw->buf, 4, fw->size, f);
958  fclose(f);
959 
960  // fill extra space in buffer
961  memset(&fw->buf[fw->size],0xff,32*4);
962 
963  // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
964  findRanges(fw);
965 
966  // Check for DIGIC 4+ dump
967  // assumes dump starting with either the main firmware or the bootloader
968  fw->main_offs = 0;
969  if (os_type == OS_DRYOS)
970  {
971  k = find_str(fw, "gaonisoy");
972  if (k != 1)
973  {
974  fw->main_offs = 0x10000 / 4;
975  }
976  }
977  // Get DRYOS version
978  fw->real_dryos_ver = fw->dryos_ver = 0;
979  if (os_type == OS_DRYOS)
980  {
981  k = find_str(fw, "DRYOS version 2.3, release #");
982  if (k != -1)
983  {
984  fw->real_dryos_ver = fw->dryos_ver = atoi(((char*)&fw->buf[k])+28);
985  fw->dryos_ver_str = (char*)&fw->buf[k];
986  }
987  }
988 
989  // Get firmware version info
990  fw->firmware_ver_str = 0;
991  k = find_str(fw, "Firmware Ver ");
992  if (os_type == OS_VXWORKS)
993  {
994  if (k < 0)
995  {
996  k = find_str(fw, "Firmware Version GM"); // ixus700
997  }
998  if (k < 0)
999  {
1000  k = find_str(fw, "Firmware Version "); // ixus30/40
1001  }
1002  }
1003  if (k != -1)
1004  {
1005  fw->firmware_ver_str = (char*)&fw->buf[k];
1006  fw->fwver_idx = k;
1007  }
1008 
1009  // Get camera name & platformid ***** UPDATE for new each new DryOS version *****
1010  fw->fsize = -((int)fw->base)/4;
1011  if (fw->alt_base) fw->fsize = -((int)fw->alt_base)/4;
1012  fw->cam_idx = -1;
1013  fw->pid_adr = 0xffffffff;
1014  fw->cam = 0;
1015  fw->pid = 0;
1016  if (os_type == OS_DRYOS)
1017  {
1018  if (fw->dryos_ver > 59) fw->dryos_ver = 59; // UPDATE when support is added for higher DryOS versions
1019  switch (fw->dryos_ver)
1020  {
1021  case 20:
1022  case 23:
1023  case 31:
1024  case 39:
1025  fw->cam_idx = adr2idx(fw,0xFFFE0110);
1026  fw->pid_adr = 0xFFFE0130;
1027  break;
1028  case 43:
1029  case 45:
1030  fw->cam_idx = adr2idx(fw,0xFFFE00D0);
1031  fw->pid_adr = 0xFFFE0130;
1032  break;
1033  case 47:
1034  fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40170:0xFFFE0170);
1035  fw->pid_adr = (fw->base==0xFF000000)?0xFFF40040:0xFFFE0040;
1036  break;
1037  case 49:
1038  case 50:
1039  case 51:
1040  case 52:
1041  if (fw->alt_base)
1042  {
1043  fw->cam_idx = adr2idx(fw,(fw->alt_base==0xFF000000)?0xFFF40190:0xFFFE0170);
1044  fw->pid_adr = (fw->alt_base==0xFF000000)?0xFFF40040:0xFFFE0040;
1045  if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) != 0))
1046  fw->cam_idx = adr2idx(fw,(fw->alt_base==0xFF000000)?0xFFF40170:0xFFFE0170);
1047  }
1048  else
1049  {
1050  fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40190:0xFFFE0170);
1051  fw->pid_adr = (fw->base==0xFF000000)?0xFFF40040:0xFFFE0040;
1052  if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) != 0))
1053  fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40170:0xFFFE0170);
1054  }
1055  break;
1056  case 54:
1057  fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFF40170:0xFFFF0170);
1058  fw->pid_adr = (fw->base==0xFF010000)?0xFFF40040:0xFFFF0040;
1059  break;
1060  case 55:
1061  case 57: // TODO: based on a single fw dump (ixus275)
1062  fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFFE0170:0xFFFF0170);
1063  fw->pid_adr = (fw->base==0xFF010000)?0xFFFE0040:0xFFFF0040;
1064  break;
1065  case 58:
1066  case 59:
1067  fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFFE03A0:0xFFFF03A0);
1068  fw->pid_adr = (fw->base==0xFF010000)?0xFFFE0270:0xFFFF0270;
1069  break;
1070  }
1071  }
1072  else
1073  {
1074  // IXUS 700 IXUS 30/40 IXUS 50 Other
1075  uint32_t vx_name_offsets[] = { 0xFFD70110, 0xFFD70120, 0xFFF80110, 0xFFFE0110 };
1076  uint32_t vx_pid_offsets[] = { 0xFFD70130, 0xFFD7014E, 0xFFF80130, 0xFFFE0130 };
1077  for (i=0; i<(int)(sizeof(vx_name_offsets)/sizeof(vx_name_offsets[0])); i++)
1078  {
1079  int k = adr2idx(fw,vx_name_offsets[i]);
1080  if (idx_valid(fw,k) && (strncmp((char*)fwadr(fw,k),"Canon ",6) == 0))
1081  {
1082  fw->cam_idx = k;
1083  fw->pid_adr = vx_pid_offsets[i];
1084  break;
1085  }
1086  }
1087  }
1088 
1089  // Extact camera name if found
1090  if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) == 0))
1091  {
1092  fw->cam = (char*)fwadr(fw,fw->cam_idx);
1093  }
1094 
1095  // Set ID if found
1096  if (idx_valid(fw,adr2idx(fw,fw->pid_adr)) && (fw->pid_adr != 0xffffffff))
1097  {
1098  // get the correct halfword
1099  fw->pid = (fwval(fw,adr2idx(fw,fw->pid_adr)) >> ((fw->pid_adr & 2)?16:0)) & 0xFFFF;
1100  }
1101 
1102  // Calc MAXRAMADDR
1103  fw->maxram = 0;
1104  if (os_type == OS_DRYOS)
1105  {
1106  if (((fw->buf[0x10 + fw->main_offs] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x11 + fw->main_offs] == 0xEE060F12))
1107  {
1108  fw->maxram = (1 << (((fw->buf[0x10 + fw->main_offs] & 0x3E) >> 1) + 1)) - 1;
1109  }
1110  else if (((fw->buf[0x14 + fw->main_offs] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x15 + fw->main_offs] == 0xEE060F12))
1111  {
1112  fw->maxram = (1 << (((fw->buf[0x14 + fw->main_offs] & 0x3E) >> 1) + 1)) - 1;
1113  }
1114  }
1115  else if (os_type == OS_VXWORKS)
1116  {
1117  for (k=16; k<100; k++)
1118  {
1119  if ((fw->buf[k] & 0xFFFF0FFF) == 0xEE060F12) // mcr 15, 0, rx, cr6, cr2, {0}
1120  {
1121  fw->maxram = (1 << (((fw->buf[k-1] & 0x3E) >> 1) + 1)) - 1;
1122  break;
1123  }
1124  }
1125  }
1126 
1127  // Find MEMISOSTART
1128  fw->memisostart = 0;
1129  if (os_type == OS_DRYOS)
1130  {
1131  for (k=0 + fw->main_offs; k<(100 + fw->main_offs); k++)
1132  {
1133  if (isLDR_PC(fw,k) && (LDR2val(fw,k) == 0x1900) && isLDR_PC(fw,k+6))
1134  {
1135  fw->memisostart = LDR2val(fw,k+6);
1136  }
1137  }
1138  }
1139  else if (os_type == OS_VXWORKS)
1140  {
1141  for (k=16; k<100; k++)
1142  {
1143  if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k+11))
1144  {
1145  fw->memisostart = LDR2val(fw,k+11);
1146  // Find DATA section info
1147  if (isLDR_PC(fw,k-1) && isLDR_PC(fw,k-4) && ((fwval(fw,k-2) & 0xFFF0FFF0) == 0xE1500000))
1148  {
1149  uint32_t fadr = LDR2val(fw,k-1);
1150  uint32_t dadr = 0x1900;
1151  uint32_t eadr = LDR2val(fw,k-4);
1152  if ((fadr > fw->base) && (dadr < fw->base))
1153  {
1154  fw->data_start = dadr;
1155  fw->data_init_start = fadr;
1156  fw->data_len = eadr / 4;
1157  }
1158  }
1159  break;
1160  }
1161  else if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k-2) && isLDR_PC(fw,k-3))
1162  {
1163  // special case ixus30/40
1164  fw->maxram = 0x1FFFFFF; // 32MB, difficult to find
1165  fw->memisostart = 0x1900 + LDR2val(fw,k-3);
1166  // Find DATA section info
1167  fw->data_init_start = LDR2val(fw,k-2);
1168  fw->data_start = 0x1900;
1169  j = idxFollowBranch(fw, k+6, 1);
1170  if (j != k+6)
1171  {
1172  k = idxFollowBranch(fw, j+1, 0x01000001);
1173  if (k != j+1)
1174  {
1175  if ( isLDR_PC(fw,k+3) )
1176  {
1177  uint32_t eadr = LDR2val(fw,k+3);
1178  if ( (eadr>0x1000) && (eadr< fw->memisostart - 0x1900) )
1179  {
1180  fw->data_len = (eadr - 0x1900) / 4;
1181  }
1182  }
1183  }
1184  }
1185  break;
1186  }
1187  else if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k-2) &&
1188  ((fwval(fw,k-1) & 0xFFFF0F00) == 0xE50B0000) && isLDR_PC(fw,k+28) && isLDR_PC(fw,k+4)
1189  )
1190  {
1191  // special case ixusW
1192  fw->memisostart = LDR2val(fw,k+28);
1193  // Find DATA section info
1194  fw->data_init_start = LDR2val(fw,k-2);
1195  fw->data_start = 0x1900;
1196  fw->data_len = (LDR2val(fw,k+4) - 0x1900) / 4;
1197  break;
1198  }
1199  }
1200  }
1201 
1202  // Find encryption key & dancing bits
1203  fw->ksys_idx = 0;
1204  fw->ksys = 0;
1205  fw->dancing_bits_idx = 0;
1206  fw->dancing_bits = 0;
1207  if (os_type == OS_DRYOS)
1208  {
1209  uint32_t ofst = (fw->main_offs)?0:adr2idx(fw,0xFFFF0000); // Offset of area to find dancing bits
1210  if (idx_valid(fw,ofst) && isB(fw,ofst) && isLDR_PC(fw,ofst+1))
1211  {
1212  // Get KEYSYS value
1213  ofst = adr2idx(fw,LDR2val(fw,ofst+1)); // Address of firmware encryption key
1214  if (idx_valid(fw,ofst))
1215  {
1216  fw->ksys_idx = ofst;
1217  fw->ksys = "? Not found, possible new firmware encryption key.";
1218  switch (fwval(fw,ofst))
1219  {
1220  // Note: only check first word of key (assumes Canon won't release a new key with the same initial value as an existing one)
1221  // (Avoid storing full encryption key in this source code).
1222  case 0x70726964: fw->ksys = "d3"; break;
1223  case 0x646C726F: fw->ksys = "d3enc"; break;
1224  case 0x774D450B: fw->ksys = "d4"; break;
1225  case 0x80751A95: fw->ksys = "d4a"; break;
1226  case 0x76894368: fw->ksys = "d4b"; break;
1227  case 0x50838EF7: fw->ksys = "d4c"; break;
1228  case 0xCCE4D2E6: fw->ksys = "d4d"; break;
1229  case 0x66E0C6D2: fw->ksys = "d4e"; break;
1230  case 0xE1268DB4: fw->ksys = "d4f"; break;
1231  case 0x216EA8C8: fw->ksys = "d4g"; break;
1232  case 0x45264974: fw->ksys = "d4h"; break;
1233  case 0x666363FC: fw->ksys = "d4i"; break;
1234  case 0xAE8DB5AF: fw->ksys = "d4j"; break;
1235  }
1236  }
1237 
1238  // Get NEED_ENCODED_DISKBOOT value
1239  ofst = ofst + 4; // Address of dancing bits data (try after firmware key)
1240  if (idx_valid(fw,ofst))
1241  {
1242  for (i=0; i<VITALY && !fw->dancing_bits; i++)
1243  {
1244  fw->dancing_bits = i+1;
1245  for (j=0; j<8 && fw->dancing_bits; j++)
1246  {
1247  if ((fwval(fw,ofst+j) & 0xFF) != _chr_[i][j])
1248  {
1249  fw->dancing_bits = 0;
1250  }
1251  }
1252  }
1253  if (!fw->dancing_bits)
1254  {
1255  // Try before firmware key
1256  ofst = ofst - 12;
1257  for (i=0; i<VITALY && !fw->dancing_bits; i++)
1258  {
1259  fw->dancing_bits = i+1;
1260  for (j=0; j<8 && fw->dancing_bits; j++)
1261  {
1262  if ((fwval(fw,ofst+j) & 0xFF) != _chr_[i][j])
1263  {
1264  fw->dancing_bits = 0;
1265  }
1266  }
1267  }
1268  }
1269  if (fw->dancing_bits != 0)
1270  {
1271  // Make sure LoadBootFile actually fails on files that are not encoded
1272  // E.G. G9 - will load and run an un-encoded DISKBOOT.BIN file
1273  int need_dance = 1;
1274  for (k = ofst; (k>adr2idx(fw,0xFFFF0000)) && need_dance; k--)
1275  {
1276  if (isLDR_PC(fw,k) && (LDR2val(fw,k) == idx2adr(fw,ofst)))
1277  {
1278  j = find_inst_rev(fw,isSTMFD_LR,k-1,10);
1279  if (j >= 0)
1280  {
1281  uint32_t fadr = idx2adr(fw,j);
1282  for (i=j-200; i<j+200 && need_dance; i++)
1283  {
1284  if (isB(fw,i))
1285  {
1286  uint32_t badr = followBranch(fw,idx2adr(fw,i),1);
1287  if (badr == fadr)
1288  {
1289  int l;
1290  for (l=i-1; l>i-50; l--)
1291  {
1292  if (isLDR(fw,l) && isCMP(fw,l+1) && isBX_cond(fw,l+2))
1293  {
1294  need_dance = 0;
1295  break;
1296  }
1297  }
1298  }
1299  }
1300  }
1301  }
1302  }
1303  }
1304  if (need_dance)
1305  fw->dancing_bits_idx = ofst;
1306  else
1307  fw->dancing_bits = 0;
1308  }
1309  }
1310  }
1311  }
1312 
1313  int dx = 3;
1314 
1315  fw->lowest_idx = 0;
1316 
1317  // DryOS R50/R51/R52 etc. copies a block of ROM to RAM and then uses that copy
1318  // Need to allow for this in finding addresses
1319  // Seen on SX260HS
1320  if (fw->dryos_ver >= 50)
1321  {
1322 
1323  // Try and find ROM address copied, and location copied to
1324  for (i=3 + fw->main_offs; i<(100 + fw->main_offs); i++)
1325  {
1326  if (isLDR_PC(fw,i) && isLDR_PC(fw,i+1) && (isLDR_PC(fw,i+2)))
1327  {
1328  uint32_t fadr = LDR2val(fw,i);
1329  uint32_t dadr = LDR2val(fw,i+1);
1330  uint32_t eadr = LDR2val(fw,i+2);
1331  if ((fadr > fw->base) && (dadr < fw->base))
1332  {
1333  fw->buf2 = &fw->buf[adr2idx(fw,fadr)];
1334  fw->base2 = dadr;
1335  fw->base_copied = fadr;
1336  fw->size2 = (eadr - dadr) / 4;
1337  fw->lowest_idx = adr2idx(fw,fw->base2);
1338  dx = i+3;
1339  break;
1340  }
1341  }
1342  }
1343  }
1344 
1345  // Find DATA section info
1346  if (os_type == OS_DRYOS)
1347  {
1348  for (i=dx; i<(100 + fw->main_offs); i++)
1349  {
1350  if (isLDR_PC(fw,i) && isLDR_PC(fw,i+1) && (isLDR_PC(fw,i+2)))
1351  {
1352  uint32_t fadr = LDR2val(fw,i);
1353  uint32_t dadr = LDR2val(fw,i+1);
1354  uint32_t eadr = LDR2val(fw,i+2);
1355  if ((fadr > fw->base) && (dadr < fw->base))
1356  {
1357  fw->data_start = dadr;
1358  fw->data_init_start = fadr;
1359  fw->data_len = (eadr - dadr) / 4;
1360  break;
1361  }
1362  }
1363  }
1364  }
1365 }
int search_fw ( firmware fw,
int(*)(firmware *, int, uint32_t, uint32_t func,
uint32_t  v1,
uint32_t  v2,
int  len 
)

Definiert in Zeile 881 der Datei firmware_load.c.

882 {
883  BufRange *p = fw->br;
884  while (p)
885  {
886  int k;
887  for (k = p->off; k <= p->off + p->len - len; k++)
888  {
889  int rv = func(fw,k,v1,v2);
890  if (rv != 0)
891  return rv;
892  }
893  p = p->next;
894  }
895  return 0;
896 }
int search_fw_bytes ( firmware fw,
int(*)(firmware *, int)  func 
)

Definiert in Zeile 903 der Datei firmware_load.c.

904 {
905  BufRange *p = fw->br;
906  while (p)
907  {
908  int k;
909  for (k = p->off*4; k < (p->off + p->len)*4; k++)
910  {
911  if (func(fw,k))
912  return 1;
913  }
914  p = p->next;
915  }
916  return 0;
917 }
void set_ignore_errors ( int  n)

Definiert in Zeile 212 der Datei firmware_load.c.

213 {
214  ignore_errors = n;
215 }