int main (int argc, char **argv) { FILE *file; char buf[256]; int line = 0; srec_t srec; if (argc != 2) fatal("usage: %s filename\n", argv[0]); if (!(file = fopen(argv[1], "r"))) fatal("%s: couldn't open\n", argv[1]); while (fgets(buf, sizeof(buf), file)) { int error; line++; if ((error = srec_decode(&srec, buf)) < 0) { if (error != S_INVALID_CKSUM) { fatal("%s: %s on line %d\n", argv[1], srec_strerror(error), line); } } if (srec.type == 0) { srec.data[srec.count] = '\0'; printf("S0: %s\n", srec.data); } } }
static ulong load_serial(ulong offset) { char record[SREC_MAXRECLEN + 1]; /* buffer for one S-Record */ char binbuf[SREC_MAXBINLEN]; /* buffer for binary data */ int binlen; /* no. of data bytes in S-Rec. */ int type; /* return code for record type */ ulong addr; /* load address from S-Record */ ulong size; /* number of bytes transferred */ char buf[32]; ulong store_addr; ulong start_addr = ~0; ulong end_addr = 0; int line_count = 0; while (read_record(record, SREC_MAXRECLEN + 1) >= 0) { type = srec_decode(record, &binlen, &addr, binbuf); if (type < 0) { return ~0; /* Invalid S-Record */ } switch (type) { case SREC_DATA2: case SREC_DATA3: case SREC_DATA4: store_addr = addr + offset; memcpy((char *)(store_addr), binbuf, binlen); if ((store_addr) < start_addr) start_addr = store_addr; if ((store_addr + binlen - 1) > end_addr) end_addr = store_addr + binlen - 1; break; case SREC_END2: case SREC_END3: case SREC_END4: udelay(10000); size = end_addr - start_addr + 1; printf("\n" "## First Load Addr = 0x%08lX\n" "## Last Load Addr = 0x%08lX\n" "## Total Size = 0x%08lX = %ld Bytes\n", start_addr, end_addr, size, size ); sprintf(buf, "%lX", size); setenv("filesize", buf); return addr; case SREC_START: break; default: break; } if (!do_echo) { /* print a '.' every 100 lines */ if ((++line_count % 100) == 0) console_putc(CONSOLE_STDOUT, '.'); } } return ~0; /* Download aborted */ }
int srec_read (FILE *file, int start) { char buf[256]; srec_t srec; int line = 0; int entry = 0; /* Read image file */ while (fgets(buf, sizeof(buf), file)) { int error, i; line++; /* Skip blank lines */ for (i = 0; buf[i]; i++) if (!isspace(buf[i])) break; if (!buf[i]) continue; /* Decode line */ if ((error = srec_decode(&srec, buf)) < 0) { if (error != SREC_INVALID_CKSUM) { fprintf(stderr, "firmware: %s on line %d\n", srec_strerror(error), line); return -1; } } /* Process s-record data */ if (srec.type == 1) { memcpy(&memory[srec.addr], &srec.data, srec.count); } /* Process image starting address */ else if (srec.type == 9) { entry = srec.addr; } } return entry; }
/***************************************************************************** * void main(void) * * Main application. * * In: n/a * * Out: n/a *****************************************************************************/ void main(void) { UInt16 state; char *temp_ptr; extern word _vba; uint8_t sw0, sw1; INTC_VBA = ((word)&_vba) >> (21-INTC_VBA_BITS); /* Set Vector Base Address */ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ /*StartDelay = pmem_read((unsigned int *)BOOT_START_DELAY_PLACE) & 0x00FF; if(!StartDelay) bootExit(); else bootTimerInit();*/ /* Write your code here */ GPIO_A_PER &= ~GPIO_A_PER_PE0_MASK; // set to GPIO mode GPIO_A_PER &= ~GPIO_A_PER_PE1_MASK; GPIO_A_DDR |= GPIO_A_DDR_DD0_MASK; // set as output GPIO_A_DDR |= GPIO_A_DDR_DD1_MASK; GPIO_A_DR &= ~GPIO_A_DR_D0_MASK; // set low GPIO_A_DR &= ~GPIO_A_DR_D1_MASK; Cpu_Delay100US(5000); // power-up delay // Initialize R0,R1,M01, and N for circular buffer (including shadows) asm { swap shadows ;// Switch to shadow registers moveu.w #(RX_DATA_SIZE-1),M01 ;// Set buffer size moveu.w #rx_data,R0 ;// Set starting address moveu.w #QSCI_STAT,R1 ;// Use R1 for SCI status register moveu.w #0,N ;// N is unused swap shadows ;// Switch back to normal registers } // with DEFCON 17, we used a timer to keep the badge in bootloader mode on power up for 10 seconds // for DEFCON 18, the bootloader mode is only enabled if both buttons are held down on power up // otherwise it jumps directly to the user application. no timer necessary, so that code is commented out // check buttons GPIO_C_PUR |= GPIO_C_PUR_PU0_MASK; // enable pull-up GPIO_C_PUR |= GPIO_C_PUR_PU1_MASK; GPIO_C_DDR &= ~GPIO_C_DDR_DD0_MASK; // set as input GPIO_C_DDR &= ~GPIO_C_DDR_DD1_MASK; GPIO_C_PER &= ~GPIO_C_PER_PE0_MASK; // set to GPIO mode GPIO_C_PER &= ~GPIO_C_PER_PE1_MASK; Cpu_Delay100US(1000); // setup delay #define SW0_PIN_MASK ((byte)1) /* Pin mask */ #define SW1_PIN_MASK ((byte)2) /* Pin mask */ sw0 = !((bool)(getRegBits(GPIO_C_RAWDATA,SW0_PIN_MASK))); sw1 = !((bool)(getRegBits(GPIO_C_RAWDATA,SW1_PIN_MASK))); if (sw0 || sw1) // one or more buttons has been pressed { Cpu_Delay100US(1000); // give the user time to press both buttons (also serves as 100mS debounce) sw0 = !((bool)(getRegBits(GPIO_C_RAWDATA,SW0_PIN_MASK))); sw1 = !((bool)(getRegBits(GPIO_C_RAWDATA,SW1_PIN_MASK))); } if (sw0 && sw1) // if both buttons have been pressed, enter bootloader { // Turn on LEDs so the user knows we're here GPIO_A_DR |= GPIO_A_DR_D0_MASK; // set high GPIO_A_DR |= GPIO_A_DR_D1_MASK; // Initialize globals mem_init(rx_data, NULL, RX_DATA_SIZE); data_out = data_in = rx_data; state = INITIAL_STATE; temp_ptr = rx_data; // Disable protection setReg(FM_PROT,BOOT_PROT_VALUE); // Output banner sci_tx(&StrCopyright[0]); // Now it is safe to enable interrupts Cpu_EnableInt(); do { // State: Initial State if (state == INITIAL_STATE) { status = 0; sci_tx(&StrWaitingSrec[0]); sci_tx_char(XON); state = WAIT_FOR_S; } if (data_in != temp_ptr) { //Timer_Disable(); // State: Wait for Header "S" if (state == WAIT_FOR_S) { temp_ptr = data_out; if (get_char(&temp_ptr) == 'S') { state = WAIT_FOR_0; } else { get_char(&data_out); } } // State: Wait for Header "0" else if (state == WAIT_FOR_0) { if (get_char(&temp_ptr) == '0') { state = WAIT_FOR_EOL; } else { get_char(&data_out); state = WAIT_FOR_S; } } // State: Wait for EOL else if (state == WAIT_FOR_EOL) { if (get_char(&temp_ptr) == '\r') { if (!(status & TX_XOFF)) { sci_tx_char(XOFF); status |= TX_XOFF; } srec_decode(); temp_ptr = data_out; } } } else { if (status & TX_XOFF) { sci_tx_char(XON); status &= ~TX_XOFF; } } // State: Error if (status & DOWNLOAD_ERROR) { sci_tx(StrErr); sci_tx(int_to_string(status)); state = INITIAL_STATE; sci_tx(StrNewLine); } //bootTimerCheck(); } while (status != DOWNLOAD_OK); sci_tx(StrNewLine); sci_tx(&StrLoaded[0]); } bootExit(); }
int srec_load (char *name, unsigned char *image, int maxlen, unsigned short *start) { FILE *file; char buf[256]; srec_t srec; int line = 0; int length = 0; int strip = 0; /* Initialize starting address */ *start = IMAGE_START; /* Open file */ if ((file = fopen(name, "r")) == NULL) { fprintf(stderr, "%s: failed to open\n", name); exit(1); } /* Clear image to zero */ memset(image, 0, maxlen); /* Read image file */ while (fgets(buf, sizeof(buf), file)) { int error, i; line++; /* Skip blank lines */ for (i = 0; buf[i]; i++) if (!isspace(buf[i])) break; if (!buf[i]) continue; /* Decode line */ if ((error = srec_decode(&srec, buf)) < 0) { if (error != SREC_INVALID_CKSUM) { fprintf(stderr, "%s: %s on line %d\n", name, srec_strerror(error), line); exit(1); } } /* Detect Firm0309.lgo header, set strip=1 if found */ if (srec.type == 0) { if (srec.count == 16) if (!strncmp(srec.data, "?LIB_VERSION_L00", 16)) strip = 1; } /* Process s-record data */ else if (srec.type == 1) { if (srec.addr < IMAGE_START || srec.addr + srec.count > IMAGE_START + maxlen) { fprintf(stderr, "%s: address out of bounds on line %d\n", name, line); exit(1); } if (srec.addr + srec.count - IMAGE_START > length) length = srec.addr + srec.count - IMAGE_START; memcpy(&image[srec.addr - IMAGE_START], &srec.data, srec.count); } /* Process image starting address */ else if (srec.type == 9) { if (srec.addr < IMAGE_START || srec.addr > IMAGE_START + maxlen) { fprintf(stderr, "%s: address out of bounds on line %d\n", name, line); exit(1); } *start = srec.addr; } } /* Strip zeros */ #ifdef FORCE_ZERO_STRIPPING strip = 1; #endif if (strip) { int pos; for (pos = IMAGE_MAXLEN - 1; pos >= 0 && image[pos] == 0; pos--); length = pos + 1; } /* Check length */ if (length == 0) { fprintf(stderr, "%s: image contains no data\n", name); exit(1); } return length; }