diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..28c32e2 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CC = gcc +LIBS = +CFLAGS = -O2 -g -Wno-unused-result + +.PHONY: all clean + +all: balong-usbdload + +clean: + rm *.o + rm balong-usbdload + +#.c.o: +# $(CC) -o $@ $(LIBS) $^ qcio.o + +balong-usbdload: balong-usbdload.o + @gcc $^ -o $@ $(LIBS) diff --git a/balong-usbdload.c b/balong-usbdload.c new file mode 100644 index 0000000..16176f8 --- /dev/null +++ b/balong-usbdload.c @@ -0,0 +1,236 @@ +// Загрузчик usbloader.bin через аварийный порт для модемов на платформе Balong V7R2. +// +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int siofd; +FILE* ldr; + + +//************************************************* +//* HEX-дамп области памяти * +//************************************************* + +void dump(unsigned char buffer[],int len) { +int i,j; +unsigned char ch; + +printf("\n"); +for (i=0;i 0x7e)&&(ch<0xc0))) putchar('.'); + else putchar(ch); + } + // заполнение пробелами для неполных строк + else printf(" "); + } + printf("*\n"); + } +} + + +//************************************************* +//* Рассчет контрольной суммы командного пакета +//************************************************* +void csum(unsigned char* buf, int len) { + +unsigned int i,c,csum=0; + +unsigned int cconst[]={0,0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF}; + +for (i=0;i<(len-2);i++) { + c=(buf[i]&0xff); + csum=((csum<<4)&0xffff)^cconst[(c>>4)^(csum>>12)]; + csum=((csum<<4)&0xffff)^cconst[(c&0xf)^(csum>>12)]; +} +buf[len-2]=(csum>>8)&0xff; +buf[len-1]=csum&0xff; + +} + +//************************************************* +//* Отсылка командного пакета модему +//************************************************* +int sendcmd(unsigned char* cmdbuf, int len) { + +unsigned char replybuf[1024]; +unsigned int replylen; + +csum(cmdbuf,len); +write(siofd,cmdbuf,len); // отсылка команды +tcdrain(siofd); +replylen=read(siofd,replybuf,1024); +if ((replylen == 0) || (replybuf[0] == 0xaa)) return 1; +return 0; +} + + + + + + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +void main(int argc, char* argv[]) { + +struct termios sioparm; +char* lptr; +unsigned int i,res,opt,datasize,pktcount,adr; +int nblk; // число блоков для загрузки +int bl; // текущий блок + +unsigned char cmdhead[14]={0xfe,0, 0xff}; +unsigned char cmddata[1040]={0xda,0,0}; +unsigned char cmdeod[5]={0xed,0,0,0,0}; + +struct { + int lmode; // режим загрузки: 1 - прямой старт, 2 - через перезапуск A-core + int size; // размер блока + int adr; // адрес загрузки блока в память + int offset; // смещение до блока от начала файла +} blk[10]; + +unsigned char devname[50]="/dev/ttyUSB0"; + +while ((opt = getopt(argc, argv, "hp:sa:")) != -1) { + switch (opt) { + case 'h': + +printf("\n Утилита предназначена для аварийной USB-загрузки модемов E3372S\n\n\ +%s [ключи] <имя файла для загрузки>\n\n\ + Допустимы следующие ключи:\n\n\ +-p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0\n\ +\n",argv[0]); + return; + + case 'p': + strcpy(devname,optarg); + break; + + } +} + +if (optind>=argc) { + printf("\n - Не указано имя файла для загрузки\n"); + return; +} + +// Настройка SIO +siofd = open(devname, O_RDWR | O_NOCTTY |O_SYNC); +if (siofd == -1) { + printf("\n - Последовательный порт %s не открывается\n", argv[1]); + return; + } + + +bzero(&sioparm, sizeof(sioparm)); +sioparm.c_cflag = B115200 | CS8 | CLOCAL | CREAD; +sioparm.c_iflag = 0; // INPCK; +sioparm.c_oflag = 0; +sioparm.c_lflag = 0; +sioparm.c_cc[VTIME]=1; // таймаут +sioparm.c_cc[VMIN]=1; // 1 байт минимального ответа + +tcsetattr(siofd, TCSANOW, &sioparm); +tcflush(siofd,TCIOFLUSH); // очистка выходного буфера + + +ldr=fopen(argv[optind],"r"); +if (ldr == 0) { + printf("\n Ошибка открытия %s",argv[optind]); + return; +} + +// Прверяем сигнатуру usloader +fread(&i,1,4,ldr); +if (i != 0x20000) { + printf("\n Файл %s не является загрузчиком usbloader\n",argv[optind]); + return; +} + +fseek(ldr,36,SEEK_SET); // начало описателей блоков для загрузки + +// Разбираем заголовок + +for(nblk=0;nblk<10;nblk++) { + fread(&blk[nblk].lmode,1,4,ldr); + fread(&blk[nblk].size,1,4,ldr); + fread(&blk[nblk].adr,1,4,ldr); + fread(&blk[nblk].offset,1,4,ldr); + if (blk[nblk].lmode == 0) break; +} +printf("\n Найдено %i блоков для загрузки",nblk); + +// главный цикл загрузки - загружаем все блоки, найденные в заголовке + +for(bl=0;bl=blk[bl].size) datasize=blk[bl].size-adr; + fprintf(stderr,"\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize); + + // читаем порцию данных + if (datasize != fread(cmddata+3,1,datasize,ldr)) { + printf("\n Неожиданный конец файла\n"); + return; + } + + // готовим пакет данных + cmddata[1]=pktcount; + cmddata[2]=(~pktcount)&0xff; + pktcount++; + if (!sendcmd(cmddata,datasize+5)) { + printf("\nМодем отверг пакет данных\nОбраз пакета:"); + dump(cmddata,datasize+5); + return; + } + } + + // Фрмируем пакет конца данных + cmdeod[1]=pktcount; + cmdeod[2]=(~pktcount)&0xff; + + if (!sendcmd(cmdeod,5)) { + printf("\nМодем отверг пакет конца данных\nОбраз пакета:"); + dump(cmdeod,5); + } +} +printf("\n Загрузка окончена\n"); +} + +