From 7f807afceab690fc593e002f3c3cda1dfb2a250e Mon Sep 17 00:00:00 2001 From: Robert Zaage Date: Sun, 3 Jul 2022 09:49:25 +0200 Subject: [PATCH] Initial to English translated release --- Makefile | 9 +- README.md | 22 +--- balong-usbdload.c | 278 +++++++++++++++++++++++----------------------- loader-patch.c | 74 ++++++------ parts.c | 21 ++-- parts.h | 14 +-- patcher.c | 51 +++++---- ptable-injector.c | 72 ++++++------ ptable-list.c | 22 ++-- 9 files changed, 265 insertions(+), 298 deletions(-) diff --git a/Makefile b/Makefile index 3e10320..b09beb0 100755 --- a/Makefile +++ b/Makefile @@ -1,18 +1,18 @@ CC = gcc -LIBS = +LIBS = CFLAGS = -O2 -g -Wno-unused-result .PHONY: all clean all: balong-usbdload ptable-injector loader-patch ptable-list -clean: +clean: rm *.o rm balong-usbdload rm ptable-injector rm loader-patch rm ptable-list - + #.c.o: # $(CC) -o $@ $(LIBS) $^ qcio.o @@ -21,10 +21,9 @@ balong-usbdload: balong-usbdload.o parts.o patcher.o ptable-injector: ptable-injector.o parts.o @gcc $^ -o $@ $(LIBS) - + loader-patch: loader-patch.o patcher.o @gcc $^ -o $@ $(LIBS) ptable-list: ptable-list.o parts.o @gcc $^ -o $@ $(LIBS) - \ No newline at end of file diff --git a/README.md b/README.md index b11d697..92283c8 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,11 @@ # balong-usbdload -**Please read "getting help" section carefully before asking any questions!** - -## Russian section - -Утилита для аварийной USB-загрузки модемов на чипсете Balong V2R7, V7R11 и V7R22. -Позволяет загрузить внешний загрузчик-прошивальщик (usbloader) через аварийный USB-serial порт загрузки, создаваемый модемом при повреждении прошивки или замыкании на землю контакта аварийной загрузки на плате модема. - -Многие загрузчики могут быть автоматически пропатчены данной утилитой в процессе загрузки. Патч необходим потому, что оригинальный usbloader стирает всю флеш-память в процессе загрузки, включая уникальные данные, хранящиеся в NVRAM. - -**Эта утилита может вывести ваше устройство из строя!** -Используйте ее, только если осознаете все риски и последствия. В случае каких-либо возникших проблем, не ждите помощи, рассчитывайте только на свои собственные силы. - -Пожалуйста, воздержитесь от любых вопросов, не касающихся программы напрямую, в том числе и о вопросах о файлах-загрузчиках. У нас их нет. Нет, мы не знаем, где их взять. - -## English section - ### About -Balong-usbdload is an emergency USB boot loader utility for Huawei LTE modems and routers with Balong V2R7, V7R11 and V7R22 chipsets. +Balong-usbdload is an emergency USB boot loader utility for Huawei LTE modems and routers with Balong V2R7, V7R11 and V7R22 chipsets. It loads external boot loader/firmware update tool file (usbloader.bin) via emergency serial port available if the firmware is corrupted or boot pin (test point) is shorted to the ground. -**This utility can make your device unbootable!** +**This utility can make your device unbootable!** Use it only if you fully understand all risks and consequences. In case of any issues, you're on your own. Do not expect any help. ### Where to get USB loader files (usbloader.bin)? @@ -55,7 +39,7 @@ We have no idea where boot pin is on your model. Look [here](https://routerunloc * Please **DO NOT ASK** Windows-relared questions or ask for Windows builds. -Main development is focused on Linux version only. +Main development is focused on Linux version only. Windows part is maintained by [**@rust3028**](https://github.com/rust3028) and is out of scope of this repository. **To sum it up**: feel free to ask questions about the program itself; Report bugs if it could be reproduced in Linux. No questions about loader files allowed. Pull requests with functionality changes or bug fixes are welcome. diff --git a/balong-usbdload.c b/balong-usbdload.c index 539084c..29646e9 100644 --- a/balong-usbdload.c +++ b/balong-usbdload.c @@ -1,5 +1,6 @@ -// Загрузчик usbloader.bin через аварийный порт для модемов на платформе Balong V7R2. // +// Balong-usbdload is an emergency USB boot loader utility for Huawei LTE modems and routers with Balong V2R7, V7R11 and V7R22 chipsets. +// It loads external boot loader/firmware update tool file (usbloader.bin) via emergency serial port available if the firmware is corrupted or boot pin (test point) is shorted to the ground. // #include #include @@ -35,7 +36,7 @@ FILE* ldr; //************************************************* -//* HEX-дамп области памяти * +//* HEX-dump of the memory area * //************************************************* void dump(unsigned char buffer[],int len) { @@ -51,12 +52,12 @@ for (i=0;i 0x7e)&&(ch<0xc0))) putchar('.'); else putchar(ch); - } - // заполнение пробелами для неполных строк + } + // filling with spaces for incomplete lines else printf(" "); } printf("*\n"); @@ -65,26 +66,25 @@ for (i=0;i>4)^(csum>>12)]; csum=((csum<<4)&0xffff)^cconst[(c&0xf)^(csum>>12)]; -} +} buf[len-2]=(csum>>8)&0xff; buf[len-1]=csum&0xff; - + } //************************************************* -//* Отсылка командного пакета модему +//* Sending a command packet to a modem * //************************************************* int sendcmd(unsigned char* cmdbuf, int len) { @@ -93,7 +93,7 @@ unsigned int replylen; #ifndef WIN32 csum(cmdbuf,len); -write(siofd,cmdbuf,len); // отсылка команды +write(siofd,cmdbuf,len); // sending a command tcdrain(siofd); replylen=read(siofd,replybuf,1024); #else @@ -109,55 +109,55 @@ replylen=read(siofd,replybuf,1024); ReadFile(hSerial, replybuf, 1024, (LPDWORD)&replylen, NULL); } while (replylen == 0 && GetTickCount() - t < 1000); #endif -if (replylen == 0) return 0; +if (replylen == 0) return 0; if (replybuf[0] == 0xaa) return 1; return 0; } -//************************************* -// Открытие и настройка последовательного порта -//************************************* +//************************************************* +// Opening and configuring the serial port * +//************************************************* int open_port(char* devname) { -//============= Linux ======================== +//============= Linux =============== #ifndef WIN32 int i,dflag=1; char devstr[200]={0}; -// Вместо полного имени устройства разрешается передавать только номер ttyUSB-порта +// only the ttyUSB port number can be transmitted instead of the full device name. -// Проверяем имя устройства на наличие нецифровых символов +// check the device name for nonnumeric characters for(i=0;i'9')) dflag=0; } -// Если в строке - только цифры, добавляем префикс /dev/ttyUSB +// if there are only digits in the string, add the prefix /dev/ttyUSB if (dflag) strcpy(devstr,"/dev/ttyUSB"); -// копируем имя устройства +// copy the device name strcat(devstr,devname); siofd = open(devstr, O_RDWR | O_NOCTTY |O_SYNC); if (siofd == -1) return 0; -bzero(&sioparm, sizeof(sioparm)); // готовим блок атрибутов termios +bzero(&sioparm, sizeof(sioparm)); // prepare the attribute block termios sioparm.c_cflag = B115200 | CS8 | CLOCAL | CREAD ; sioparm.c_iflag = 0; // INPCK; sioparm.c_oflag = 0; sioparm.c_lflag = 0; -sioparm.c_cc[VTIME]=30; // timeout -sioparm.c_cc[VMIN]=0; +sioparm.c_cc[VTIME]=30; // timeout +sioparm.c_cc[VMIN]=0; tcsetattr(siofd, TCSANOW, &sioparm); return 1; -//============= Win32 ======================== +//============= Win32 =============== #else char device[20] = "\\\\.\\COM"; DCB dcbSerialParams = {0}; COMMTIMEOUTS CommTimeouts; strcat(device, devname); - + hSerial = CreateFileA(device, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hSerial == INVALID_HANDLE_VALUE) return 0; @@ -192,11 +192,11 @@ return 1; #endif } -//************************************* -//* Поиск linux-ядра в образе раздела -//************************************* +//******************************************************* +//* Searching for the linux core in the partition image * +//******************************************************* int locate_kernel(char* pbuf, uint32_t size) { - + int off; for(off=(size-8);off>0;off--) { @@ -268,10 +268,10 @@ static int find_port(int* port_no, char* port_name) void main(int argc, char* argv[]) { unsigned int i,res,opt,datasize,pktcount,adr; -int bl; // текущий блок +int bl; // current block unsigned char c; int fbflag=0, tflag=0, mflag=0, bflag=0, cflag=0; -int koff; // смещение до ANDROID-заголовка +int koff; // offset to ANDROID header char ptfile[100]; FILE* pt; @@ -284,15 +284,15 @@ unsigned char cmdhead[14]={0xfe,0, 0xff}; unsigned char cmddata[1040]={0xda,0,0}; unsigned char cmdeod[5]={0xed,0,0,0,0}; -// список разделов, которым нужно установить файловый флаг +// list of partitions to set the file flag uint8_t fileflag[41]; struct { - int lmode; // режим загрузки: 1 - прямой старт, 2 - через перезапуск A-core - int size; // размер компонента - int adr; // адрес загрузки компонента в память - int offset; // смещение до компонента от начала файла - char* pbuf; // буфер для загрузки образа компонента + int lmode; // loading mode: 1 - direct start, 2 - via restarting A-core + int size; // size of a component + int adr; // address of the component loading into memory + int offset; // offset to the component from the beginning of the file + char* pbuf; // buffer for loading the component image } blk[10]; @@ -313,23 +313,23 @@ memset(fileflag, 0, sizeof(fileflag)); while ((opt = getopt(argc, argv, "hp:ft:ms:bc")) != -1) { switch (opt) { - case 'h': - -printf("\n Утилита предназначена для аварийной USB-загрузки устройств на чипете Balong V7\n\n\ -%s [ключи] <имя файла для загрузки>\n\n\ - Допустимы следующие ключи:\n\n" + case 'h': + +printf("\n This utility is intended for emergency USB loading of devices on the Balong V7 chip\n\n\ +%s [option] \n\n\ + The following options are allowed:\n\n" #ifndef WIN32 -"-p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0)\n" +"-p - serial port for communicating with the bootloader (by default /dev/ttyUSB0)\n" #else -"-p # - номер последовательного порта для общения с загрузчиком (например, -p8)\n" -" если ключ -p не указан, производится автоопределение порта\n" +"-p # - number of the serial port for communicating with the loader (e.g. -p8)\n" +" if the -p switch is not specified, the port is auto-detected\n" #endif -"-f - грузить usbloader только до fastboot (без запуска линукса)\n\ --b - аналогично -f, дополнительно отключить проверку дефектных блоков при стирании\n\ --t - взять таблицу разделов из указанного файла\n\ --m - показать таблицу разделов загрузчика и завершить работу\n\ --s n - установить файловый флаг для раздела n (ключ можно указать несколько раз)\n\ --c - не производить автоматический патч стирания разделов\n\ +"-f - Load usbloader only to fastboot (without starting Linux)\n\ +-b - Similarly to -f, additionally disable check of defective blocks during wipeout\n\ +-t - Take partition table from specified file\n\ +-m - Show the loader partition table and exit\n\ +-s n - Set file flag for partition n (option can be set multiple times)\n\ +-c - Do not automatically patch partitions\n\ \n",argv[0]); return; @@ -362,134 +362,134 @@ printf("\n Утилита предназначена для аварийной U case 's': i=atoi(optarg); if (i>41) { - printf("\n Раздела #%i не существует\n",i); + printf("\n Partition #%i does not exist\n",i); return; } fileflag[i]=1; break; - + case '?': - case ':': + case ':': return; - + } -} +} -printf("\n Аварийный USB-загрузчик Balong-чипсета, версия 2.20, (c) forth32, 2015"); +printf("\n Balong-chipset emergency USB loader, version 2.20, (c) forth32, 2015\n"); +printf("\n English Version (c) robertzaage, 2022"); #ifdef WIN32 -printf("\n Порт для Windows 32bit (c) rust3028, 2016"); +printf("\n Windows Port 32bit (c) rust3028, 2016"); #endif - if (optind>=argc) { - printf("\n - Не указано имя файла для загрузки\n"); + printf("\n - File to upload is not specified\n"); return; -} +} ldr=fopen(argv[optind],"rb"); if (ldr == 0) { - printf("\n Ошибка открытия %s",argv[optind]); + printf("\n Opening error %s",argv[optind]); return; } -// Прверяем сигнатуру usloader +// Checking the usloader signature fread(&i,1,4,ldr); if (i != 0x20000) { - printf("\n Файл %s не является загрузчиком usbloader\n",argv[optind]); + printf("\n File %s is not a usbloader\n",argv[optind]); return; -} +} -fseek(ldr,36,SEEK_SET); // начало описателей блоков для загрузки +fseek(ldr,36,SEEK_SET); // beginning of block descriptors to load -// Разбираем заголовок +// parsing the header fread(&blk[0],1,16,ldr); // raminit fread(&blk[1],1,16,ldr); // usbldr //--------------------------------------------------------------------- -// Чтение компонентов в память +// reading components into memory for(bl=0;bl<2;bl++) { - // выделяем память под полный образ раздела + // allocate memory for the full image of the partition blk[bl].pbuf=(char*)malloc(blk[bl].size); - // читаем образ раздела в память + // read partition image into memory fseek(ldr,blk[bl].offset,SEEK_SET); res=fread(blk[bl].pbuf,1,blk[bl].size,ldr); if (res != blk[bl].size) { - printf("\n Неожиданный конец файла: прочитано %i ожидалось %i\n",res,blk[bl].size); + printf("\n Unexpected end of file: read %i expected %i\n",res,blk[bl].size); return; } - if (bl == 0) continue; // для raminit более ничего делать не надо + if (bl == 0) continue; // nothing more needs to be done for raminit - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // fastboot-патч + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // fastboot patch if (fbflag) { koff=locate_kernel(blk[bl].pbuf,blk[bl].size); if (koff != 0) { - blk[bl].pbuf[koff]=0x55; // патч сигнатуры - blk[bl].size=koff+8; // обрезаем раздел до начала ядра + blk[bl].pbuf[koff]=0x55; // patch the signature + blk[bl].size=koff+8; // trim the partition to the start of the kernel } else { - printf("\n В загрузчике нет ANDROID-компонента - fastboot-загрузка невозможна\n"); + printf("\n There is no ANDROID component in the loader - fastboot-loading is not possible.\n"); exit(0); - } - } + } + } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // Ищем таблицу разделов в загрузчике + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // look for the partition table in the boot loader ptoff=find_ptable_ram(blk[bl].pbuf,blk[bl].size); - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // патч таблицы разделов + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // patch partition table if (tflag) { pt=fopen(ptfile,"rb"); - if (pt == 0) { - printf("\n Не найден файл %s - замена таблицы разделов невозможна\n",ptfile); + if (pt == 0) { + printf("\n File %s is not found - partition table cannot be replaced\n",ptfile); return; - } + } fread(ptbuf,1,2048,pt); fclose(pt); if (memcmp(headmagic,ptbuf,sizeof(headmagic)) != 0) { - printf("\n Файл %s не явлется таблицей разделов\n",ptfile); + printf("\n The file %s is not a partition table\n",ptfile); return; - } + } if (ptoff == 0) { - printf("\n В загрузчике не найдена таблица разделов - замена невозможна"); + printf("\n No partition table found in loader - cannot be replaced"); return; } memcpy(blk[bl].pbuf+ptoff,ptbuf,2048); } ptable=(struct ptable_t*)(blk[bl].pbuf+ptoff); - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // Патч файловых флагов + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // patch file flags for(i=0;i<41;i++) { if (fileflag[i]) { ptable->part[i].nproperty |= 1; - } - } + } + } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // Вывод таблицы разделов + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // output partition table if (mflag) { if (ptoff == 0) { - printf("\n Таблица разделов не найдена - вывод карты невозможен\n"); + printf("\n Partition table not found - mapping output not possible\n"); return; } show_map(*ptable); return; } - // Патч erase-процедуры на предмет игнорировани бедблоков + // patch the erase procedure to ignore deadlocks if (bflag) { res=perasebad(blk[bl].pbuf, blk[bl].size); - if (res == 0) { - printf("\n! Не найдена сигнатура isbad - загрузка невозможна\n"); + if (res == 0) { + printf("\n! No isbad signature found - cannot load\n"); return; - } + } } - // Удаление процедуры flash_eraseall + // removing the flash_eraseall procedure if (!cflag) { res = pv7r1(blk[bl].pbuf, blk[bl].size); if (res == 0) @@ -502,9 +502,9 @@ for(bl=0;bl<2;bl++) { res = pv7r22_2(blk[bl].pbuf, blk[bl].size); if (res == 0) res = pv7r22_3(blk[bl].pbuf, blk[bl].size); - if (res != 0) printf("\n\n * Удалена процедура flash_eraseall по смещению %08x", blk[bl].offset + res); + if (res != 0) printf("\n\n * Removed flash_eraseall procedure at offset %08x", blk[bl].offset + res); else { - printf("\n Процедура eraseall не найдена в загрузчике - используйте ключ -с для загрузки без патча!\n"); + printf("\n Procedure eraseall not found in the bootloader - use key -s to boot without patch!\n"); return; } } @@ -516,28 +516,27 @@ for(bl=0;bl<2;bl++) { #ifdef WIN32 if (*devname == '\0') { - printf("\n\nПоиск порта аварийной загрузки...\n"); - + printf("\n\nSearching for the emergency loading port...\n"); + if (find_port(&port_no, port_name) == 0) { sprintf(devname, "%d", port_no); - printf("Порт: \"%s\"\n", port_name); + printf("Port: \"%s\"\n", port_name); } else { - printf("Порт не обнаружен!\n"); + printf("No port found!\n"); return; } } #endif if (!open_port(devname)) { - printf("\n Последовательный порт не открывается\n"); + printf("\n Can't open serial port\n"); return; -} - +} -// Проверяем загрузочный порт +// Check the boot port c=0; #ifndef WIN32 write(siofd,"A",1); @@ -549,66 +548,63 @@ res=read(siofd,&c,1); ReadFile(hSerial, &c, 1, &bytes_read, NULL); #endif if (c != 0x55) { - printf("\n ! Порт не находится в режиме USB Boot\n"); + printf("\n! Port is not in USB-Boot mode\n"); return; -} +} //---------------------------------- -// главный цикл загрузки - загружаем все блоки, найденные в заголовке -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// main loading cycle - load all the blocks found in the header +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -printf("\n\n Компонент Адрес Размер %%загрузки\n------------------------------------------\n"); +printf("\n\n Component Address Size %% loaded\n------------------------------------------\n"); for(bl=0;bl<2;bl++) { datasize=1024; pktcount=1; - - // фрмируем пакет начала блока + // create a package of the beginning of the block *((unsigned int*)&cmdhead[4])=htonl(blk[bl].size); *((unsigned int*)&cmdhead[8])=htonl(blk[bl].adr); cmdhead[3]=blk[bl].lmode; - - // отправляем пакет начала блока + + // send a block start packet res=sendcmd(cmdhead,14); if (!res) { - printf("\nМодем отверг пакет заголовка\n"); + printf("\nModem rejected the header packet\n"); return; - } + } + - - // ---------- Цикл поблочной загрузки данных --------------------- + // ---------- Block-by-block data loading cycle ------------ for(adr=0;adr=blk[bl].size) datasize=blk[bl].size-adr; + // get the size of the last downloaded packet + if ((adr+1024)>=blk[bl].size) datasize=blk[bl].size-adr; + + printf("\r %s %08x %8i %i%%",bl?"usbboot":"raminit",blk[bl].adr,blk[bl].size,(adr+datasize)*100/blk[bl].size); - printf("\r %s %08x %8i %i%%",bl?"usbboot":"raminit",blk[bl].adr,blk[bl].size,(adr+datasize)*100/blk[bl].size); - - // готовим пакет данных + // prepare the data package cmddata[1]=pktcount; cmddata[2]=(~pktcount)&0xff; memcpy(cmddata+3,blk[bl].pbuf+adr,datasize); - + pktcount++; if (!sendcmd(cmddata,datasize+5)) { - printf("\nМодем отверг пакет данных"); + printf("\nModem rejected the data packet"); return; - } + } } free(blk[bl].pbuf); - // Фрмируем пакет конца данных + // prepare an end-of-data packet cmdeod[1]=pktcount; cmdeod[2]=(~pktcount)&0xff; if (!sendcmd(cmdeod,5)) { - printf("\nМодем отверг пакет конца данных"); + printf("\nModem rejected the end of data packet"); } -printf("\n"); -} -printf("\n Загрузка окончена\n"); +printf("\n"); +} +printf("\n Loading finished!\n"); } - - diff --git a/loader-patch.c b/loader-patch.c index a045634..1a88501 100644 --- a/loader-patch.c +++ b/loader-patch.c @@ -18,7 +18,7 @@ //####################################################################################################### void main(int argc, char* argv[]) { - + FILE* in; FILE* out; uint8_t* buf; @@ -28,18 +28,17 @@ uint8_t outfilename[100]; int oflag=0,bflag=0; uint32_t res; - -// Разбор командной строки +// parsing command line while ((opt = getopt(argc, argv, "o:bh")) != -1) { switch (opt) { - case 'h': - -printf("\n Программа для автоматического патча загрузчиков платформ Balong V7\n\n\ -%s [ключи] <файл загрузчика usbloader>\n\n\ - Допустимы следующие ключи:\n\n\ --o file - имя выходного файла. По умолчанию производится только проверка возможности патча\n\ --b - добавить патч, отключающий проверку дефектных блоков\n\ + case 'h': + +printf("\n Program for automatic patching of Balong V7 bootloaders\n\n\ +%s [options] \n\n\ + Following options are allowed:\n\n\ +-o file - Name of the output file (by default, only a patch test is performed)\n\ +-b - Add a patch that disables checking of defective blocks\n\ \n",argv[0]); return; @@ -51,33 +50,34 @@ printf("\n Программа для автоматического патча case 'b': bflag=1; break; - + case '?': - case ':': + case ':': return; - + } -} +} -printf("\n Программа автоматической модификации загрузчиков Balong V7, (c) forth32"); +printf("\n Program for automatic modification of Balong V7 loaders, (c) forth32"); +printf("\n English Version (c) robertzaage, 2022"); - if (optind>=argc) { - printf("\n - Не указано имя файла для загрузки\n - Для подсказки укажите ключ -h\n"); +if (optind>=argc) { + printf("\n - Name of the file to load is not specified\n - add -h option for help\n"); return; -} - +} + in=fopen(argv[optind],"rb"); if (in == 0) { - printf("\n Ошибка открытия файла %s",argv[optind]); + printf("\n Can't open file %s",argv[optind]); return; } -// определяем размер файла +// determine file size fseek(in,0,SEEK_END); fsize=ftell(in); rewind(in); -// выделяем буфер и читаем туда весь файл +// select a buffer and read the whole file there buf=malloc(fsize); fread(buf,1,fsize,in); fclose(in); @@ -86,49 +86,49 @@ fclose(in); res=pv7r1(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R1 по смещению %08x",res); + printf("\n* V7R1 type signature found at offset %08x",res); goto endpatch; -} +} res=pv7r2(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R2 по смещению %08x",res); + printf("\n* V7R2 type signature found at offset %08x",res); goto endpatch; -} +} res=pv7r11(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R11 по смещению %08x",res); + printf("\n* V7R11 type signature found at offset %08x",res); goto endpatch; -} +} res=pv7r22(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R22 по смещению %08x",res); + printf("\n* V7R22 type signature found at offset %08x",res); goto endpatch; -} +} res=pv7r22_2(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R22_2 по смещению %08x",res); + printf("\n* V7R22_2 type signature found at offset %08x",res); goto endpatch; } res=pv7r22_3(buf, fsize); if (res != 0) { - printf("\n* Найдена сигнатура типа V7R22_3 по смещению %08x",res); + printf("\n* V7R22_3 type signature found at offset %08x",res); goto endpatch; } -printf("\n! Сигнатура eraseall-патча не найдена"); +printf("\n! Patch eraseall signature not found"); //================================================================================== endpatch: if (bflag) { res=perasebad(buf, fsize); - if (res != 0) printf("\n* Найдена сигнатура isbad по смещению %08x",res); - else printf("\n! Сигнатура isbad не найдена"); + if (res != 0) printf("\n* Found isbad signature at offset %08x",res); + else printf("\n! Signature isbad not found"); } if (oflag) { @@ -137,10 +137,8 @@ if (oflag) { fwrite(buf,1,fsize,out); fclose(out); } - else printf("\n Ошибка открытия выходного файла %s",outfilename); + else printf("\n Error opening output file %s",outfilename); } free(buf); printf("\n"); } - - \ No newline at end of file diff --git a/parts.c b/parts.c index b4e335b..0a96480 100644 --- a/parts.c +++ b/parts.c @@ -11,11 +11,11 @@ #include "parts.h" -// сигнатура заголовка таблицы -const uint8_t headmagic[16]={0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}; +// header signature table +const uint8_t headmagic[16]={0x70, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}; //********************************************* -//* Поиск таблицы разделов в загрузчике +//* Search for the partition table in the loader //********************************************* uint32_t find_ptable(FILE* ldr) { @@ -29,16 +29,16 @@ while (fread(rbuf,1,16,ldr) == 16) { } return 0; } - + //********************************************* -//* Печать таблицы разделов +//* Printing the partition table //********************************************* void show_map(struct ptable_t ptable) { int pnum; - -printf("\n Версия таблицы разделов: %16.16s",ptable.version); -printf("\n Версия прошивки: %16.16s\n",ptable.product); + +printf("\n Partition table version: %16.16s",ptable.version); +printf("\n Firmware version: %16.16s\n",ptable.product); printf("\n ## ----- NAME ----- start len loadsize loadaddr entry flags type count\n------------------------------------------------------------------------------------------"); @@ -64,11 +64,11 @@ printf("\n"); } //********************************************* -//* Поиск таблицы разделов в памяти +//* Search for partition table in memory //********************************************* uint32_t find_ptable_ram(char* buf, uint32_t size) { -// сигнатура заголовка таблицы +// header signature table uint32_t off; for(off=0;off<(size-16);off+=4) { @@ -76,4 +76,3 @@ for(off=0;off<(size-16);off+=4) { } return 0; } - diff --git a/parts.h b/parts.h index 7a6db38..e4bdd31 100644 --- a/parts.h +++ b/parts.h @@ -1,18 +1,18 @@ -// Структура описателя раздела +// partition descriptor structure struct ptable_line{ char name[16]; unsigned start; unsigned lsize; unsigned length; - unsigned loadaddr; - unsigned entry; - unsigned type; - unsigned nproperty; // флаги раздела + unsigned loadaddr; + unsigned entry; + unsigned type; + unsigned nproperty; // partition flags unsigned count; }; -// Полная структура страницы таблицы разделов +// pull page structure from partition table struct ptable_t { uint8_t head[16]; uint8_t version[16]; @@ -21,7 +21,7 @@ struct ptable_t { uint8_t tail[32]; }; -// сигнатура заголовка таблицы +// header signature table extern const uint8_t headmagic[16]; uint32_t find_ptable(FILE* ldr); diff --git a/patcher.c b/patcher.c index a65abf8..e9fea20 100644 --- a/patcher.c +++ b/patcher.c @@ -4,21 +4,21 @@ #include //*********************************************************************** -//* Поиск сигнатуры и наложение патча +//* Find the signature and apply the patch //* -//* ptype=0 - nop-патч -//* ptype=1 - br-патч +//* ptype=0 - nop-patch +//* ptype=1 - br-patch //*********************************************************************** uint32_t patch(struct defpatch fp, uint8_t* buf, uint32_t fsize, uint32_t ptype) { -// накладываемый патч - mov r0,#0 -const char nop0[4]={0, 0, 0xa0, 0xe3}; +// overlapping patch - mov r0,#0 +const char nop0[4]={0, 0, 0xa0, 0xe3}; uint32_t i; uint8_t c; for(i=8;i<(fsize-60);i+=4) { if (memcmp(buf+i,fp.sig, fp.sigsize) == 0) { - // найдена сигнатура - накладываем патч и уходим + // a signature is found - apply the patch and exit switch (ptype) { case 0: memcpy(buf+i+fp.sigsize+fp.poffset,nop0,4); @@ -35,17 +35,17 @@ for(i=8;i<(fsize-60);i+=4) { } } } -// сигнатрура не найдена +// no signature found return 0; } //********************************************** -// Описатели патчей +// Patch Descriptors //********************************************** const char sigburn_v7r22[]={ 0x12, 0x3B, 0xA0, 0xE3, 0x4A, 0x35, 0x4A, 0xE3, 0x00, 0x20, 0xA0, 0xE3, - 0x78, 0x20, 0xC3, 0xE5, 0x79, 0x20, 0xC3, 0xE5, 0x7A, 0x20, 0xC3, 0xE5, + 0x78, 0x20, 0xC3, 0xE5, 0x79, 0x20, 0xC3, 0xE5, 0x7A, 0x20, 0xC3, 0xE5, 0x7B, 0x20, 0xC3, 0xE5, 0x00, 0x00, 0xA0, 0xE3}; const char sigburn_v7r22_2[]={ @@ -57,35 +57,35 @@ const char sigburn_v7r22_3[]={ 0x18, 0x30, 0x94, 0xE5, 0x14, 0x30, 0x8D, 0xE5}; const char sigburn_v7r11[]={ - 0x00, 0x00, 0x50, 0xE3, 0x70, 0x80, 0xBD, 0x08, 0x00, 0x30, 0xA0, 0xE3, - 0x4E, 0x26, 0x04, 0xE3, 0xE0, 0x3F, 0x44, 0xE3, 0x55, 0x22, 0x44, 0xE3, - 0x4C, 0x01, 0x9F, 0xE5, 0x4E, 0xC6, 0x04, 0xE3, 0x48, 0x41, 0x9F, 0xE5, - 0x02, 0x10, 0xA0, 0xE1, 0x4C, 0xC4, 0x44, 0xE3, 0x5C, 0x23, 0x83, 0xE5, + 0x00, 0x00, 0x50, 0xE3, 0x70, 0x80, 0xBD, 0x08, 0x00, 0x30, 0xA0, 0xE3, + 0x4E, 0x26, 0x04, 0xE3, 0xE0, 0x3F, 0x44, 0xE3, 0x55, 0x22, 0x44, 0xE3, + 0x4C, 0x01, 0x9F, 0xE5, 0x4E, 0xC6, 0x04, 0xE3, 0x48, 0x41, 0x9F, 0xE5, + 0x02, 0x10, 0xA0, 0xE1, 0x4C, 0xC4, 0x44, 0xE3, 0x5C, 0x23, 0x83, 0xE5, 0x00, 0x00, 0x8F, 0xE0, 0x40, 0xC3, 0x83, 0xE5}; -const char sigburn_v7r2[]={ +const char sigburn_v7r2[]={ 0x00, 0x30, 0xA0, 0xE3, 0x9A, 0x3F, 0x07, 0xEE, 0xFF, 0x2F, 0x0F, 0xE3, - 0xE1, 0x2F, 0x44, 0xE3, 0x07, 0x30, 0x02, 0xE5, 0x9A, 0x3F, 0x07, 0xEE, - 0x00, 0x40, 0xA0, 0xE3, 0xE0, 0x4F, 0x44, 0xE3, 0x4E, 0x36, 0x04, 0xE3, + 0xE1, 0x2F, 0x44, 0xE3, 0x07, 0x30, 0x02, 0xE5, 0x9A, 0x3F, 0x07, 0xEE, + 0x00, 0x40, 0xA0, 0xE3, 0xE0, 0x4F, 0x44, 0xE3, 0x4E, 0x36, 0x04, 0xE3, 0x4C, 0x34, 0x44, 0xE3, 0x30, 0x33, 0x84, 0xE5}; -const char sigburn_v7r1[]={ - 0x3D, 0xE2, 0xE0, 0xE3, 0x00, 0xE0, 0x9E, 0xE5, 0x5C, 0xC3, 0x9F, 0xE5, +const char sigburn_v7r1[]={ + 0x3D, 0xE2, 0xE0, 0xE3, 0x00, 0xE0, 0x9E, 0xE5, 0x5C, 0xC3, 0x9F, 0xE5, 0x0C, 0x00, 0x5E, 0xE1, 0x00, 0x00, 0x00, 0x0A}; - + const char sigbad[]={0x04, 0x10, 0x8D, 0xE2, 0x04, 0x00, 0xA0, 0xE1}; struct defpatch patch_v7r22={sigburn_v7r22, sizeof(sigburn_v7r22), -37}; struct defpatch patch_v7r22_2={sigburn_v7r22_2, sizeof(sigburn_v7r22_2), 0}; struct defpatch patch_v7r22_3={sigburn_v7r22_3, sizeof(sigburn_v7r22_3), 0}; -struct defpatch patch_v7r11={sigburn_v7r11, sizeof(sigburn_v7r11), 4}; -struct defpatch patch_v7r2={sigburn_v7r2, sizeof(sigburn_v7r2), 16}; -struct defpatch patch_v7r1={sigburn_v7r1, sizeof(sigburn_v7r1), 0}; -struct defpatch patch_erasebad={sigbad, sizeof(sigbad), 0}; - +struct defpatch patch_v7r11={sigburn_v7r11, sizeof(sigburn_v7r11), 4}; +struct defpatch patch_v7r2={sigburn_v7r2, sizeof(sigburn_v7r2), 16}; +struct defpatch patch_v7r1={sigburn_v7r1, sizeof(sigburn_v7r1), 0}; +struct defpatch patch_erasebad={sigbad, sizeof(sigbad), 0}; + //**************************************************** -//* Процедуры патча под разные чипсеты и задачи +//* Patch procedures for different chipsets and tasks //**************************************************** uint32_t pv7r2 (uint8_t* buf, uint32_t fsize) { return patch(patch_v7r2, buf, fsize,0); } @@ -95,4 +95,3 @@ uint32_t pv7r22 (uint8_t* buf, uint32_t fsize) { return patch(patch_v7r22, buf, uint32_t pv7r22_2 (uint8_t* buf, uint32_t fsize) { return patch(patch_v7r22_2, buf, fsize,0); } uint32_t pv7r22_3 (uint8_t* buf, uint32_t fsize) { return patch(patch_v7r22_3, buf, fsize,0); } uint32_t perasebad (uint8_t* buf, uint32_t fsize) { return patch(patch_erasebad, buf, fsize,0); } - diff --git a/ptable-injector.c b/ptable-injector.c index 53fb523..4fa78e9 100644 --- a/ptable-injector.c +++ b/ptable-injector.c @@ -1,6 +1,5 @@ -// Программа для замены таблицы разделов в загрузчике usbloader -// -// +// Program to replace the partition table in the usbloader +// #include #include @@ -18,13 +17,12 @@ #include "parts.h" - //############################################################################################################3 void main(int argc, char* argv[]) { - - -int opt; + + +int opt; int mflag=0; char ptfile[100]; int rflag=0,xflag=0; @@ -38,64 +36,63 @@ FILE* in; while ((opt = getopt(argc, argv, "mr:hx")) != -1) { switch (opt) { - case 'h': - -printf("\n Утилита для замены таблицы разделов в загрузчиках usbloader\ + case 'h': + +printf("\n Utility for partition table replacement in usbloaders\ \n\n\ -%s [ключи] <имя файла usbloader>\n\n\ - Допустимы следующие ключи:\n\n\ --m - показать текущую карту разделов в usbloader\n\ --x - извлечь текущую карту в файл ptable.bin\n\ --r - заменить карту разделов на карту из указанного файла\n\ +%s [options] \n\n\ + Following options are allowed:\n\n\ +-m - Show current partition map in usbloader\n\ +-x - Extract current partition map to ptable.bin file\n\ +-r - Replace current partition map with map from specified file\n\ \n",argv[0]); return; - + case 'm': mflag=1; break; - + case 'x': xflag=1; break; - + case 'r': rflag=1; strcpy (ptfile,optarg); break; - + case '?': - case ':': + case ':': return; - - } -} + + } +} if (optind>=argc) { - printf("\n - Не указано имя файла загрузчика\n"); + printf("\n - Loader file name is not specified\n"); return; -} +} ldr=fopen(argv[optind],"r+b"); if (ldr == 0) { - printf("\n Ошибка открытия файла %s\n",argv[optind]); + printf("\n Can't open file %s\n",argv[optind]); return; } - -// Ищем таблицу разделов в файле загрузчика +// searching for the partition table in the loader file ptaddr=find_ptable(ldr); if (ptaddr == 0) { printf("\n Таблица разделов в загрузчике не найдена\n"); return ; } -// читаем текущую таблицу +// read the current table fread(&ptable,sizeof(ptable),1,ldr); if (xflag) { out=fopen("ptable.bin","wb"); fwrite(&ptable,sizeof(ptable),1,out); fclose(out); -} +} if (mflag) { show_map(ptable); @@ -103,24 +100,23 @@ if (mflag) { if (mflag | xflag) return; - -if (rflag) { +if (rflag) { in=fopen(ptfile,"rb"); if (in == 0) { - printf("\n Ошибка открытия файла %s",ptfile); + printf("\n Can't open file %s",ptfile); return; } fread(&ptable,sizeof(ptable),1,in); fclose(in); - - // проверяем файл + + // check the file if (memcmp(ptable.head,headmagic,16) != 0) { - printf("\n Входной файл не является таблицей разделов\n"); + printf("\n Input file is not a partition table\n"); return; } fseek(ldr,ptaddr,SEEK_SET); fwrite(&ptable,sizeof(ptable),1,ldr); fclose(ldr); - -} + +} } diff --git a/ptable-list.c b/ptable-list.c index 176d5d6..9aaaf8c 100644 --- a/ptable-list.c +++ b/ptable-list.c @@ -1,6 +1,5 @@ -// Программа для замены таблицы разделов в загрузчике usbloader -// -// +// Program to replace the partition table in the usbloader +// #include #include @@ -18,35 +17,32 @@ #include "parts.h" - //############################################################################################################3 void main(int argc, char* argv[]) { - - struct ptable_t ptable; FILE* in; if (argc != 2) { - printf("\n - Не указано имя файла с таблицей разделов\n"); + printf("\n - Partition table file name is not specified\n"); return; -} +} in=fopen(argv[optind],"r+b"); if (in == 0) { - printf("\n Ошибка открытия файла %s\n",argv[optind]); + printf("\n Can't open file %s\n",argv[optind]); return; } - -// читаем текущую таблицу + +// read current table fread(&ptable,sizeof(ptable),1,in); if (strncmp(ptable.head, "pTableHead", 16) != 0) { - printf("\n Файл не является таблицей разделов\n"); + printf("\n File is not a partition table\n"); return ; } - + show_map(ptable); }