From 9a26a0be0271ef6767a53992971dc706af14f128 Mon Sep 17 00:00:00 2001 From: forth32 Date: Thu, 9 Apr 2015 08:55:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BE=D1=81=D0=BC=D0=B5=D1=82=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- balong_flash.c | 272 +++++++++++++++++++++++++++++++++---------------- hdlcio.c | 84 ++++++++++++++- 2 files changed, 267 insertions(+), 89 deletions(-) diff --git a/balong_flash.c b/balong_flash.c index 149c4cc..afafb24 100644 --- a/balong_flash.c +++ b/balong_flash.c @@ -11,19 +11,63 @@ #include "hdlcio.h" +//****************************************************** +//* поиск символического имени раздела по его коду +//****************************************************** + +void find_pname(unsigned int id,unsigned char* pname) { + +unsigned int j; +struct { + char name[20]; + int code; +} pcodes[]={ + {"M3Boot",0x20000}, + {"M3Boot_R11",0x200000}, + {"Ptable",0x10000}, + {"Fastboot",0x110000}, + {"Kernel",0x30000}, + {"Kernel_R11",0x90000}, + {"VxWorks",0x40000}, + {"VxWorks_R11",0x220000}, + {"M3Image",0x50000}, + {"M3Image_R11",0x230000}, + {"DSP",0x60000}, + {"DSP_R11",0x240000}, + {"NVRAM",0x70000}, + {"NVRAM_R11",0x250000}, + {"System",0x590000}, + {"APP",0x5a0000}, + {"CD_WUI_VER",0xa0000}, + {"CDROMISO",0xb0000}, + {"WEBUI",0x5b0000}, + {0,0} +}; + +for(j=0;pcodes[j].code != 0;j++) { + if(pcodes[j].code == id) break; +} +if (pcodes[j].code != 0) strcpy(pname,pcodes[j].name); // имя найдено - копируем его в структуру +else sprintf(pname,"U%08x",id); // имя не найдено - подставляем псевдоимя Uxxxxxxxx в тупоконечном формате +} + + //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void main(int argc, char* argv[]) { -struct termios sioparm; unsigned int i,j,res,opt,npart=0,iolen,part,blk,blksize; FILE* in; FILE* out; struct { - unsigned int offset; - unsigned int size; - unsigned int code; + unsigned int offset; // позиция образа раздела + unsigned int hdoffset; // позиция заголовка раздела + unsigned int size; // размер образа раздела + unsigned int hdsize; // размер заголовка раздела + unsigned int code; // ID раздела + unsigned char pname[20]; // буквенное имя раздела + unsigned char filename[50]; // имя файла, соответствующее разделу }ptable[100]; unsigned char buf[4096]; @@ -36,9 +80,11 @@ unsigned char OKrsp[]={0x0d, 0x0a, 0x4f, 0x4b, 0x0d, 0x0a}; unsigned char NAKrsp[]={0x03, 0x00, 0x02, 0xba, 0x0a, 0x7e}; unsigned int dpattern=0xa55aaa55; -unsigned int mflag=0,eflag=0,rflag=0; +unsigned int mflag=0,eflag=0,rflag=0,sflag=0,nflag=0; unsigned char filename [100]; +unsigned char fdir[40]; // каталог для мультифайловой прошивки + unsigned char cmdver[7]={0x0c}; // версия протокола unsigned char cmddone[7]={0x1}; // команда выхода из HDLC unsigned char cmd_reset[7]={0xa}; // команда выхода из HDLC @@ -46,38 +92,21 @@ unsigned char cmd_dload_init[15]={0x41}; // команда начала раз unsigned char cmd_data_packet[11000]={0x42}; // команда начала пакета unsigned char cmd_dload_end[30]={0x43}; // команда конца раздела // Коды типов разделов -struct { - char name[20]; - int code; -} pcodes[]={ - {"M3Boot",0x20000}, - {"Ptable",0x10000}, - {"Fastboot",0x110000}, - {"Kernel",0x30000}, - {"VxWorks",0x40000}, - {"M3Image",0x50000}, - {"DSP",0x60000}, - {"NVRAM",0x70000}, - {"System",0x590000}, - {"APP",0x5a0000}, - {"CD_WUI_VER",0xa0000}, - {"CDROMISO",0xb0000}, - {"WEBUI",0x5b0000}, - {0,0} -}; //-d - попытка переключить модем из режима HDLC в АТ-режим\n\ -while ((opt = getopt(argc, argv, "hp:mer")) != -1) { +while ((opt = getopt(argc, argv, "hp:mersn")) != -1) { switch (opt) { case 'h': -printf("\n Утилита предназначена для аварийной USB-загрузки модемов E3372S\n\n\ -%s [ключи] <имя файла для загрузки>\n\n\ +printf("\n Утилита предназначена для прошивки модемов E3372S\n\n\ +%s [ключи] <имя файла для загрузки или имя каталога с файлами>\n\n\ Допустимы следующие ключи:\n\n\ --p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0\n\ +-p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0)\n\ +-n - режим мультифайловой прошивки из указанного каталога\n\ -m - вывести карту файла прошивки и завершить работу\n\ --e - разобрать файл прошивки на разделы и завершить работу\n\ --r - перезагрузить модем после прошивки\n\ +-e - разобрать файл прошивки на разделы без заголовков\n\ +-s - разобрать файл прошивки на разделы с заголовками\n\ +-r - выйти из режима прошивки и перезагрузить модем\n\ \n",argv[0]); return; @@ -89,6 +118,10 @@ printf("\n Утилита предназначена для аварийной U mflag=1; break; + case 'n': + nflag=1; + break; + case 'r': rflag=1; break; @@ -97,73 +130,127 @@ printf("\n Утилита предназначена для аварийной U eflag=1; break; + case 's': + sflag=1; + break; + case '?': case ':': return; } } +if (eflag&sflag) { + printf("\n Ключи -s и -e несовместимы\n"); + return; +} + +if (nflag&(eflag|sflag|mflag)) { + printf("\n Ключ -n несовместим с ключами -s, -m и -e\n"); + return; +} + + +// ------ перезагрузка без указания файла +//-------------------------------------------- +if ((optind>=argc)&rflag) goto sio; + + +// Открытие входного файла +//-------------------------------------------- if (optind>=argc) { + if (nflag) + printf("\n - Не указан каталог с файлами\n"); + else printf("\n - Не указано имя файла для загрузки\n"); - return; + return; } +if (nflag) + // для -n - просто копируем префикс + strncpy(fdir,argv[optind],39); +else { + // для однофайловых операций in=fopen(argv[optind],"r"); if (in == 0) { printf("\n Ошибка открытия %s",argv[optind]); return; } +} + // Поиск разделов внутри файла -printf("\n Разбираем файл прошвки..."); -while (fread(&i,1,4,in) == 4) { - if (i != dpattern) continue; // ищем разделитель - ptable[npart].offset=ftell(in); // позиция начала раздела - fread(buf,1,96,in); // заголовок - ptable[npart].offset+=*((unsigned int*)&buf[0])-4; // выкидываем из смещения длину заголовка+КС - ptable[npart].size=*((unsigned int*)&buf[20]); // размер раздела - ptable[npart].code=*((unsigned int*)&buf[16]); // тип раздела - npart++; -} -if (npart == 0) { - printf("\nРазделы не найдены!"); - return ; +//-------------------------------------------- + +if (!nflag) { + printf("\n Разбираем файл прошвки..."); + while (fread(&i,1,4,in) == 4) { + if (i != dpattern) continue; // ищем разделитель + + // Выделяем параметры раздела + ptable[npart].hdoffset=ftell(in); // позиция начала заголовка раздела + fread(buf,1,96,in); // заголовок + ptable[npart].hdsize=*((unsigned int*)&buf[0])-4; // размер заголовка + ptable[npart].offset=ptable[npart].hdoffset+ptable[npart].hdsize; // смещение до тела раздела + ptable[npart].size=*((unsigned int*)&buf[20]); // размер раздела + ptable[npart].code=*((unsigned int*)&buf[16]); // тип раздела + + // Ищем символическое имя раздела по таблице + find_pname(ptable[npart].code,ptable[npart].pname); + // увеличиваем счетчик разделов + npart++; + } + if (npart == 0) { + printf("\nРазделы не найдены!"); + return ; + } } -printf(" найдено %i разделов",npart); -//------ Режим вывода карты файла прошивки +// Поиск файлов прошивок в указанном каталоге +//-------------------------------------------- +else { + printf("\n Поиск файлов-образов разделов...\n\n ## Размер ID Имя Файл\n-----------------------------------------------------------------\n"); + for (npart=0;npart<30;npart++) { + if (find_file(npart, fdir, ptable[npart].filename, &ptable[npart].code, &ptable[npart].size) == 0) break; // конец поиска - раздела с таким ID не нашли + // получаем символическое имя раздела + find_pname(ptable[npart].code,ptable[npart].pname); + printf("\n %02i %8i %08x %-8.8s %s",npart,ptable[npart].size,ptable[npart].code,ptable[npart].pname,ptable[npart].filename); + } +} + +printf("\n Найдено %i разделов",npart); + + +//------ Режим вывода карты файла прошивки +//-------------------------------------------- + if (mflag) { printf("\n Таблица разделов, найденных в файле:\n\n ## Смещение Размер Имя\n-------------------------------------"); - for (i=0;i=argc)&rflag) goto reset; // перезагрузка без указания файла // Главный цикл записи разделов for(part=0;part #include "printf.h" #endif - +#include #include "hdlcio.h" unsigned int nand_cmd=0x1b400000; @@ -343,3 +343,85 @@ sioparm.c_cc[VMIN]=0; tcsetattr(siofd, TCSANOW, &sioparm); #endif } + +//************************************************* +//* Поиск файла по номеру в указанном каталоге +//* +//* num - # файла +//* filename - буфер для полного имени файла +//* id - переменная, в которую будет записан идентификатор раздела +//* +//* return 0 - не найдено +//* 1 - найдено +//************************************************* +int find_file(int num, char* dirname, char* filename,unsigned int* id, unsigned int* size) { + +DIR* fdir; +FILE* in; +unsigned int pt; +struct dirent* dentry; +char fpattern[5]; + +sprintf(fpattern,"%02i",num); // образец для поиска файла по 3 цифрам номера +fdir=opendir(dirname); +if (fdir == 0) { + printf("\n Каталог %s не открывается\n"); + exit(1); +} + +// главный цикл - поиск нужного нам файла +while ((dentry=readdir(fdir)) != 0) { + if (dentry->d_type != DT_REG) continue; // пропускаем все кроме регулярных файлов + if (strncmp(dentry->d_name,fpattern,2) == 0) break; // нашли нужный файл. Точнее, файл с нужными 3 цифрами в начале имени. +} + +closedir(fdir); + +// формируем полное имя файла в буфере результата +if (dentry == 0) return 0; // не нашли +strcpy(filename,dirname); +strcat(filename,"/"); +// копируем имя файла в буфер результата +strcat(filename,dentry->d_name); + +// 00-00000200-M3Boot.bin +//проверяем имя файла на наличие знаков '-' +if ((dentry->d_name[2] != '-') || (dentry->d_name[11] != '-')) { + printf("\n Неправильный формат имени файла - %s\n",dentry->d_name); + exit(1); +} + +// проверяем цифровое поле ID раздела +if (strspn(dentry->d_name+3,"0123456789AaBbCcDdEeFf") != 8) { + printf("\n Ошибка в идентификаторе раздела - нецифрвой знак - %s\n",filename); + exit(1); +} +sscanf(dentry->d_name+3,"%8x",id); + +// Проверяем доступность и читаемость файла +in=fopen(filename,"r"); +if (in == 0) { + printf("\n Ошибка открытия файла %s\n",filename); + exit(1); +} +if (fread(&pt,1,4,in) != 4) { + printf("\n Ошибка чтения файла %s\n",filename); + exit(1); +} + +// проверяем, что файл - сырой образ, без заголовка +if (pt == 0xa55aaa55) { + printf("\n Файл %s имеет заголовок - для прошивки не подходит\n",filename); + exit(1); +} + + +// Что еще можно проверить? Пока не придумал. + +// Получаем размер файла +fseek(in,0,SEEK_END); +*size=ftell(in); +fclose(in); + +return 1; +}