root/modules/firmware_crc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. crc32_for_byte
  2. crc32
  3. dump_rom
  4. gui_fwc_done
  5. gui_fwc_dump_dialog
  6. crc_core
  7. gui_fwc_draw
  8. _run
  9. _module_can_unload
  10. _module_exit_alt

   1 #include "camera_info.h"
   2 #include "gui.h"
   3 #include "gui_draw.h"
   4 #include "meminfo.h"
   5 #include "module_load.h"
   6 #include "simple_module.h"
   7 #include "clock.h"
   8 #include "console.h"
   9 #include "conf.h"
  10 #include "lang.h"
  11 #include "firmware_crc_types.h"
  12 
  13 // =========  MODULE INIT =================
  14 
  15 static int running = 0;
  16 
  17 //-------------------------------------------------------------------
  18 // From public domain crc32 code
  19 //-------------------------------------------------------------------
  20 
  21 unsigned long crc32_for_byte(unsigned long r) {
  22     unsigned long j;
  23     for (j = 0; j < 8; j++) {
  24         r = (r & 1? 0: (unsigned long)0xEDB88320) ^ r >> 1;
  25     }
  26     return r ^ (unsigned long)0xFF000000;
  27 }
  28 
  29 void crc32(const void *data, unsigned long n_bytes, unsigned long* crc) {
  30     static unsigned long ct[0x100] = {0};
  31     unsigned long i;
  32     if (!ct[0]) {
  33         for (i = 0; i < 0x100; i++) {
  34             ct[i] = crc32_for_byte(i);
  35         }
  36     }
  37     for (i = 0; i < n_bytes; i++) {
  38         *crc = ct[(unsigned char)*crc ^ ((unsigned char*)data)[i]] ^ *crc >> 8;
  39     }
  40 }
  41 
  42 /*************** GUI MODULE *******************/
  43 
  44 #include "gui_lang.h"
  45 #include "gui_mbox.h"
  46 #include "gui_fselect.h"
  47 #include "keyboard.h"
  48 
  49 void gui_fwc_draw();
  50 
  51 gui_handler GUI_MODE_FWC = 
  52     /*GUI_MODE_FWC*/  { GUI_MODE_MODULE, gui_fwc_draw, 0 /* only keys are in dialogs */, 0 /* no special handling for menu */, 0, 0 };
  53 
  54 enum {
  55     FWC_STATE_INIT,
  56     FWC_STATE_STARTED,
  57     FWC_STATE_CHECK,
  58     FWC_STATE_FAIL,
  59     FWC_STATE_DIALOG,
  60     FWC_STATE_DUMP,
  61     FWC_STATE_DUMP_OK,
  62     FWC_STATE_DUMP_FAIL,
  63     FWC_STATE_DONE,
  64     FWC_STATE_QUIT,
  65     FWC_STATE_END,
  66 }; 
  67 
  68 int fwc_state = FWC_STATE_INIT;
  69 
  70 extern const firmware_crc_desc_t firmware_crc_desc;
  71 
  72 static char out[512];
  73 
  74 int dump_rom(void) {
  75     // match dumper script that normally skipts last word to avoid potential wraparound issues
  76     unsigned dump_size = 0xfffffffc - camera_info.rombaseaddr;
  77     // so far, no ROM bigger that 32MB
  78     if(dump_size > 0x1fffffc) {
  79         dump_size = 0x1fffffc;
  80     }
  81     FILE *fh = fopen("A/PRIMARY.BIN","wb");
  82     if(!fh) {
  83         return 0;
  84     }
  85     fwrite((char *)camera_info.rombaseaddr,dump_size,1,fh);
  86     fclose(fh);
  87     return 1;
  88 }
  89 
  90 static void gui_fwc_done(__attribute__ ((unused))unsigned unused)
  91 {
  92     fwc_state = FWC_STATE_DONE;
  93 }
  94 
  95 static void gui_fwc_dump_dialog(unsigned btn)
  96 {
  97     if (btn == MBOX_BTN_OK) {
  98         fwc_state = FWC_STATE_DUMP;
  99     } else {
 100         fwc_state = FWC_STATE_DONE;
 101     }
 102 }
 103 
 104 int crc_core(const firmware_crc_desc_t *desc)
 105 {
 106     running = 1;
 107 
 108     int failed = 0;
 109     char *s = out;
 110     unsigned i;
 111     for(i=0; i < desc->sub_count; i++) {
 112         if(!strcmp(desc->firmware_ver_ptr,desc->subs[i].canon_sub)) {
 113             gui_browser_progress_show("ROM CRC",0);
 114             s += sprintf(out,"%s\n%s %s\n%s\n",
 115                     lang_str(LANG_FIRMWARE_CRC_FAIL),
 116                     camera_info.platform, desc->subs[i].canon_sub,lang_str(LANG_FIRMWARE_CRC_FAILED_CHUNKS));
 117             unsigned b;
 118             const firmware_crc_block_t *blocks = desc->subs[i].blocks;
 119             for(b=0; b < desc->block_count; b++) {
 120                 gui_browser_progress_show("ROM CRC",100*(b+1)/desc->block_count);
 121                 // truncated dump could have zero sized blocks
 122                 if(blocks[b].size != 0) {
 123                     unsigned long fw_crc = 0;
 124                     crc32(blocks[b].start,blocks[b].size,&fw_crc);
 125                     if(fw_crc != blocks[b].crc) {
 126                         s += sprintf(s,"%8x ",blocks[b].start);
 127                         failed++;
 128                     }
 129                 }
 130             }
 131             sprintf(s,"\n%s",lang_str(LANG_FIRMWARE_CRC_DUMP_ROM));
 132             break;
 133         }
 134     }
 135     if(failed) {
 136         fwc_state = FWC_STATE_FAIL;
 137     } else {
 138         fwc_state = FWC_STATE_DONE;
 139     }
 140     return 0;
 141 }
 142 
 143 void gui_fwc_draw()
 144 {
 145     switch(fwc_state) {
 146         case FWC_STATE_STARTED:
 147             fwc_state = FWC_STATE_CHECK;
 148             crc_core(&firmware_crc_desc);
 149             break;
 150         case FWC_STATE_FAIL:
 151             fwc_state = FWC_STATE_DIALOG;
 152             gui_mbox_init(LANG_WARNING, (int)out, MBOX_BTN_OK|MBOX_BTN_CANCEL|MBOX_FUNC_RESTORE, gui_fwc_dump_dialog );
 153             break;
 154         case FWC_STATE_DUMP:
 155             gui_browser_progress_show("Write PRIMARY.BIN",10); // LIES!
 156             if(dump_rom()) {
 157                 fwc_state = FWC_STATE_DUMP_OK;
 158             } else {
 159                 fwc_state = FWC_STATE_DUMP_FAIL;
 160             }
 161             gui_browser_progress_show("Write PRIMARY.BIN",100);
 162             break;
 163         case FWC_STATE_DUMP_OK:
 164             fwc_state = FWC_STATE_DIALOG;
 165             gui_mbox_init(LANG_INFORMATION,(int)"Wrote PRIMARY.BIN", MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, gui_fwc_done);
 166             break;
 167         case FWC_STATE_DUMP_FAIL:
 168             fwc_state = FWC_STATE_DIALOG;
 169             gui_mbox_init(LANG_ERROR, (int)"Failed to write PRIMARY.BIN", MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, gui_fwc_done);
 170             break;
 171         case FWC_STATE_DONE:
 172             // if set to only on boot, clear
 173             if(conf.check_firmware_crc == 1) {
 174                 conf.check_firmware_crc = 0;
 175                 conf_save();
 176             }
 177             // force one spytask iteration delay
 178             fwc_state = FWC_STATE_QUIT;
 179             break;
 180         case FWC_STATE_QUIT:
 181             fwc_state = FWC_STATE_END;
 182             // exiting alt will clear gui mode, meaning draw will no longer be called, exit_alt handler will terminate module
 183             exit_alt();
 184     }
 185 }
 186 
 187 
 188 //-------------------------------------------------------------------
 189 
 190 /***************** BEGIN OF AUXILARY PART *********************
 191   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 192  **************************************************************/
 193 
 194 int _run()
 195 {
 196     // PROBLEM: we need to be in alt mode for keyboard handling and dialogs to work,
 197     // but entering alt changes gui and requires getting into the main spytask loop
 198     // solution: abuse the _module_can_unload handler, which is called periodically from the main loop
 199     running = 1;
 200     enter_alt(0);
 201     return 0;
 202 }
 203 
 204 int _module_can_unload()
 205 {
 206     if(fwc_state == FWC_STATE_INIT) {
 207         gui_set_mode(&GUI_MODE_FWC);
 208         fwc_state = FWC_STATE_STARTED;
 209     }
 210     return (running==0);
 211 }
 212 
 213 int _module_exit_alt()
 214 {
 215     running = 0;
 216     return 0;
 217 }
 218 
 219 /******************** Module Information structure ******************/
 220 
 221 libsimple_sym _libfirmwarecrc =
 222 {
 223     {
 224          0, 0, _module_can_unload, _module_exit_alt, _run
 225     },
 226 };
 227 
 228 ModuleInfo _module_info =
 229 {
 230     MODULEINFO_V1_MAGICNUM,
 231     sizeof(ModuleInfo),
 232     {2,0},      // Module version
 233 
 234     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,           // Requirements of CHDK version
 235     ANY_PLATFORM_ALLOWED,       // Specify platform dependency
 236 
 237     (int32_t)"Checksum ROM",
 238     MTYPE_TOOL,
 239 
 240     &_libfirmwarecrc.base,
 241 
 242     CONF_VERSION,               // CONF version
 243     CAM_SCREEN_VERSION,         // CAM SCREEN version
 244     ANY_VERSION,                // CAM SENSOR version
 245     ANY_VERSION,                // CAM INFO version
 246 
 247     0,
 248 };
 249 
 250 /*************** END OF AUXILARY PART *******************/
 251 

/* [<][>][^][v][top][bottom][index][help] */