📄 btcflash.cpp
字号:
/* * Firmware flash utility for BTC DRW1008 DVD+/-RW recorder * Version 2004/04/29 * By David Huang <khym@azeotrope.org> * This work is dedicated to the public domain * * This utility may also work with other BTC DVD recorders, such as * the DRW1004 and DRW1108, but they have not been tested. * * USE AT YOUR OWN RISK! * btcflash is provided AS IS, with NO WARRANTY, either expressed or implied. * * Requires "transport.hxx" from Andy Polyakov's DVD+RW tools: * http://fy.chalmers.se/~appro/linux/DVD+RW/tools/ * If obtained as part of dvd+rw-tools it can be built with * 'make +btcflash'. * * Firmware files may be obtained by running BTC's Windows flash * utility, then searching in the WINDOWS\TEMP or WINNT\TEMP directory * for a *.HEX file. It will probably be in a subdirectory named * PAC*.tmp.DIR, and the HEX file will be named Vnnnn.HEX, where nnnn * is the firmware version number. You'll also find IDEFLASH.EXE or * BTCFLASH.EXE in the same directory. * * This utility will also accept firmware files in ".BIN" format. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "transport.hxx"const unsigned int FLASHSIZE = 0x100000; /* BTC flash is 1MB */unsigned char *loadfirmware(const char *);int getbyte(char *&);unsigned short calcsum(unsigned char *);unsigned char *loadfirmware(const char *firmware){ FILE *f; char line[80], *p; unsigned char *fwbuf; int bank, length, offset, type, hexsum; int i, b; fwbuf = new unsigned char[FLASHSIZE]; if (!fwbuf) { fprintf(stderr, "Could not allocate memory for firmware\n"); return NULL; } f = fopen(firmware, "r"); if (!f) { fprintf(stderr, "%s: Unable to open: ", firmware); perror(NULL); return NULL; } // Get length of file. If it's exactly FLASHSIZE, assume it's a // .bin file. Otherwise, try to read it as a .hex file. fseek(f, 0, SEEK_END); if (ftell(f) == FLASHSIZE) { rewind(f); if (fread(fwbuf, 1, FLASHSIZE, f) != FLASHSIZE) { fprintf(stderr, "%s: Short read\n", firmware); return NULL; } fclose(f); return fwbuf; } rewind(f); memset(fwbuf, 0xff, FLASHSIZE); bank = 0; while (fgets(line, sizeof(line), f)) { if (line[0] != ':') continue; p = line + 1; length = getbyte(p); offset = getbyte(p) << 8 | getbyte(p); type = getbyte(p); if (length < 0 || offset < 0 || type < 0 || (type != 0 && length != 0)) { fprintf(stderr, "Malformed line: %s", line); return NULL; } else if (length == 0) { if (strncmp(line, ":00000155AA", 11) == 0) { if (++bank >= 16) { fprintf(stderr, "Firmware file larger than 1MB\n"); return NULL; } continue; } else if (strncmp(line, ":00000001FF", 11) == 0) break; else { fprintf(stderr, "Malformed line: %s", line); return NULL; } } hexsum = (length + (offset >> 8) + (offset & 0xff)) & 0xff; for (i = 0; i < length; i++, offset++) { b = getbyte(p); hexsum = (hexsum + b) & 0xff; if (b < 0) { fprintf(stderr, "Short line: %s", line); return NULL; } fwbuf[(bank << 16) | offset] = (char)b; } hexsum = (0x100 - hexsum) & 0xff; if (hexsum != getbyte(p)) { fprintf(stderr, "Checksum mismatch: %s", line); return NULL; } } fclose(f); if (bank != 15) { fprintf(stderr, "Firmware file too small\n"); return NULL; } return fwbuf;}intgetbyte(char *&p){ int h, l; h = *p; if (h >= '0' && h <= '9') h -= '0'; else if (h >= 'A' && h <= 'F') h -= 'A' - 10; else if (h >= 'a' && h <= 'f') h -= 'a' - 10; else return -1; l = *(p+1); if (l >= '0' && l <= '9') l -= '0'; else if (l >= 'A' && l <= 'F') l -= 'A' - 10; else if (l >= 'a' && l <= 'f') l -= 'a' - 10; else return -1; p += 2; return (h << 4) | l;}unsigned shortcalcsum(unsigned char *fwbuf){ unsigned int flashsum, i; for(flashsum = 0, i = 0; i < FLASHSIZE; i++) flashsum += fwbuf[i]; return (flashsum & 0xffff);}int main(int argc, char *argv[]){ const char *fwfile; char confirm[5]; unsigned char *fwbuf, inq[128], csbuf[32]; unsigned short checksum; Scsi_Command cmd; int err; unsigned int offset; if (argc < 3) { fprintf(stderr, "Usage: %s /dev/cdrom firmware\n", argv[0]); return 1; } printf("BTC DVD+/-RW firmware flash utility 2004/04/29\n"); printf("USE AT YOUR OWN RISK!\n\n"); if (!cmd.associate(argv[1])) { fprintf(stderr, "%s: unable to open: ", argv[1]); perror (NULL); return 1; } fwfile = argv[2]; if (!(fwbuf = loadfirmware(fwfile))) return 1; checksum = calcsum(fwbuf); printf("Loaded firmware from %s\nFirmware checksum is %04X\n", fwfile, checksum); cmd[0] = 0x12; // INQUIRY cmd[4] = 36; cmd[5] = 0; if (err = cmd.transport(READ, inq, 36)) { sperror("INQUIRY", err); return 1; } printf("Drive is currently: [%.8s][%.16s][%.4s]\n", inq+8, inq+16, inq+32); printf("Firmware appears to be: [%.8s][%.16s][%.4s]\n\n", fwbuf+0x40bc, fwbuf+0x40c4, fwbuf+0x40d4); if (strncmp((char*)inq + 8, (char*)fwbuf + 0x40bc, 24) != 0) printf( "***********************************************" "***********\n" "WARNING! THIS FIRMWARE DOES NOT SEEM TO BE FOR " "THIS DRIVE!\n" "***********************************************" "***********\n"); printf("Type \"YES\" to proceed with flash: "); fflush(stdout); fgets(confirm, sizeof(confirm), stdin); if (strcmp(confirm, "YES\n") != 0) { printf("\nFlash canceled.\n"); return 0; } printf("\nUploading firmware...\n"); // Upload firmware for (offset = 0; offset < FLASHSIZE; offset += 0x1000) { cmd[0] = 0x3B; // WRITE BUFFER cmd[1] = 6; // Download Microcode with Offsets cmd[2] = 0; // Buffer ID 0 cmd[3] = (offset >> 16) & 0xff; cmd[4] = (offset >> 8) & 0xff; cmd[5] = 0x20; cmd[6] = 0; // Length 0x1000 cmd[7] = 0x10; cmd[8] = 0; cmd[9] = 0; if (err = cmd.transport(WRITE, fwbuf + offset, 0x1000)) { sperror("WRITE BUFFER[1]", err); return 1; } } // Upload checksum memset(csbuf, 0, 32); csbuf[30] = (checksum >> 8); csbuf[31] = (checksum & 0xff); cmd[0] = 0x3B; // WRITE BUFFER cmd[1] = 6; // Download Microcode with Offsets cmd[2] = 0; // Buffer ID 0 cmd[3] = 0; // Offset 0 cmd[4] = 0; cmd[5] = 0; cmd[6] = 0; // Length 0x20 cmd[7] = 0; cmd[8] = 0x20; cmd[9] = 0; if (err = cmd.transport(WRITE, csbuf, 0x20)) { sperror("WRITE BUFFER[2]", err); return 1; } printf("Flashing drive...\n"); // Firmware uploaded; now flash it! cmd[0] = 0x3B; // WRITE BUFFER cmd[1] = 7; // Download Microcode with Offsets and Save cmd[2] = 0; // Buffer ID 0 cmd[3] = 0; // Offset 0 cmd[4] = 0; cmd[5] = 0; cmd[6] = 0; // Length 0 cmd[7] = 0; cmd[8] = 0; cmd[9] = 0; if (err = cmd.transport()) { sperror("WRITE BUFFER[3]", err); return 1; } sleep(50); // Let drive sit for a while before bothering it while (1) { sleep(1); cmd[0] = 0; // TEST UNIT READY cmd[5] = 0; err = cmd.transport(); // Wait until it returns either ready or // not ready/medium not present if ((err == 0) || (SK(err) == 2 && ASC(err) == 0x3A)) break; } cmd[0] = 0x12; // INQUIRY cmd[4] = 36; cmd[5] = 0; if (err = cmd.transport(READ, inq, 36)) { sperror("INQUIRY[2]", err); return 1; } printf("Drive is now: [%.8s][%.16s][%.4s]\n\n", inq+8, inq+16, inq+32); printf("Please reboot before using the drive.\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -