/************************************************************/ /* Spidcom Technologies FILE NAME : commands.c DESCRIPTION : command file HISTORY : -------------------------------------------------------------- DATE | AUTHOR | Version | Description -------------------------------------------------------------- 27/01/04 | Petillon | 1.0 | Creation */ /************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "mtd_part.h" #include "image_table.h" #include void bb_error_msg_and_die(const char *s, ...) { va_list p; va_start(p, s); vfprintf(stderr, s, p); va_end(p); putc('\n', stderr); exit(1); } int plc_system_led(int value) { #ifdef SP_CRISTINA ApGpio_dev_t *ApGpio_dev = (ApGpio_dev_t *) GPIO_BASE; if (value) { ApGpio_dev->GPIO_15_8.data_out |= (1<<5) ; } else { ApGpio_dev->GPIO_15_8.data_out &= (~(1<<5)); } ApGpio_dev->GPIO_15_8.direction = 0; #endif return 0; } static int bt_image_secure_write(image_desc_t *img, int fd, ssize_t count, unsigned char *md) { int len; MD5_CTX c; unsigned char md5[16]; unsigned char buf[4096]; /* Write file to flash memory */ lseek(fd, 0, SEEK_SET); plc_system_led(1); if(bb_copyfd_mem(fd, img->storage_address, count) < 0) bb_error_msg_and_die("bb_copyfd_mem error"); /* Check md5 */ MD5_Init(&c); lseek(fd, 0, SEEK_SET); for(; count > 0; count -= len){ len = read(fd, buf, sizeof(buf)); /* Update md5 here */ MD5_Update(&c, buf, (len < count ? len : count)); } /* Final check */ MD5_Final(md5, &c); if(!!memcmp(md5, md, sizeof(md5))) return -1; return 0; } static int bt_image_secure_init(image_desc_t *img, void *load_addr, size_t count, void *entry_point, void *store_addr, const char *format) { /* Default init */ #ifdef SP_LISA img->load_address = (caddr_t)0xB0400000; img->entry_point = (caddr_t)0xB0400000; #else img->load_address = (caddr_t)0x70400000; img->entry_point = (caddr_t)0x70400000; #endif img->storage_address = (caddr_t)0x0; img->compressed = 0; img->format = iBin; img->size = 0; /* Optional init */ if(load_addr) img->load_address = (caddr_t)load_addr; if(count) img->size = count; if(entry_point) img->entry_point = (caddr_t)entry_point; if(store_addr) img->storage_address = (caddr_t)store_addr; if(!strcmp(format, "elf")){ #ifdef SP_LISA img->entry_point = (caddr_t)0xB0008000; #else img->entry_point = (caddr_t)0x70008000; #endif img->compressed = 1; img->format = iElf; } /* Check struct coherency */ if(img->storage_address && (img->storage_address < available_flash_base() || img->storage_address >= available_flash_base()+available_flash_size())){ printf("Invalid storage address 0x%.8lx\n", (ulong)img->storage_address); return -1; } if(img->format == iBin && !img->entry_point){ printf("Error: invalid image format, or binary without entry point.\n" \ "Supported formats are: hex, gz-hex, elf, gz-elf.\n"); return -1; } return 0; } int images(int argc, char **argv) { const char *image_name; image_desc_t image_desc; int selected, i; /* printf("Flash memory: 0x%.8lx-0x%.8lx (%lu MB).\n",*/ /* (unsigned long)FLASH_BASE,(unsigned long)FLASH_BASE+FLASH_SIZE-1,(FLASH_SIZE/1024)/1024);*/ printf("Area available for images: 0x%.8lx-0x%.8lx.\n", (unsigned long)available_flash_base(),(unsigned long)available_flash_base()+available_flash_size()-1); printf("\n"); if (!table_is_setup()) { printf("Error: Table not set-up or corrupted.\n\n"); return -1; } image_name = next_entry((char*)0x0); if (!image_name) printf("No images stored in table.\n\n"); else { printf("Images:\n\n"); printf("%-16s %-21s %-8s %-10s %-10s %-6s %s\n", "Name","Flash Area","Size(B)","Address","Entry","Format","S"); printf("\n"); while (image_name) { get_entry(image_name, &image_desc, &selected); if (image_desc.format==iBin) printf("%-16s 0x%.8lx-0x%.8lx %8lu 0x%.8lx 0x%.8lx %-6s %c\n", image_name, (unsigned long)image_desc.storage_address, (unsigned long)image_desc.storage_address+image_desc.size-1, (unsigned long)image_desc.size, (unsigned long)image_desc.load_address, (unsigned long)image_desc.entry_point, format_string(image_desc.compressed,image_desc.format), selected?'X':' '); else if (image_desc.format==iElf) printf("%-16s 0x%.8lx-0x%.8lx %8lu 0x%.8lx %-6s %c\n", image_name, (unsigned long)image_desc.storage_address, (unsigned long)image_desc.storage_address+image_desc.size-1, (unsigned long)image_desc.size, (unsigned long)image_desc.entry_point, format_string(image_desc.compressed,image_desc.format), selected?'X':' '); else // iHex printf("%-16s 0x%.8lx-0x%.8lx %8lu %-6s %c\n", image_name, (unsigned long)image_desc.storage_address, (unsigned long)image_desc.storage_address+image_desc.size-1, (unsigned long)image_desc.size, format_string(image_desc.compressed,image_desc.format), selected?'X':' '); image_name = next_entry(image_name); } printf("\n"); } return 0; } int create(int argc, char **argv) { image_desc_t image_desc; char *name; int v; char c; int addset; int entryset; char ftpIp[18]; char remoteFile[255]; sigset_t sigset; if (argc<4) { printf("%s [options] \n",argv[0]); return -1; } if (!table_is_setup()) { printf("Error: Table not set-up or corrupted.\n\n"); return -1; } name = argv[1]; if (!check_image_name(name)) printf("Error: invalid image name \"%s\". Image name must be [a-zA-Z0-9][a-zA-Z0-9-_.]*.\n",name); else if (get_entry(name,&image_desc,&v)>=0) printf("Error: name \"%s\" already used.\n",name); else { argc -= 1; argv += 1; #ifdef SP_LISA image_desc.load_address = (caddr_t)0xB0400000; image_desc.entry_point = (caddr_t)0xB0400000; #else image_desc.load_address = (caddr_t)0x70400000; image_desc.entry_point = (caddr_t)0x70400000; #endif image_desc.size = 0; image_desc.storage_address = (caddr_t)0x0; image_desc.format = iBin; image_desc.compressed = 0; addset = 1; entryset = 1; while ((v=getopt(argc, argv, "a:l:e:f:t:"))!=-1) { c = (char) v; switch (c) { case 'a': image_desc.load_address = (caddr_t)strtoul(optarg,NULL,0); addset = 1; break; case 'l': image_desc.size = strtoul(optarg,NULL,0); break; case 'e': image_desc.entry_point = (caddr_t)strtoul(optarg,NULL,0); entryset = 1; break; case 'f': image_desc.storage_address = (caddr_t)strtoul(optarg,NULL,0); break; case 't': if(!strcmp(optarg,"elf")) { image_desc.format = iElf; #ifdef SP_LISA image_desc.entry_point = (caddr_t)0xB0008000; #else image_desc.entry_point = (caddr_t)0x70008000; #endif image_desc.compressed = 1; } break; default: /* display_usage("createraw");*/ return -1; break; } } argc -= optind; argv += optind; if (argc<2) { printf("%s [options] \n",argv[0]); return -1; } strcpy(ftpIp,argv[0]); strcpy(remoteFile,argv[1]); printf("Now creating image %s from FTP server %s from file %s\n",name,ftpIp,remoteFile); if (image_desc.storage_address!=0x0 && (image_desc.storage_address=available_flash_base()+available_flash_size())) { printf("Invalid storage address 0x%.8lx\n",(unsigned long)image_desc.storage_address); return -1; } if ((!addset && entryset) || (addset && !entryset)) { printf("%s:%d\n",__FILE__,__LINE__); return -1; } if (image_desc.format==iBin && !entryset) { printf("Error: invalid image format, or binary without entry point.\n" "Supported formats are: hex, gz-hex, elf, gz-elf.\n"); /* boottable_clean(buffer);*/ return -1; } /* Critical section : ignore SIGINT */ sigaddset (&sigset, SIGINT); sigprocmask (SIG_BLOCK, &sigset, NULL); ftp_main(ftpIp, remoteFile, &image_desc, name); plc_system_led(1); } return 0; } int erase(int argc, char **argv) { if (argc<2) return -1; else { if (remove_entry(argv[1])<0) printf("Error: %s.\n",image_table_error()); } return 0; } int bootrename(int argc, char **argv) { if (argc<3) return -1; else { if (rename_entry(argv[1],argv[2])<0) printf("Error: %s.\n",image_table_error()); } return 0; } int secure_create(int argc, char **argv) { int fd; time_t t; char *name; char md5[16]; sigset_t sigset; image_desc_t img; int len, n = 3, v, i; int already_exist = false; if(argc < 5){ printf("%s \n", argv[0]); return -1; } if(!table_is_setup()){ printf("Error: Table not set-up or corrupted.\n\n"); return -1; } if(!check_image_name(argv[1])) printf("Error: invalid image name \"%s\"." \ "Image name must be [a-zA-Z][a-zA-Z0-9-_.]*.\n", argv[1]); bt_image_secure_init(&img, NULL, 0, NULL, NULL, "bin"); printf("Now creating image %s from FTP server %s from file %s\n", argv[1], argv[2], argv[3]); if((fd = open("/tmp/secure_image", O_RDWR | O_CREAT | O_TRUNC)) != -1){ /* Receive file */ img.size = ftp_secure_main(argv[2], argv[3], argv[4], fd, md5); /* Time measure */ t = time (NULL); /* Critical section : ignore SIGINT */ sigaddset (&sigset, SIGINT); sigprocmask (SIG_BLOCK, &sigset, NULL); /* Erase current flash bank */ if((name = (char*)get_selected_name()) != NULL && remove_entry(name) < 0) bb_error_msg_and_die("Error: %s\n", image_table_error()); /* Don't know why, but this is needed */ if(test_add_entry(argv[1], &img) < 0) bb_error_msg_and_die("Error: %s\n", image_table_error()); while(n--){ /* Write file to flash */ if(bt_image_secure_write(&img, fd, img.size, md5) != -1){ printf("Updating table in flash memory...\n"); if(add_entry(argv[1], &img) < 0) bb_error_msg_and_die("Error: %s\n", image_table_error()); printf("Created image \"%s\" in %d secs\n", argv[1], time (NULL) - t); close(fd); return 0; } } close(fd); } printf("Unable to write image to flash\n"); return -1; }