📄 load_file.c
字号:
/* * vivi/lib/load-file.c: Load a file via serial or usb. * * Copyright (C) 2002 MIZI Research, Inc. * * Author : Janghoon Lyu <nandy@mizi.com> * Date : $Date: 2004/05/07 02:22:39 $ * * $Revision: 1.7 $ * * History * * 2002-06-27: Janghoon Lyu <nandy@mizi.com> * - Initial code * * 2002-07-29: Janghoon Lyu <nandy@mizi.com> * - download_file()俊辑 modem 急琶且 锭狼 滚弊 荐沥. * * 2002-10-22: Janghoon Lyu <nandy@mizi.com> * - Simpify functions related to a load command. * * TODO: * 1. default modem捞扼绰 VIVI 颇扼固磐啊 鞘夸且鳖夸? */#include <config.h>#include <machine.h>#include <memory.h>#include <command.h>#include <mtd/mtd.h>#include <mtd/partitions.h>#include <serial.h>#include <vstring.h>#include <md5.h>#include <param.h>#include <xmodem.h>#include <ymodem.h>#include <net/net.h>#include <irq.h>#define LOAD_TO_FLASH 1#define LOAD_TO_RAM 2static char *buf = NULL;static char *part_name = NULL;static int target_mt;static unsigned long offset, size, dn_size;static int bpn; static char sign_str[5]; /* for Mobile DiskOnChip Plus */static int modem;static int flag;static intwhat_is_target(const char *mt){ if (strncmp(mt, "ram", 3) == 0) { return LOAD_TO_RAM; } else if (strncmp(mt, "flash", 5) == 0) { return LOAD_TO_FLASH; } else { return -1; }}static int modem_is(const char *mt){ if (strncmp("x", mt, 1) == 0) { return X_MODEM; } else if (strncmp("y", mt, 1) == 0) { return Y_MODEM; } else if (strncmp("z", mt, 1) == 0) { return Z_MODEM; } else if (strncmp("tftp", mt, 3) == 0) { return TFTP_ETHER; } else { return UNKNOWN_MODEM; }}static voidshow_usage(void){ printk("load [OPTIONS] -- load an image to flash or ram\n\n"); printk(" to=<flash|ram>\n"); printk(" where to load\n"); printk(" pn=<name>\n"); printk(" Use information of partition table\n"); printk(" ofs=<address>\n"); printk(" Set offset\n"); printk(" sz=<size>\n"); printk(" Set size to be loaded\n"); printk(" bpn=<number>\n"); printk(" If you have MDOCP, set binary partition number\n"); printk(" sign=<signature>\n"); printk(" If you have MDOCP, set signature\n"); printk(" flag=<flag>\n"); printk(" set partition's flag\n"); printk(" modem=<x|y|tftp>\n"); printk(" Select transfer protocol if possible\n");}static intparsing_argument(int argc, const char *argv[]){ int i; /* Initialize variables */ target_mt = LOAD_TO_FLASH; offset = (RAM_BASE + 0x8000); part_name = NULL; size = 0; bpn = 0; sign_str[0] = '\0'; modem = Y_MODEM; //for (i = 1; argv[i] != NULL; i++) { for (i = 1; i < argc; i++) { char *p = NULL; char sbuf[128]; int slen = 0; p = strchr(argv[i], '='); p++; slen = strlen(p); strncpy((char *)(&sbuf[0]), p, slen); sbuf[slen] = '\0'; if (strncmp(argv[i], "pn=", 3) == 0) {#ifdef CONFIG_MTD mtd_partition_t *partbuf; printk("Upadte %s partition\n", sbuf); partbuf = get_mtd_partition(sbuf); if (partbuf == NULL) { printk("Could not found \"%s\" partition\n", sbuf); return -1; } part_name = partbuf->name; offset = partbuf->offset; size = partbuf->size; flag = partbuf->flag;#endif } else if (strncmp(argv[i], "flag=", 5) == 0) { flag = (int)simple_strtoul(sbuf, NULL, 0); } else if (strncmp(argv[i], "to=", 3) == 0) { target_mt = what_is_target(sbuf); } else if (strncmp(argv[i], "ofs=", 4) == 0) { offset = simple_strtoul(sbuf, NULL, 0); } else if (strncmp(argv[i], "sz=", 3) == 0) { size = simple_strtoul(sbuf, NULL, 0); } else if (strncmp(argv[i], "bpn=", 4) == 0) { bpn = simple_strtoul(sbuf, NULL, 0); } else if (strncmp(argv[i], "sign=", 5) == 0) { strncpy(sign_str, sbuf, 5); } else if (strncmp(argv[i], "modem=", 6) == 0) { modem = modem_is(sbuf); } else if (strncmp(argv[i], "help", 4) == 0) { show_usage(); return 1; } else { show_usage(); return 1; } } switch (target_mt) { case LOAD_TO_FLASH: if ((size == 0) || (target_mt < 0)) { printk("Error: Wrong arguments\n"); show_usage(); return 1; } break; case LOAD_TO_RAM: if (size == 0) size = RAM_SIZE; break; } printk("Load to offset = 0x%08lx, size = 0x%08lx at %s\n", offset, size, (target_mt == LOAD_TO_RAM) ? "ram" : "flash"); return 0;}static size_tdownload_file(char *name){ size_t ret; switch (modem) { case X_MODEM:#ifdef CONFIG_SERIAL_XMODEM printk("Ready for downloading using xmodem...\n"); printk("Waiting...\n"); ret = xmodem_receive(buf, size);#else printk("Not support XMODEM protocol by this vivi\n"); ret = 0;#endif break; case Y_MODEM:#ifdef CONFIG_SERIAL_YMODEM printk("Ready for downloading using ymodem...\n"); printk("Waiting...\n"); ret = ymodem_receive(buf, size, name); if (ret > 0) { check_md5sum(buf, ret, name); }#else printk("Not support YMODEM protocol by this vivi\n"); ret = 0;#endif break; case Z_MODEM: printk("Not support zmodem yet.\n"); ret = 0; break; case TFTP_ETHER: {#ifdef CONFIG_NET char tmp_tftp_file_name[64] = {0,}; strncpy(&tmp_tftp_file_name[0], part_name, 60); strcat (&tmp_tftp_file_name[0],".img"); ret = tftp_ether_receive(buf, size, &tmp_tftp_file_name[0]); if (ret > 0) { printk("\n"); check_md5sum(buf, ret, &tmp_tftp_file_name[0]); } printk("\n");#else printk("Not support TFTP protocol via Ethernet by this vivi\n"); ret = 0;#endif } break; default: printk("Not support this protocol\n"); ret = 0; break; } /* hacked by nandy. delay for serial output */ { int i = 0x50000; while (i > 0) i--; } if (ret == 0) { printk("Failed downloading file\n"); return ret; } printk("Downloaded file at 0x%08lx, size = %d bytes\n", buf, ret); return ret;}static intload_to_ram(void){ char file_name[255] = { 0, }; buf = (char *)offset; /* download a file */ dn_size = 0; dn_size = download_file(file_name); if (dn_size == 0) { return -1; } return 0;}static intload_to_flash(void){ int ret = 1; char file_name[255] = { 0, }; if (flag & MF_RAM) { printk("Ooops, actually this partition is ram. It's tweak...!\n"); return load_to_ram(); }#ifdef CONFIG_MTD if (!mymtd) { printk("The vivi doesn't have MTD information\n"); return 1; } /* download a file */ buf = (char *)RAM_BASE; dn_size = 0; dn_size = download_file(file_name); if (dn_size == 0) { return 1; } if (dn_size > size) { printk("An image size is too large to write flash." "wanted = 0x%08lx, loaded = 0x%08lx\n", size, dn_size); return 1; } disable_irq(); switch (mymtd->type) { case MTD_NORFLASH: case MTD_NANDFLASH: case MTD_MDOC: ret = mtd_write_part(part_name, buf, dn_size); break; default: break; } enable_irq();#endif return ret;}void command_load(int argc, const char **argv){ int ret; /* fake */ if (strncmp(argv[1], "flash", 5) == 0) { char *fargv[3]; char cmd[3][16]; strcpy(cmd[0], argv[0]); cmd[0][strlen(argv[0])] = '\0'; strcpy(cmd[1], "pn="); strcat(cmd[1], argv[2]); strcpy(cmd[2], "modem="); strcat(cmd[2], argv[3]); fargv[0] = (char *)&cmd[0]; fargv[1] = (char *)&cmd[1]; fargv[2] = (char *)&cmd[2]; argc = 3; /* Parse arguments */ if (parsing_argument(argc, (const char **)fargv)) { return; } } else { /* Parse arguments */ if (parsing_argument(argc, argv)) { return; } } switch (target_mt) { case LOAD_TO_FLASH: ret = load_to_flash(); break; case LOAD_TO_RAM: ret = load_to_ram(); break; default: printk("Fatal error: Wrong place\n"); return; } if (ret) printk("failed downloading.\n"); return;}user_command_t load_cmd = { "load", command_load, NULL};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -