// Scan the EEPROM config. Returns true if the config is valid. bool isEEPROMContentValid(void) { uint8_t chk = 0; const uint8_t *p = &__config_start; const configHeader_t *header = (const configHeader_t *)p; if (header->eepromConfigVersion != EEPROM_CONF_VERSION) { return false; } if (strncasecmp(header->boardIdentifier, TARGET_BOARD_IDENTIFIER, sizeof(TARGET_BOARD_IDENTIFIER))) { return false; } chk = updateChecksum(chk, header, sizeof(*header)); p += sizeof(*header); // include the transitional masterConfig record chk = updateChecksum(chk, p, sizeof(masterConfig)); p += sizeof(masterConfig); for (;;) { const configRecord_t *record = (const configRecord_t *)p; if (record->size == 0) { // Found the end. Stop scanning. break; } if (p + record->size >= &__config_end || record->size < sizeof(*record)) { // Too big or too small. return false; } chk = updateChecksum(chk, p, record->size); p += record->size; } const configFooter_t *footer = (const configFooter_t *)p; chk = updateChecksum(chk, footer, sizeof(*footer)); p += sizeof(*footer); chk = ~chk; const uint8_t checkSum = *p; p += sizeof(checkSum); eepromConfigSize = p - &__config_start; return chk == checkSum; }
// #################################################### // SETTERS // #################################################### bool Message::add(uint8_t value){ #ifdef DEBUG_MSG T(std::cout, "Entering Message::add"); H(std::cout,int(value)); #endif // short circuit is guaranteed but just in case if(insert(value)) updateChecksum(value); return true; }
void EEPROM::storeMixingRatios(bool _updateChecksum) { for(uint8_t e = 0; e < NUM_EXTRUDER; e++) { for(uint8_t i = 0; i < VIRTUAL_EXTRUDER; i++) { HAL::eprSetInt16(EEPROM_EXTRUDER_OFFSET + e * EEPROM_EXTRUDER_LENGTH + EPR_EXTRUDER_MIXING_RATIOS + 2 * i, extruder[e].virtualWeights[i]); } } if(_updateChecksum) updateChecksum(); }
// Scan the EEPROM config. Optionally also load into memory. Returns // true if the config is valid. bool scanEEPROM(bool andLoad) // FIXME boolean argument. { uint8_t chk = 0; const uint8_t *p = &__config_start; const configHeader_t *header = (const configHeader_t *)p; if (header->format != EEPROM_CONF_VERSION) { return false; } chk = updateChecksum(chk, header, sizeof(*header)); p += sizeof(*header); for (;;) { const configRecord_t *record = (const configRecord_t *)p; if (record->size == 0) { // Found the end. Stop scanning. break; } if (p + record->size >= &__config_end || record->size < sizeof(*record)) { // Too big or too small. return false; } chk = updateChecksum(chk, p, record->size); if (andLoad) { loadPG(record); } p += record->size; } const configFooter_t *footer = (const configFooter_t *)p; chk = updateChecksum(chk, footer, sizeof(*footer)); p += sizeof(*footer); chk = ~chk; return chk == *p; }
void EEPROM::updatePrinterUsage() { #if EEPROM_MODE != 0 if(Printer::filamentPrinted==0) return; // No miles only enabled uint32_t seconds = (HAL::timeInMilliseconds()-Printer::msecondsPrinting)/1000; seconds += HAL::eprGetInt32(EPR_PRINTING_TIME); HAL::eprSetInt32(EPR_PRINTING_TIME,seconds); HAL::eprSetFloat(EPR_PRINTING_DISTANCE,HAL::eprGetFloat(EPR_PRINTING_DISTANCE)+Printer::filamentPrinted*0.001); Printer::filamentPrinted = 0; Printer::msecondsPrinting = HAL::timeInMilliseconds(); updateChecksum(); Commands::reportPrinterUsage(); #endif }
int main(int argc, char *argv[]) { initSigning(); const char* argv0 = argv[0]; int ch; SigType type = SigAuto; bool remove = false; while ((ch = getopt(argc, argv, "?c:opsuv")) != -1) { switch (ch) { case 'c': if (!strcmp(optarg, "d")) type = SigDsa; else if (!strcmp(optarg, "r")) type = SigRsa; else fprintf(stderr, "Unknown algorithm\n"); break; case 'o': break; case 'p': break; case 's': break; case 'u': remove = true; break; case '?': default: showHelp(argv0); return 0; } } argc -= optind; argv += optind; char* input = NULL; char* output = NULL; char* cert = NULL; char* key = NULL; char* passphrase = NULL; if (argc > 5) argc = 5; switch (argc) { case 5: passphrase = argv[4]; case 4: key = argv[3]; case 3: cert = argv[2]; case 2: output = argv[1]; case 1: input = argv[0]; } if (input == NULL) { showHelp(argv0); return 0; } if (!output) output = input; uint8_t header[16]; SISContents* contents = loadSISFile(input, header); if (!contents) return 1; SISCompressed* cController = (SISCompressed*) contents->FindElement(SISFieldType::SISCompressed); TCompressionAlgorithm algorithm = cController->Algorithm(); cController->Uncompress(); cController->LoadChild(); SISField* field = cController->Field(); if (field->Id() != SISFieldType::SISController) { fprintf(stderr, "Bad SIS field type in the top level compressed field\n"); exit(1); } SISController* controller = (SISController*) field; if (remove) { SISField* field = controller->FindRemoveLastElement(SISFieldType::SISSignatureCertificateChain); delete field; } else { SISDataIndex* dataIndex = (SISDataIndex*) controller->FindRemoveElement(SISFieldType::SISDataIndex); const char* certData = NULL; const char* keyData = NULL; bool freeCerts = false; if (cert && key) { try { certData = loadTextFile(cert); keyData = loadTextFile(key); } catch (SignUtilError err) { return err; } freeCerts = true; } else { fprintf(stderr, "You must specify certificate and key.\n"); exit(1); } try { SISSignatureCertificateChain* chain = makeChain(controller, certData, keyData, passphrase, type); controller->AddElement(chain); } catch (SignUtilError err) { return err; } controller->AddElement(dataIndex); if (freeCerts) { delete [] certData; delete [] keyData; } } /* FILE* tout = fopen("testcontroller", "wb"); controller->CopyHeaderData(tout); fclose(tout); */ cController->LoadUncompressed(); cController->Compress(algorithm); SISControllerChecksum* csum = (SISControllerChecksum*) contents->FindElement(SISFieldType::SISControllerChecksum); updateChecksum(csum, cController); FILE* out = fopen(output, "wb"); fwrite(header, 1, 16, out); contents->CopyHeaderData(out); fclose(out); delete contents; cleanupSigning(); return 0; }
/* * Do the actual optimization. This is executed in the dexopt process. * * For best use of disk/memory, we want to extract once and perform * optimizations in place. If the file has to expand or contract * to match local structure padding/alignment expectations, we want * to do the rewrite as part of the extract, rather than extracting * into a temp file and slurping it back out. (The structure alignment * is currently correct for all platforms, and this isn't expected to * change, so we should be okay with having it already extracted.) * * Returns "true" on success. */ bool dvmContinueOptimization(int fd, off_t dexOffset, long dexLength, const char* fileName, u4 modWhen, u4 crc, bool isBootstrap) { DexClassLookup* pClassLookup = NULL; RegisterMapBuilder* pRegMapBuilder = NULL; u4 headerFlags = 0; assert(gDvm.optimizing); LOGV("Continuing optimization (%s, isb=%d)\n", fileName, isBootstrap); assert(dexOffset >= 0); /* quick test so we don't blow up on empty file */ if (dexLength < (int) sizeof(DexHeader)) { LOGE("too small to be DEX\n"); return false; } if (dexOffset < (int) sizeof(DexOptHeader)) { LOGE("not enough room for opt header\n"); return false; } bool result = false; /* * Drop this into a global so we don't have to pass it around. We could * also add a field to DexFile, but since it only pertains to DEX * creation that probably doesn't make sense. */ gDvm.optimizingBootstrapClass = isBootstrap; { /* * Map the entire file (so we don't have to worry about page * alignment). The expectation is that the output file contains * our DEX data plus room for a small header. */ bool success; void* mapAddr; mapAddr = mmap(NULL, dexOffset + dexLength, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (mapAddr == MAP_FAILED) { LOGE("unable to mmap DEX cache: %s\n", strerror(errno)); goto bail; } /* * Rewrite the file. Byte reordering, structure realigning, * class verification, and bytecode optimization are all performed * here. * * In theory the file could change size and bits could shift around. * In practice this would be annoying to deal with, so the file * layout is designed so that it can always be rewritten in place. * * This sets "headerFlags" and creates the class lookup table as * part of doing the processing. */ success = rewriteDex(((u1*) mapAddr) + dexOffset, dexLength, &headerFlags, &pClassLookup); if (success) { DvmDex* pDvmDex = NULL; u1* dexAddr = ((u1*) mapAddr) + dexOffset; if (dvmDexFileOpenPartial(dexAddr, dexLength, &pDvmDex) != 0) { LOGE("Unable to create DexFile\n"); success = false; } else { /* * If configured to do so, generate register map output * for all verified classes. The register maps were * generated during verification, and will now be serialized. */ if (gDvm.generateRegisterMaps) { pRegMapBuilder = dvmGenerateRegisterMaps(pDvmDex); if (pRegMapBuilder == NULL) { LOGE("Failed generating register maps\n"); success = false; } } DexHeader* pHeader = (DexHeader*)pDvmDex->pHeader; updateChecksum(dexAddr, dexLength, pHeader); dvmDexFileFree(pDvmDex); } } /* unmap the read-write version, forcing writes to disk */ if (msync(mapAddr, dexOffset + dexLength, MS_SYNC) != 0) { LOGW("msync failed: %s\n", strerror(errno)); // weird, but keep going } #if 1 /* * This causes clean shutdown to fail, because we have loaded classes * that point into it. For the optimizer this isn't a problem, * because it's more efficient for the process to simply exit. * Exclude this code when doing clean shutdown for valgrind. */ if (munmap(mapAddr, dexOffset + dexLength) != 0) { LOGE("munmap failed: %s\n", strerror(errno)); goto bail; } #endif if (!success) goto bail; } /* get start offset, and adjust deps start for 64-bit alignment */ off_t depsOffset, optOffset, endOffset, adjOffset; int depsLength, optLength; u4 optChecksum; depsOffset = lseek(fd, 0, SEEK_END); if (depsOffset < 0) { LOGE("lseek to EOF failed: %s\n", strerror(errno)); goto bail; } adjOffset = (depsOffset + 7) & ~(0x07); if (adjOffset != depsOffset) { LOGV("Adjusting deps start from %d to %d\n", (int) depsOffset, (int) adjOffset); depsOffset = adjOffset; lseek(fd, depsOffset, SEEK_SET); } /* * Append the dependency list. */ if (writeDependencies(fd, modWhen, crc) != 0) { LOGW("Failed writing dependencies\n"); goto bail; } /* compute deps length, then adjust opt start for 64-bit alignment */ optOffset = lseek(fd, 0, SEEK_END); depsLength = optOffset - depsOffset; adjOffset = (optOffset + 7) & ~(0x07); if (adjOffset != optOffset) { LOGV("Adjusting opt start from %d to %d\n", (int) optOffset, (int) adjOffset); optOffset = adjOffset; lseek(fd, optOffset, SEEK_SET); } /* * Append any optimized pre-computed data structures. */ if (!writeOptData(fd, pClassLookup, pRegMapBuilder)) { LOGW("Failed writing opt data\n"); goto bail; } endOffset = lseek(fd, 0, SEEK_END); optLength = endOffset - optOffset; /* compute checksum from start of deps to end of opt area */ if (!computeFileChecksum(fd, depsOffset, (optOffset+optLength) - depsOffset, &optChecksum)) { goto bail; } /* * Output the "opt" header with all values filled in and a correct * magic number. */ DexOptHeader optHdr; memset(&optHdr, 0xff, sizeof(optHdr)); memcpy(optHdr.magic, DEX_OPT_MAGIC, 4); memcpy(optHdr.magic+4, DEX_OPT_MAGIC_VERS, 4); optHdr.dexOffset = (u4) dexOffset; optHdr.dexLength = (u4) dexLength; optHdr.depsOffset = (u4) depsOffset; optHdr.depsLength = (u4) depsLength; optHdr.optOffset = (u4) optOffset; optHdr.optLength = (u4) optLength; optHdr.flags = headerFlags; optHdr.checksum = optChecksum; fsync(fd); /* ensure previous writes go before header is written */ lseek(fd, 0, SEEK_SET); if (sysWriteFully(fd, &optHdr, sizeof(optHdr), "DexOpt opt header") != 0) goto bail; LOGV("Successfully wrote DEX header\n"); result = true; //dvmRegisterMapDumpStats(); bail: dvmFreeRegisterMapBuilder(pRegMapBuilder); free(pClassLookup); return result; }
static bool writeSettingsToEEPROM(void) { config_streamer_t streamer; config_streamer_init(&streamer); config_streamer_start(&streamer, (uintptr_t)&__config_start, &__config_end - &__config_start); uint8_t chk = 0; configHeader_t header = { .eepromConfigVersion = EEPROM_CONF_VERSION, .boardIdentifier = TARGET_BOARD_IDENTIFIER, }; config_streamer_write(&streamer, (uint8_t *)&header, sizeof(header)); chk = updateChecksum(chk, (uint8_t *)&header, sizeof(header)); // write the transitional masterConfig record config_streamer_write(&streamer, (uint8_t *)&masterConfig, sizeof(masterConfig)); chk = updateChecksum(chk, (uint8_t *)&masterConfig, sizeof(masterConfig)); PG_FOREACH(reg) { const uint16_t regSize = pgSize(reg); configRecord_t record = { .size = sizeof(configRecord_t) + regSize, .pgn = pgN(reg), .version = pgVersion(reg), .flags = 0 }; if (pgIsSystem(reg)) { // write the only instance record.flags |= CR_CLASSICATION_SYSTEM; config_streamer_write(&streamer, (uint8_t *)&record, sizeof(record)); chk = updateChecksum(chk, (uint8_t *)&record, sizeof(record)); config_streamer_write(&streamer, reg->address, regSize); chk = updateChecksum(chk, reg->address, regSize); } else { // write one instance for each profile for (uint8_t profileIndex = 0; profileIndex < MAX_PROFILE_COUNT; profileIndex++) { record.flags = 0; record.flags |= ((profileIndex + 1) & CR_CLASSIFICATION_MASK); config_streamer_write(&streamer, (uint8_t *)&record, sizeof(record)); chk = updateChecksum(chk, (uint8_t *)&record, sizeof(record)); const uint8_t *address = reg->address + (regSize * profileIndex); config_streamer_write(&streamer, address, regSize); chk = updateChecksum(chk, address, regSize); } } } configFooter_t footer = { .terminator = 0, }; config_streamer_write(&streamer, (uint8_t *)&footer, sizeof(footer)); chk = updateChecksum(chk, (uint8_t *)&footer, sizeof(footer)); // append checksum now chk = ~chk; config_streamer_write(&streamer, &chk, sizeof(chk)); config_streamer_flush(&streamer); bool success = config_streamer_finish(&streamer) == 0; return success; } void writeConfigToEEPROM(void) { bool success = false; // write it for (int attempt = 0; attempt < 3 && !success; attempt++) { if (writeSettingsToEEPROM()) { success = true; } } if (success && isEEPROMContentValid()) { return; } // Flash write failed - just die now failureMode(FAILURE_FLASH_WRITE_FAILED); }
Directory::Directory() { memset(__raw, 0xFF, BlockSize); m_updateCounter = 0; updateChecksum(); }