📄 firmware_flash.c
字号:
i++; } } while (read == SEC_SIZE); rb->close(fd); return failures;}/***************** Support Functions *****************//* check if we have "normal" boot ROM or flash mirrored to zero */tCheckROM CheckBootROM(void){ unsigned boot_crc; unsigned* pFlash = (unsigned*)FB; unsigned* pRom = (unsigned*)0x0; unsigned i; boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF); if (boot_crc == 0x56DBA4EE) /* the known boot ROM */ return eBootROM; /* check if ROM is a flash mirror */ for (i=0; i<256*1024/sizeof(unsigned); i++) { if (*pRom++ != *pFlash++) { /* difference means no mirror */ return eUnknown; } } return eROMless;}/***************** User Interface Functions *****************/int WaitForButton(void){ int button; do { button = rb->button_get(true); } while (button & BUTTON_REL); return button;}#ifdef HAVE_LCD_BITMAP/* Recorder implementation *//* helper for DoUserDialog() */void ShowFlashInfo(tFlashInfo* pInfo){ char buf[32]; if (!pInfo->manufacturer) { rb->lcd_puts(0, 0, "Flash: M=?? D=??"); rb->lcd_puts(0, 1, "Impossible to program"); } else { rb->snprintf(buf, sizeof(buf), "Flash: M=%02x D=%02x", pInfo->manufacturer, pInfo->id); rb->lcd_puts(0, 0, buf); if (pInfo->size) { rb->lcd_puts(0, 1, pInfo->name); rb->snprintf(buf, sizeof(buf), "Size: %d KB", pInfo->size / 1024); rb->lcd_puts(0, 2, buf); } else { rb->lcd_puts(0, 1, "Unsupported chip"); } } rb->lcd_update();}/* Kind of our main function, defines the application flow. */void DoUserDialog(char* filename){ tFlashInfo FlashInfo; char buf[32]; char default_filename[32]; int button; int rc; /* generic return code */ int memleft; tCheckROM result; bool is_romless; rb->lcd_setfont(FONT_SYSFIXED); /* test if the user is running the correct plugin for this box */ if (!CheckPlatform(PLATFORM_ID, *(UINT16*)(FB + VERSION_ADR))) { rb->splash(HZ*3, true, "Wrong plugin"); return; /* exit */ } /* check boot ROM */ result = CheckBootROM(); if (result == eUnknown) { /* no support for any other yet */ rb->splash(HZ*3, true, "Wrong boot ROM"); return; /* exit */ } is_romless = (result == eROMless); /* compose filename if none given */ if (filename == NULL) { rb->snprintf( default_filename, sizeof(default_filename), "/firmware_%s%s.bin", FILE_TYPE, is_romless ? "_norom" : ""); filename = default_filename; } /* "allocate" memory */ sector = rb->plugin_get_buffer(&memleft); if (memleft < SEC_SIZE) /* need buffer for a flash sector */ { rb->splash(HZ*3, true, "Out of memory"); return; /* exit */ } rc = GetFlashInfo(&FlashInfo); ShowFlashInfo(&FlashInfo); if (FlashInfo.size == 0) /* no valid chip */ { rb->splash(HZ*3, true, "Sorry!"); return; /* exit */ } rb->lcd_puts(0, 3, "using file:"); rb->lcd_puts_scroll(0, 4, filename); rb->lcd_puts(0, 6, "[F1] to check file"); rb->lcd_puts(0, 7, "other key to exit"); rb->lcd_update(); button = WaitForButton(); if (button != BUTTON_F1) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "checking..."); rb->lcd_update(); rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); rb->lcd_puts(0, 0, "checked:"); switch (rc) { case eOK: rb->lcd_puts(0, 1, "File OK."); break; case eFileNotFound: rb->lcd_puts(0, 1, "File not found."); rb->lcd_puts(0, 2, "Put this in root:"); rb->lcd_puts_scroll(0, 4, filename); break; case eTooBig: rb->lcd_puts(0, 1, "File too big,"); rb->lcd_puts(0, 2, "larger than chip."); break; case eTooSmall: rb->lcd_puts(0, 1, "File too small."); rb->lcd_puts(0, 2, "Incomplete?"); break; case eReadErr: rb->lcd_puts(0, 1, "Read error."); break; case eBadContent: rb->lcd_puts(0, 1, "File invalid."); rb->lcd_puts(0, 2, "Sanity check fail."); break; case eCrcErr: rb->lcd_puts(0, 1, "File invalid."); rb->lcd_puts(0, 2, "CRC check failed,"); rb->lcd_puts(0, 3, "checksum mismatch."); break; case eBadPlatform: rb->lcd_puts(0, 1, "Wrong file for"); rb->lcd_puts(0, 2, "this hardware."); break; default: rb->lcd_puts(0, 1, "Check failed."); break; } if (rc == eOK) { rb->lcd_puts(0, 6, "[F2] to program"); rb->lcd_puts(0, 7, "other key to exit"); } else { /* error occured */ rb->lcd_puts(0, 6, "Any key to exit"); } rb->lcd_update(); button = WaitForButton(); if (button != BUTTON_F2 || rc != eOK) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Program all Flash?"); rb->lcd_puts(0, 1, "Are you shure?"); rb->lcd_puts(0, 2, "If it goes wrong,"); rb->lcd_puts(0, 3, "it kills your box!"); rb->lcd_puts(0, 4, "See documentation."); rb->lcd_puts(0, 6, "[F3] to proceed"); rb->lcd_puts(0, 7, "other key to exit"); rb->lcd_update(); button = WaitForButton(); if (button != BUTTON_F3) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Programming..."); rb->lcd_update(); rc = ProgramFirmwareFile(filename, FlashInfo.size); if (rc) { /* errors */ rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Panic:"); rb->lcd_puts(0, 1, "Programming fail!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts(0, 2, buf); rb->lcd_update(); button = WaitForButton(); } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Verifying..."); rb->lcd_update(); rc = VerifyFirmwareFile(filename); rb->lcd_clear_display(); if (rc == 0) { rb->lcd_puts(0, 0, "Verify OK."); } else { rb->lcd_puts(0, 0, "Panic:"); rb->lcd_puts(0, 1, "Verify fail!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts(0, 2, buf); } rb->lcd_puts(0, 7, "Any key to exit"); rb->lcd_update(); button = WaitForButton();}#else /* HAVE_LCD_BITMAP *//* Player implementation *//* helper for DoUserDialog() */void ShowFlashInfo(tFlashInfo* pInfo){ char buf[32]; if (!pInfo->manufacturer) { rb->lcd_puts_scroll(0, 0, "Flash: M=? D=?"); rb->lcd_puts_scroll(0, 1, "Impossible to program"); WaitForButton(); } else { rb->snprintf(buf, sizeof(buf), "Flash: M=%02x D=%02x", pInfo->manufacturer, pInfo->id); rb->lcd_puts_scroll(0, 0, buf); if (pInfo->size) { rb->snprintf(buf, sizeof(buf), "Size: %d KB", pInfo->size / 1024); rb->lcd_puts_scroll(0, 1, buf); } else { rb->lcd_puts_scroll(0, 1, "Unsupported chip"); WaitForButton(); } }}void DoUserDialog(char* filename){ tFlashInfo FlashInfo; char buf[32]; char default_filename[32]; int button; int rc; /* generic return code */ int memleft; tCheckROM result; bool is_romless; /* test if the user is running the correct plugin for this box */ if (!CheckPlatform(PLATFORM_ID, *(UINT16*)(FB + VERSION_ADR))) { rb->splash(HZ*3, true, "Wrong version"); return; /* exit */ } /* check boot ROM */ result = CheckBootROM(); if (result == eUnknown) { /* no support for any other yet */ rb->splash(HZ*3, true, "Wrong boot ROM"); return; /* exit */ } is_romless = (result == eROMless); /* compose filename if none given */ if (filename == NULL) { rb->snprintf( default_filename, sizeof(default_filename), "/firmware_%s%s.bin", FILE_TYPE, is_romless ? "_norom" : ""); filename = default_filename; } /* "allocate" memory */ sector = rb->plugin_get_buffer(&memleft); if (memleft < SEC_SIZE) /* need buffer for a flash sector */ { rb->splash(HZ*3, true, "Out of memory"); return; /* exit */ } rc = GetFlashInfo(&FlashInfo); ShowFlashInfo(&FlashInfo); if (FlashInfo.size == 0) /* no valid chip */ { return; /* exit */ } rb->lcd_puts_scroll(0, 0, filename); rb->lcd_puts_scroll(0, 1, "[Menu] to check"); button = WaitForButton(); if (button != BUTTON_MENU) { return; } rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Checking..."); rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); rb->lcd_puts(0, 0, "Checked:"); switch (rc) { case eOK: rb->lcd_puts(0, 1, "File OK."); break; case eFileNotFound: rb->lcd_puts_scroll(0, 0, "File not found:"); rb->lcd_puts_scroll(0, 1, filename); break; case eTooBig: rb->lcd_puts_scroll(0, 0, "File too big,"); rb->lcd_puts_scroll(0, 1, "larger than chip."); break; case eTooSmall: rb->lcd_puts_scroll(0, 0, "File too small."); rb->lcd_puts_scroll(0, 1, "Incomplete?"); break; case eReadErr: rb->lcd_puts_scroll(0, 0, "Read error."); break; case eBadContent: rb->lcd_puts_scroll(0, 0, "File invalid."); rb->lcd_puts_scroll(0, 1, "Sanity check failed."); break; case eCrcErr: rb->lcd_puts_scroll(0, 0, "File invalid."); rb->lcd_puts_scroll(0, 1, "CRC check failed."); break; case eBadPlatform: rb->lcd_puts_scroll(0, 0, "Wrong file for"); rb->lcd_puts_scroll(0, 1, "this hardware."); break; default: rb->lcd_puts_scroll(0, 0, "Check failed."); break; } rb->sleep(HZ*3); if (rc == eOK) { rb->lcd_puts_scroll(0, 0, "[On] to program,"); rb->lcd_puts_scroll(0, 1, "other key to exit."); } else { /* error occured */ return; } button = WaitForButton(); if (button != BUTTON_ON) { return; } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Are you sure?"); rb->lcd_puts_scroll(0, 1, "[+] to proceed."); button = WaitForButton(); if (button != BUTTON_RIGHT) { return; } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Programming..."); rc = ProgramFirmwareFile(filename, FlashInfo.size); if (rc) { /* errors */ rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Programming failed!"); rb->snprintf(buf, sizeof(buf), "%d errors", rc); rb->lcd_puts_scroll(0, 1, buf); WaitForButton(); } rb->lcd_clear_display(); rb->lcd_puts_scroll(0, 0, "Verifying..."); rc = VerifyFirmwareFile(filename); rb->lcd_clear_display(); if (rc == 0) { rb->lcd_puts_scroll(0, 0, "Verify OK."); } else { rb->snprintf(buf, sizeof(buf), "Verify failed! %d errors", rc); rb->lcd_puts_scroll(0, 0, buf); } rb->lcd_puts_scroll(0, 1, "Press any key to exit."); WaitForButton();}#endif /* not HAVE_LCD_BITMAP *//***************** Plugin Entry Point *****************/enum plugin_status plugin_start(struct plugin_api* api, void* parameter){ /* this macro should be called as the first thing you do in the plugin. it test that the api version and model the plugin was compiled for matches the machine it is running on */ TEST_PLUGIN_API(api); rb = api; /* copy to global api pointer */ /* now go ahead and have fun! */ DoUserDialog((char*) parameter); return PLUGIN_OK;}#endif /* ifdef PLATFORM_ID */#endif /* #ifndef SIMULATOR */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -