📄 wrt54g.c
字号:
ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055);
ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0);
ejtag_write_h(addr, data_lo);
// wait for bits to stop toggling
while (ejtag_read_h(addr) != (data & 0xFFFF)) {}
// Now Handle Other Half Of Word
ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00AA00AA);
ejtag_write_h(FLASH_MEMORY_START+(0x2AA << 1), 0x00550055);
ejtag_write_h(FLASH_MEMORY_START+(0x555 << 1), 0x00A000A0);
ejtag_write_h(addr+2, data_hi);
// wait for bits to stop toggling
while (ejtag_read_h(addr+2) != ((data >> 16) & 0xFFFF)) {}
}
if (cmd_type == CMD_TYPE_SST)
{
// Handle Half Of Word
ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA);
ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055);
ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0);
ejtag_write_h(addr, data_lo);
// wait for bits to stop toggling
// while (ejtag_read_h(addr) != (data & 0xFFFF)) {}
while (ejtag_read_h(addr) != ejtag_read_h(addr)) {}
// Now Handle Other Half Of Word
ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00AA00AA);
ejtag_write_h(FLASH_MEMORY_START+(0x2AAA << 1), 0x00550055);
ejtag_write_h(FLASH_MEMORY_START+(0x5555 << 1), 0x00A000A0);
ejtag_write_h(addr+2, data_hi);
// wait for bits to stop toggling
// while (ejtag_read_h(addr+2) != ((data >> 16) & 0xFFFF)) {}
while (ejtag_read_h(addr+2) != ejtag_read_h(addr+2)) {}
}
if ((cmd_type == CMD_TYPE_BSC) || (cmd_type == CMD_TYPE_SCS))
{
// Handle Half Of Word
ejtag_write_h(addr, 0x00400040); // Write Command
ejtag_write_h(addr, data_lo); // Send HalfWord Data
while (ejtag_read_h(addr) != 0x0080) {} // Wait for completion of write
// Now Handle Other Half Of Word
ejtag_write_h(addr+2, 0x00400040); // Write Command
ejtag_write_h(addr+2, data_hi); // Send HalfWord Data
while (ejtag_read_h(addr) != 0x0080) {} // Wait for completion of write
}
}
void show_usage(void)
{
flash_chip_type* flash_chip = flash_chip_list;
processor_chip_type* processor_chip = processor_chip_list;
int counter = 0;
printf( " ABOUT: This program reads/writes flash memory on the WRT54G/GS and\n"
" compatible routers via EJTAG using either DMA Access routines\n"
" or PrAcc routines (slower/more compatible). Processor chips\n"
" supported in this version include the following chips:\n\n"
" Supported Chips\n"
" ---------------\n");
while (processor_chip->chip_id)
{
printf(" %-40.40s\n", processor_chip->chip_descr);
processor_chip++;
}
printf( "\n\n");
printf( " USAGE: wrt54g [parameter] </noreset> </noemw> </nocwd> </nobreak> </noerase>\n"
" </notimestamp> </dma> </nodma>\n"
" <start:XXXXXXXX> </length:XXXXXXXX>\n"
" </silent> </skipdetect> </instrlen:XX> </fc:XX>\n\n"
" Required Parameter\n"
" ------------------\n"
" -backup:cfe\n"
" -backup:nvram\n"
" -backup:kernel\n"
" -backup:wholeflash\n"
" -backup:env\n"
" -backup:custom\n"
" -erase:cfe\n"
" -erase:nvram\n"
" -erase:kernel\n"
" -erase:wholeflash\n"
" -erase:env\n"
" -erase:custom\n"
" -flash:cfe\n"
" -flash:nvram\n"
" -flash:kernel\n"
" -flash:wholeflash\n"
" -flash:env\n"
" -flash:custom\n\n"
" Optional Switches\n"
" -----------------\n"
" /noreset ........... prevent Issuing EJTAG CPU reset\n"
" /noemw ............. prevent Enabling Memory Writes\n"
" /nocwd ............. prevent Clearing CPU Watchdog Timer\n"
" /nobreak ........... prevent Issuing Debug Mode JTAGBRK\n"
" /noerase ........... prevent Forced Erase before Flashing\n"
" /notimestamp ....... prevent Timestamping of Backups\n"
" /dma ............... force use of DMA routines\n"
" /nodma ............. force use of PRACC routines (No DMA)\n"
" /window:XXXXXXXX ... custom flash window base (in HEX)\n"
" /start:XXXXXXXX .... custom start location (in HEX)\n"
" /length:XXXXXXXX ... custom length (in HEX)\n"
" /silent ............ prevent scrolling display of data\n"
" /skipdetect ........ skip auto detection of CPU Chip ID\n"
" /instrlen:XX ....... set instruction length manually\n\n"
" /fc:XX = Optional (Manual) Flash Chip Selection\n"
" -----------------------------------------------\n");
while (flash_chip->vendid)
{
printf(" /fc:%02d ............. %-40.40s\n", ++counter, flash_chip->flash_part);
flash_chip++;
}
printf( "\n\n");
printf( " NOTES: 1) If 'flashing' - the source filename must exist as follows:\n"
" CFE.BIN, NVRAM.BIN, ENV.BIN, KERNEL.BIN, WHOLEFLASH.BIN or CUSTOM.BIN\n\n"
" 2) If you have difficulty auto-detecting a particular flash part\n"
" you can manually specify your exact part using the /fc:XX option.\n\n"
" 3) If you have difficulty with the older bcm47xx chips or when no CFE\n"
" is currently active/operational you may want to try both the\n"
" /noreset and /nobreak command line options together. Some bcm47xx\n"
" chips *may* always require both these options to function properly.\n\n"
" 4) When using this utility, usually it is best to type the command line\n"
" out, then plug in the router, and then hit <ENTER> quickly to avoid\n"
" the CPUs watchdog interfering with the EJTAG operations.\n\n"
" ***************************************************************************\n"
" * Flashing the KERNEL or WHOLEFLASH will take a very long time using JTAG *\n"
" * via this utility. You are better off flashing the CFE & NVRAM files *\n"
" * & then using the normal TFTP method to flash the KERNEL via ethernet. *\n"
" ***************************************************************************\n\n");
}
int main(int argc, char** argv)
{
char choice[128];
int run_option;
int j;
printf("\n");
printf("====================================\n");
printf("WRT54G/GS EJTAG Debrick Utility v4.5\n");
printf("====================================\n\n");
if (argc < 2)
{
show_usage();
exit(1);
}
strcpy(choice,argv[1]);
run_option = 0;
if (strcasecmp(choice,"-backup:cfe")==0) { run_option = 1; strcpy(AREA_NAME, "CFE"); }
if (strcasecmp(choice,"-backup:nvram")==0) { run_option = 1; strcpy(AREA_NAME, "NVRAM"); }
if (strcasecmp(choice,"-backup:kernel")==0) { run_option = 1; strcpy(AREA_NAME, "KERNEL"); }
if (strcasecmp(choice,"-backup:wholeflash")==0) { run_option = 1; strcpy(AREA_NAME, "WHOLEFLASH"); }
if (strcasecmp(choice,"-backup:env")==0) { run_option = 1; strcpy(AREA_NAME, "ENV"); }
if (strcasecmp(choice,"-backup:custom")==0) { run_option = 1; strcpy(AREA_NAME, "CUSTOM"); custom_options++; }
if (strcasecmp(choice,"-erase:cfe")==0) { run_option = 2; strcpy(AREA_NAME, "CFE"); }
if (strcasecmp(choice,"-erase:nvram")==0) { run_option = 2; strcpy(AREA_NAME, "NVRAM"); }
if (strcasecmp(choice,"-erase:kernel")==0) { run_option = 2; strcpy(AREA_NAME, "KERNEL"); }
if (strcasecmp(choice,"-erase:wholeflash")==0) { run_option = 2; strcpy(AREA_NAME, "WHOLEFLASH"); }
if (strcasecmp(choice,"-erase:env")==0) { run_option = 2; strcpy(AREA_NAME, "ENV"); }
if (strcasecmp(choice,"-erase:custom")==0) { run_option = 2; strcpy(AREA_NAME, "CUSTOM"); custom_options++; }
if (strcasecmp(choice,"-flash:cfe")==0) { run_option = 3; strcpy(AREA_NAME, "CFE"); }
if (strcasecmp(choice,"-flash:nvram")==0) { run_option = 3; strcpy(AREA_NAME, "NVRAM"); }
if (strcasecmp(choice,"-flash:kernel")==0) { run_option = 3; strcpy(AREA_NAME, "KERNEL"); }
if (strcasecmp(choice,"-flash:wholeflash")==0) { run_option = 3; strcpy(AREA_NAME, "WHOLEFLASH"); }
if (strcasecmp(choice,"-flash:env")==0) { run_option = 3; strcpy(AREA_NAME, "ENV"); }
if (strcasecmp(choice,"-flash:custom")==0) { run_option = 3; strcpy(AREA_NAME, "CUSTOM"); custom_options++; }
if (run_option == 0)
{
show_usage();
printf("\n*** ERROR - Invalid [option] specified ***\n\n");
exit(1);
}
if (argc > 2)
{
j = 2;
while (j < argc)
{
strcpy(choice,argv[j]);
if (strcasecmp(choice,"/noreset")==0) issue_reset = 0;
else if (strcasecmp(choice,"/noemw")==0) issue_enable_mw = 0;
else if (strcasecmp(choice,"/nocwd")==0) issue_watchdog = 0;
else if (strcasecmp(choice,"/nobreak")==0) issue_break = 0;
else if (strcasecmp(choice,"/noerase")==0) issue_erase = 0;
else if (strcasecmp(choice,"/notimestamp")==0) issue_timestamp = 0;
else if (strcasecmp(choice,"/dma")==0) force_dma = 1;
else if (strcasecmp(choice,"/nodma")==0) force_nodma = 1;
else if (strncasecmp(choice,"/fc:",4)==0) selected_fc = strtoul(((char *)choice + 4),NULL,10);
else if (strncasecmp(choice,"/window:",8)==0) { selected_window = strtoul(((char *)choice + 8),NULL,16); custom_options++; }
else if (strncasecmp(choice,"/start:",7)==0) { selected_start = strtoul(((char *)choice + 7),NULL,16); custom_options++; }
else if (strncasecmp(choice,"/length:",8)==0) { selected_length = strtoul(((char *)choice + 8),NULL,16); custom_options++; }
else if (strcasecmp(choice,"/silent")==0) silent_mode = 1;
else if (strcasecmp(choice,"/skipdetect")==0) skipdetect = 1;
else if (strncasecmp(choice,"/instrlen:",10)==0) instrlen = strtoul(((char *)choice + 10),NULL,10);
else
{
show_usage();
printf("\n*** ERROR - Invalid <option> specified ***\n\n");
exit(1);
}
j++;
}
}
if (strcasecmp(AREA_NAME,"CUSTOM")==0)
{
if ((custom_options != 0) && (custom_options != 4))
{
show_usage();
printf("\n*** ERROR - 'CUSTOM' also requires '/window' '/start' and '/length' options ***\n\n");
exit(1);
}
}
// ----------------------------------
// Detect CPU
// ----------------------------------
chip_detect();
// ----------------------------------
// Find Implemented EJTAG Features
// ----------------------------------
check_ejtag_features();
// ----------------------------------
// Reset State Machine For Good Measure
// ----------------------------------
test_reset();
// ----------------------------------
// Reset Processor and Peripherals
// ----------------------------------
printf("Issuing Processor / Peripheral Reset ... ");
if (issue_reset)
{
set_instr(INSTR_CONTROL);
ctrl_reg = ReadWriteData(PRRST | PERRST);
printf("Done\n");
} else printf("Skipped\n");
// ----------------------------------
// Enable Memory Writes
// ----------------------------------
// Always skip for EJTAG versions 2.5 and 2.6 since they do not support DMA transactions.
// Memory Protection bit only applies to EJTAG 2.0 based chips.
if (ejtag_version != 0) issue_enable_mw = 0;
printf("Enabling Memory Writes ... ");
if (issue_enable_mw)
{
// Clear Memory Protection Bit in DCR
ejtag_dma_write(0xff300000, (ejtag_dma_read(0xff300000) & ~(1<<2)) );
printf("Done\n");
} else printf("Skipped\n");
// ----------------------------------
// Put into EJTAG Debug Mode
// ----------------------------------
printf("Halting Processor ... ");
if (issue_break)
{
set_instr(INSTR_CONTROL);
ctrl_reg = ReadWriteData(PRACC | PROBEN | SETDEV | JTAGBRK );
if (ReadWriteData(PRACC | PROBEN | SETDEV) & BRKST)
printf("<Processor Entered Debug Mode!> ... ");
else
printf("<Processor did NOT enter Debug Mode!> ... ");
printf("Done\n");
} else printf("Skipped\n");
// ----------------------------------
// Clear Watchdog
// ----------------------------------
printf("Clearing Watchdog ... ");
if (issue_watchdog)
{
ejtag_write(0xb8000080,0);
printf("Done\n");
} else printf("Skipped\n");
// ----------------------------------
// Flash Chip Detection
// ----------------------------------
if (selected_fc != 0)
sflash_config();
else
sflash_probe();
// ----------------------------------
// Execute Requested Operation
// ----------------------------------
if ((flash_size > 0) && (AREA_LENGTH > 0))
{
if (run_option == 1 ) run_backup(AREA_NAME, AREA_START, AREA_LENGTH);
if (run_option == 2 ) run_erase(AREA_NAME, AREA_START, AREA_LENGTH);
if (run_option == 3 ) run_flash(AREA_NAME, AREA_START, AREA_LENGTH);
}
printf("\n\n *** REQUESTED OPERATION IS COMPLETE ***\n\n");
chip_shutdown();
return 0;
}
// **************************************************************************
// End of File
// **************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -