Exemplo n.º 1
0
/**
 * 比较文件数据
 * @param file1 第一个文件
 * @param file2 第二个文件
 * @param start 起始偏移
 * @param len 比较长度
 * @param ignoreLsn 是否忽略比较LSN
 * @return 文件相同返回true;否则返回false
 */
bool compareFile(File *file1, File *file2, u64 start, u64 len, bool ignoreLsn) throw(NtseException) {
	u64 size1;
	u64 errNo = file1->getSize(&size1);
	if (errNo != File::E_NO_ERROR)
		NTSE_THROW(errNo, "getSize on file %s failed", file1->getPath());
	u64 size2;
	errNo = file2->getSize(&size2);
	if (errNo != File::E_NO_ERROR)
		NTSE_THROW(errNo, "getSize on file %s failed", file2->getPath());
	if (size1 != size2)
		return false;

	assert(start < size1);
	if (ignoreLsn) { // 检查参数有效性
		assert(start % Limits::PAGE_SIZE == 0 && size1 % Limits::PAGE_SIZE == 0);
		if (size1 - start >= len)
			assert(len % Limits::PAGE_SIZE == 0);
	}
	
	u64 end = min(len, size1 - start);

	u32 bufSize = 256 * Limits::PAGE_SIZE;
	byte *buf1 = (byte *)System::virtualAlloc(bufSize);
	byte *buf2 = (byte *)System::virtualAlloc(bufSize);
	for (u64 offset = start; offset < end;) {
		u32 curSize = min((u32)(end - offset), bufSize);
		if ((errNo = file1->read(offset, curSize, buf1)) != File::E_NO_ERROR)
			NTSE_THROW(errNo, "read file %s failed", file1->getPath());
		if ((errNo = file2->read(offset, curSize, buf2)) != File::E_NO_ERROR)
			NTSE_THROW(errNo, "read file %s failed", file2->getPath());
		if (!ignoreLsn) {
			int diffPos = compareMem(buf1, buf2, curSize);
			if (diffPos >= 0)
				return false;
		} else { // 忽略LSN比较
			for (u32 i = 0; (i + Limits::PAGE_SIZE) <= curSize; i += Limits::PAGE_SIZE) {
				int diffPos = compareMem(buf1 + i + 8, buf2 + i + 8, Limits::PAGE_SIZE - 8);
				if (diffPos >= 0)
					return false;
			}
		}
		offset += curSize;
	}
	System::virtualFree(buf1);
	System::virtualFree(buf2);
	return true;
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    int fdElf;
    int lenElf;
    unsigned char * binElf;
    unsigned int entryElf;
    unsigned int flagsElf;
    unsigned int ramAddr;
    unsigned int romram;
    int secElf;
    int count;
    int temp;
    unsigned int utemp;
    int startSec, endSec;
    unsigned int start, src, size, end, type, flag;
    unsigned int maxFlash, lowFlash, highFlash;
    usb_dev_handle *udev;
    struct usb_device *dev;
    int found;
    struct usb_bus *bus;
    char cserial[256];
    tIntermediateBuffer* actBuf = NULL;
    tIntermediateBuffer* startBuf = NULL;

    if ((argc < 2) || (argc > 3))
    {
        printf("lpc21iap version v%d.%d, ", LPC21IAP_VER_MAJ, LPC21IAP_VER_MIN);
        printf("usage: %s file.elf [usb_serial_number]\n", argv[0]);
        exit(1);
    }

    fdElf = open(argv[1], O_RDONLY | O_BINARY);

    if(fdElf < 0)
    {
        perror("open file");
        exit(1);
    }

    lenElf = lseek(fdElf, 0, SEEK_END);

    if(lenElf <= 0)
    {
        perror("file length");
        exit(1);
    }

    lseek(fdElf, 0, SEEK_SET);

    binElf = malloc(lenElf);

    if (binElf == NULL)
    {
        perror("malloc failed");
        exit(1);
    }

    startBuf = malloc(sizeof(tIntermediateBuffer));
    if (startBuf == NULL)
    {
        perror("malloc failed");
        exit(1);
    }
    startBuf->start = 0xFFFFFFFF;
    startBuf->next = NULL;

    memset(startBuf->data, 0xFF, MAX_SECT);

    count = 0;
    while (count < lenElf)
    {
        temp = read(fdElf, binElf+count, lenElf-count);
        if (temp <= 0)
        {
            perror("could not read");
            exit(1);
        }
        count += temp;
    }

    close(fdElf);

    /* check ELF header */
    if (!ELFCheckHeader(binElf))
    {
        perror("no ELF header" );
        exit(1);
    }

    flagsElf = ELFHdrFlags(binElf);
    if (EF_ARM_HASENTRY == (flagsElf & EF_ARM_HASENTRY))
    {
        entryElf = ELFEntryAddr(binElf);
    }

    secElf = ELFNoPSections(binElf);

    found = 0;
    usb_init();
    usb_find_busses();

    for(count = 0; count < 100 && !found; count++)
    {
        printf(".");
        fflush(stdout);

        if (usb_find_devices())
        {
            for (bus = usb_get_busses(); bus && (!found); bus = bus->next)
            {
                for (dev = bus->devices; dev && (!found); dev = dev->next)
                {
                    if ((dev->descriptor.idVendor  == VENDOR_ID) &&
                        (dev->descriptor.idProduct == DEVICE_ID))
                    {
                        udev = usb_open(dev);

                        if (udev)
                        {
                            printf("\nFound USB device\n");
                            if (argc==3)
                            {
                                if (dev->descriptor.iSerialNumber)
                                {
                                    if (usb_get_string_simple(udev, dev->descriptor.iSerialNumber, cserial, sizeof(cserial)) > 0)
                                    {
                                        if (strncmp(argv[2], cserial, strlen(argv[2])) == 0)
                                        {
                                            found = 1;
                                        }
                                        else
                                        {
                                            printf("Serial Number does not match: %s\n", cserial);
                                        }
                                    }
                                    else
                                    {
                                        printf("could not get serial number\n");
                                    }
                                }
                                else
                                {
                                    printf("no serial number\n");
                                }

                                if (!found) usb_close(udev);
                            }
                            else found = 1;
                        }
                    }
                }
            }
        }
        Sleep(200);
    }

    if(!found)
    {
        printf("\nno USB device\n");
        exit(1);
    }


    if (!unlock(udev)) exit(1);

    if (!readBootCode(udev, &utemp)) exit(1);
    printf("BootROM code: %d.%d\n", (utemp >> 8) & 0xFF, utemp & 0xFF);

    if (!readPartID(udev, &utemp)) exit(1);
    for (count = 0; LPCtypes[count].id != 0; count++)
    {
        if (utemp == LPCtypes[count].id) break;
    }
    printf("Part ID: 0x%08X (%s)\n", utemp, LPCtypes[count].name);

    if (!readBootloaderVersion(udev, &utemp)) exit(1);
    printf("BootLoader version: %d.%d\n", (utemp >> 8) & 0xFF, utemp & 0xFF);

    if (!readRAMAddress(udev, &ramAddr)) exit(1);

    if (!readBootloaderLocation(udev, &romram)) exit(1);

    /* find used sectors (kill the unused in-betweens, speed optimized) */

    /* calc maximum usable flash address */
    maxFlash = 0;
    for (count=0; 
         count < sizeof(SectorTable_214x)/sizeof(SectorTable_214x[0]); 
         count++)
    {
            maxFlash += SectorTable_214x[count];
    }

    /* find min and max used flash address */
    lowFlash = maxFlash;
    highFlash = 0;
    for (count=0; count < secElf; count++)
    {
        start = ELFAddrPSection(binElf, count);
        src   = ELFOffsPSection(binElf, count);
        size  = ELFSizePSection(binElf, count);
        type  = ELFTypePSection(binElf, count);
        flag  = ELFFlagPSection(binElf, count);

        if ((size > 0) && 
            (src != 0) &&
            (type & PT_LOAD) &&
            (flag & (PF_X | PF_W | PF_R)) &&
            (start+size <= maxFlash))
        {
            if (start+size > highFlash) highFlash = start+size;
            if (start < lowFlash) lowFlash = start;
        }
    }

    if ((romram == RUN_ROM) && (lowFlash < BOOTLOAD_SECT*MAX_SECT))
    {
        printf("running from ROM, can not flash low sectors, load RAM version first\n");
        exit(2);
    }

    /* anything to flash erase? */
    if (lowFlash != maxFlash)
    {
        startSec = getSec(lowFlash);
        endSec = getSec(highFlash);

        /* prepare sectors for erase */
        if (!prepareSectors(udev, startSec, endSec)) exit(1);

        /* erase sectors */
        if (!eraseSectors(udev, startSec, endSec)) exit(1);
    }

    for (count=0; count < secElf; count++)
    {
        start = ELFAddrPSection(binElf, count);
        src   = ELFOffsPSection(binElf, count);
        size  = ELFSizePSection(binElf, count);
        type  = ELFTypePSection(binElf, count);
        flag  = ELFFlagPSection(binElf, count);

        /* adjust size to 32 bit alignment */
        size = (size + 3) & 0xFFFFFFFC;

        if ((size > 0) &&
            (src != 0) &&
            (type & PT_LOAD) &&
            (flag & (PF_X | PF_W | PF_R)))
        {

            if (start+size <= maxFlash)
            {
                unsigned int cnt;
                unsigned int startPage, endPage, countPage;
                unsigned int splitGap, splitCnt;

#if 0
                /* Flash */
                printf( "Flash sect  = %02d, start = 0x%08X, src = 0x%08X, size = 0x%08X, type = 0x%08X, flag = 0x%08X\n",
                count,
                start,
                src,
                size,
                type,
                flag);
#endif

                /* end address in flash */
                end = start + size;

                cnt = 0;

                /* page address of the first sector */
                startPage = start & ~(MAX_SECT-1);
                /* page address of the end sector */
                endPage  = (end+MAX_SECT) & ~(MAX_SECT-1);

                /* always 4k "blocks" are written */
                for (countPage = startPage; countPage < endPage; countPage += MAX_SECT)
                {
                    /* do checksum for first block (LE machines) */
                    if (countPage == 0)
                    {
                        unsigned int * dat = (unsigned int *) (binElf+src);
                        unsigned int crc = 0;
                        int count;

                        dat[5] = 0;

                        for(count = 0; count < 8; count++) {
                            crc += dat[count];
                        }

                        dat[5] = (unsigned long) -crc;

                        printf("changing vector table");
                    }

                    printf("#");
                    fflush(stdout);

                    splitCnt = MAX_SECT;

                    /* The LPC214x does not allow pages (4k) to be
                       programmed twice without erasing in between, not even
                       with 0xFF's being filled into the gaps. So we have to
                       store all the partly filled pages until the end and
                       flash them in one flush.                              */

                    /* first page, not beginning at page start */
                    if ((countPage == startPage) && (start != startPage))
                    {
                        /* gap of non programmed bytes at the beginning of page */
                        splitGap = start % MAX_SECT;
                        /* number of bytes in the first block */
                        if ((splitGap + size) < MAX_SECT) {
                            /* data ends within first page */
                            splitCnt = size;
                        }
                        else {
                            /* data until end of page */
                            splitCnt = MAX_SECT - splitGap;
                        }
                    }
                    /* last page, not ending at page end */
                    else  if ((countPage+MAX_SECT == endPage) && (end != endPage))
                    {
                        /* no gap at beginning */
                        splitGap = 0;
                        /* number of bytes in the last sector */
                        splitCnt = end % MAX_SECT;
                    }
                    if (splitCnt != MAX_SECT)
                    {
                        /* keep partly filled pages for later programming */
                        actBuf = startBuf;
                        while (1)
                        {
                            if (actBuf->start == countPage)
                            {
                                break;
                            }
                            if (actBuf->next == NULL)
                            {
                                actBuf->next = malloc(sizeof(tIntermediateBuffer));
                                if (actBuf->next == NULL)
                                {
                                    perror("malloc failed");
                                    exit(1);
                                }
                                actBuf = actBuf->next;
                                actBuf->start = countPage;
                                actBuf->next = NULL;
                                memset(actBuf->data, 0xFF, MAX_SECT);
                                break;
                            }
                            actBuf = actBuf->next;
                        }

                        /* copy data to buffer */
                        // read(startBuf->data + splitGap, splitCnt):
                        memcpy(actBuf->data + splitGap, binElf+src+cnt, splitCnt);
                    }
                    else
                    {
                       /* flash full filled 4k block */

                        /* copy data to buffer */
                        // read(startBuf->data, MAX_SECT):
                        memcpy(startBuf->data, binElf+src+cnt, MAX_SECT);

                        if (!writeRAM(udev, ramAddr, MAX_SECT)) exit(1);
                        if (!USBReqData(udev, startBuf->data, MAX_SECT)) exit(1);
                        if (!prepareSectors(udev, getSec(countPage), getSec(countPage))) exit(1);
                        if (!copyRAMFlash(udev, countPage, ramAddr, MAX_SECT)) exit(1);
                        if (!compareMem(udev, countPage, ramAddr, MAX_SECT)) exit(1);
                    }
                    cnt += splitCnt;
                }
            }
            else
            {
#if 0
                /* RAM */
                printf( "RAM sect  = %02d, start = 0x%08X, src = 0x%08X, size = 0x%08X, type = 0x%08X, flag = 0x%08X\n",
                count,
                start,
                src,
                size,
                type,
                flag);
#endif

                /* copy it in one piece */
                if (!writeRAM(udev, start, size)) exit(1);
                if (!USBReqData(udev, (unsigned char*) (binElf+src), size)) exit(1);
            }
        }
    }

    actBuf = startBuf;

    /* go through all the split sectors */
    while (actBuf != NULL)
    {
        if (actBuf->start != 0xFFFFFFFF)
        {
            if (!writeRAM(udev, ramAddr, MAX_SECT)) exit(1);
            if (!USBReqData(udev, actBuf->data, MAX_SECT)) exit(1);
            if (!prepareSectors(udev, getSec(actBuf->start), getSec(actBuf->start))) exit(1);
            if (!copyRAMFlash(udev, actBuf->start & ~(MAX_SECT-1), ramAddr, MAX_SECT)) exit(1);
            if (!compareMem(udev, actBuf->start & ~(MAX_SECT-1), ramAddr, MAX_SECT)) exit(1);
        }
        startBuf = actBuf;
        actBuf = actBuf->next;
        free(startBuf);
    }

    printf("\n");

    free(binElf);

    if (EF_ARM_HASENTRY == (flagsElf & EF_ARM_HASENTRY))
    {
        printf( "Starting software at 0x%08X\n", entryElf );
        if (!goSw(udev, entryElf)) exit(1);
    }

    return(0);
}