📄 auto_update.c
字号:
/* * (C) Copyright 2003 * Gary Jennejohn, DENX Software Engineering, gj@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <common.h>#include <command.h>#include <malloc.h>#include <image.h>#include <asm/byteorder.h>#include <usb.h>#ifdef CFG_HUSH_PARSER#include <hush.h>#endif#ifdef CONFIG_AUTO_UPDATE#ifndef CONFIG_USB_OHCI#error "must define CONFIG_USB_OHCI"#endif#ifndef CONFIG_USB_STORAGE#error "must define CONFIG_USB_STORAGE"#endif#ifndef CFG_HUSH_PARSER#error "must define CFG_HUSH_PARSER"#endif#if !(CONFIG_COMMANDS & CFG_CMD_FAT)#error "must define CFG_CMD_FAT"#endif/* * Check whether a USB memory stick is plugged in. * If one is found: * 1) if prepare.img ist found load it into memory. If it is * valid then run it. * 2) if preinst.img is found load it into memory. If it is * valid then run it. Update the EEPROM. * 3) if firmw_01.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. * 4) if kernl_01.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. * 5) if app.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. * 6) if disk.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. * 7) if postinst.img is found load it into memory. If it is * valid then run it. Update the EEPROM. */#undef AU_DEBUG#undef debug#ifdef AU_DEBUG#define debug(fmt,args...) printf (fmt ,##args)#else#define debug(fmt,args...)#endif /* AU_DEBUG *//* possible names of files on the USB stick. */#define AU_PREPARE "prepare.img"#define AU_PREINST "preinst.img"#define AU_FIRMWARE "firmw_01.img"#define AU_KERNEL "kernl_01.img"#define AU_APP "app.img"#define AU_DISK "disk.img"#define AU_POSTINST "postinst.img"struct flash_layout{ long start; long end;};/* layout of the FLASH. ST = start address, ND = end address. */#ifndef CONFIG_FLASH_8MB /* 16 MB Flash, 32 MB RAM */#define AU_FL_FIRMWARE_ST 0x00000000#define AU_FL_FIRMWARE_ND 0x0009FFFF#define AU_FL_VFD_ST 0x000A0000#define AU_FL_VFD_ND 0x000BFFFF#define AU_FL_KERNEL_ST 0x000C0000#define AU_FL_KERNEL_ND 0x001BFFFF#define AU_FL_APP_ST 0x001C0000#define AU_FL_APP_ND 0x005BFFFF#define AU_FL_DISK_ST 0x005C0000#define AU_FL_DISK_ND 0x00FFFFFF#else /* 8 MB Flash, 32 MB RAM */#define AU_FL_FIRMWARE_ST 0x00000000#define AU_FL_FIRMWARE_ND 0x0005FFFF#define AU_FL_KERNEL_ST 0x00060000#define AU_FL_KERNEL_ND 0x0013FFFF#define AU_FL_APP_ST 0x00140000#define AU_FL_APP_ND 0x0067FFFF#define AU_FL_DISK_ST 0x00680000#define AU_FL_DISK_ND 0x007DFFFF#define AU_FL_VFD_ST 0x007E0000#define AU_FL_VFD_ND 0x007FFFFF#endif /* CONFIG_FLASH_8MB *//* a structure with the offsets to values in the EEPROM */struct eeprom_layout{ int time; int size; int dcrc;};/* layout of the EEPROM - offset from the start. All entries are 32 bit. */#define AU_EEPROM_TIME_PREINST 64#define AU_EEPROM_SIZE_PREINST 68#define AU_EEPROM_DCRC_PREINST 72#define AU_EEPROM_TIME_FIRMWARE 76#define AU_EEPROM_SIZE_FIRMWARE 80#define AU_EEPROM_DCRC_FIRMWARE 84#define AU_EEPROM_TIME_KERNEL 88#define AU_EEPROM_SIZE_KERNEL 92#define AU_EEPROM_DCRC_KERNEL 96#define AU_EEPROM_TIME_APP 100#define AU_EEPROM_SIZE_APP 104#define AU_EEPROM_DCRC_APP 108#define AU_EEPROM_TIME_DISK 112#define AU_EEPROM_SIZE_DISK 116#define AU_EEPROM_DCRC_DISK 120#define AU_EEPROM_TIME_POSTINST 124#define AU_EEPROM_SIZE_POSTINST 128#define AU_EEPROM_DCRC_POSTINST 132static int au_usb_stor_curr_dev; /* current device *//* index of each file in the following arrays */#define IDX_PREPARE 0#define IDX_PREINST 1#define IDX_FIRMWARE 2#define IDX_KERNEL 3#define IDX_APP 4#define IDX_DISK 5#define IDX_POSTINST 6/* max. number of files which could interest us */#define AU_MAXFILES 7/* pointers to file names */char *aufile[AU_MAXFILES];/* sizes of flash areas for each file */long ausize[AU_MAXFILES];/* offsets into the EEEPROM */struct eeprom_layout auee_off[AU_MAXFILES] = { \ {0}, \ {AU_EEPROM_TIME_PREINST, AU_EEPROM_SIZE_PREINST, AU_EEPROM_DCRC_PREINST,}, \ {AU_EEPROM_TIME_FIRMWARE, AU_EEPROM_SIZE_FIRMWARE, AU_EEPROM_DCRC_FIRMWARE,}, \ {AU_EEPROM_TIME_KERNEL, AU_EEPROM_SIZE_KERNEL, AU_EEPROM_DCRC_KERNEL,}, \ {AU_EEPROM_TIME_APP, AU_EEPROM_SIZE_APP, AU_EEPROM_DCRC_APP,}, \ {AU_EEPROM_TIME_DISK, AU_EEPROM_SIZE_DISK, AU_EEPROM_DCRC_DISK,}, \ {AU_EEPROM_TIME_POSTINST, AU_EEPROM_SIZE_POSTINST, AU_EEPROM_DCRC_POSTINST,} \ };/* array of flash areas start and end addresses */struct flash_layout aufl_layout[AU_MAXFILES - 3] = { \ {AU_FL_FIRMWARE_ST, AU_FL_FIRMWARE_ND,}, \ {AU_FL_KERNEL_ST, AU_FL_KERNEL_ND,}, \ {AU_FL_APP_ST, AU_FL_APP_ND,}, \ {AU_FL_DISK_ST, AU_FL_DISK_ND,}, \};/* convert the index into aufile[] to an index into aufl_layout[] */#define FIDX_TO_LIDX(idx) ((idx) - 2)/* where to load files into memory */#define LOAD_ADDR ((unsigned char *)0x0C100000)/* the app is the largest image */#define MAX_LOADSZ ausize[IDX_APP]/* externals */extern int fat_register_device(block_dev_desc_t *, int);extern int file_fat_detectfs(void);extern long file_fat_read(const char *, void *, unsigned long);extern int i2c_read (unsigned char, unsigned int, int , unsigned char* , int);extern int i2c_write (uchar, uint, int , uchar* , int);#ifdef CONFIG_VFDextern int trab_vfd (ulong);extern int transfer_pic(unsigned char, unsigned char *, int, int);#endifextern int flash_sect_erase(ulong, ulong);extern int flash_sect_protect (int, ulong, ulong);extern int flash_write (char *, ulong, ulong);/* change char* to void* to shutup the compiler */extern int i2c_write_multiple (uchar, uint, int, void *, int);extern int i2c_read_multiple (uchar, uint, int, void *, int);extern block_dev_desc_t *get_dev (char*, int);extern int u_boot_hush_start(void);intau_check_cksum_valid(int idx, long nbytes){ image_header_t *hdr; unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ checksum = ntohl(hdr->ih_dcrc); if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; } return 0;}intau_check_header_valid(int idx, long nbytes){ image_header_t *hdr; unsigned long checksum; unsigned char buf[4]; hdr = (image_header_t *)LOAD_ADDR; /* check the easy ones first */#undef CHECK_VALID_DEBUG#ifdef CHECK_VALID_DEBUG printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM); printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);#endif if (nbytes < sizeof(*hdr)) { printf ("Image %s bad header SIZE\n", aufile[idx]); return -1; } if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } /* check the hdr CRC */ checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { printf ("Image %s bad header checksum\n", aufile[idx]); return -1; } hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST) && (hdr->ih_type != IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } /* special case for prepare.img */ if (idx == IDX_PREPARE) return 0; /* recycle checksum */ checksum = ntohl(hdr->ih_size); /* for kernel and app the image header must also fit into flash */ if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE)) checksum += sizeof(*hdr); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { printf ("Image %s is bigger than FLASH\n", aufile[idx]); return -1; } /* check the time stamp from the EEPROM */ /* read it in */ i2c_read_multiple(0x54, auee_off[idx].time, 1, buf, sizeof(buf));#ifdef CHECK_VALID_DEBUG printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x " "as int %#x time %#x\n", buf[0], buf[1], buf[2], buf[3], *((unsigned int *)buf), ntohl(hdr->ih_time));#endif /* check it */ if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) { printf ("Image %s is too old\n", aufile[idx]); return -1; } return 0;}/* power control defines */#define CPLD_VFD_BK ((volatile char *)0x04038002)#define POWER_OFF (1 << 1)int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -