BOOL SimpleStorage::Compact()
{
    GLOBAL_LOCK(irq);
    BlockStorageStream* pFreeBlock = (s_pCurrentStream == &s_BsStreamA) ? &s_BsStreamB : &s_BsStreamA;
    SIMPLESTORAGE_FILE_HEADER header;
    UINT8 buffer[256];
    const UINT32 eraseBlock = 0x0;
    const UINT32 activeBlock = SIMPLESTORAGE_ACTIVE_BLOCK_MARKER;

    pFreeBlock->Seek(0, BlockStorageStream::SeekBegin);
    if(!pFreeBlock->Erase(pFreeBlock->Length)) return FALSE;

    pFreeBlock->Seek(sizeof(SIMPLESTORAGE_BLOCK_HEADER), BlockStorageStream::SeekBegin);

    s_pCurrentStream->Seek(sizeof(SIMPLESTORAGE_BLOCK_HEADER), BlockStorageStream::SeekBegin);

    do
    {
        INT32 len;
        
        if(!ReadToNextFile(header)) break;

        if(header.Signature != SIMPLESTORAGE_FILE_SIGNATURE) break;

        pFreeBlock->Write((UINT8*)&header, sizeof(header));

        len = header.Length;
        while(len > 0)
        {
            int bufLen = len < ARRAYSIZE(buffer) ? len : ARRAYSIZE(buffer);
            
            if(!s_pCurrentStream->ReadIntoBuffer((UINT8*)buffer, bufLen)) break;
            if(!pFreeBlock->Write((UINT8*)buffer, bufLen)) break;

            len -= bufLen;
        }
    }
    while(s_pCurrentStream->CurrentIndex + sizeof(header) < s_pCurrentStream->Length);

    s_pCurrentStream->Seek(0, BlockStorageStream::SeekBegin);

    s_pCurrentStream->Write((UINT8*)&eraseBlock, sizeof(eraseBlock));

    pFreeBlock->Seek(0, BlockStorageStream::SeekBegin);

    pFreeBlock->Write((UINT8*)&activeBlock, sizeof(activeBlock)); 

    s_pCurrentStream = pFreeBlock;

    return TRUE;
}
UINT32 MicroBooter_PrepareForExecution(UINT32 physicalEntryPointAddress)
{
    if (physicalEntryPointAddress == CODE_BASEADDRESS)
    {
        BlockStorageDevice *device;
        ByteAddress ByteAddress;
        UINT32 physicalAddress = CODE_BASEADDRESS;
        
        if (BlockStorageList::FindDeviceForPhysicalAddress( &device, physicalAddress, ByteAddress)) 
        {
            BlockStorageStream stream;
    
            if(stream.Initialize(BlockUsage::CODE, device))
            {
                BYTE *dst;

                if(stream.CurrentAddress() != CODE_BASEADDRESS)
                {
                    hal_fprintf( STREAM_LCD, "Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
                    debug_printf( "Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
                    stream.Seek(CODE_BASEADDRESS - stream.CurrentAddress(), BlockStorageStream::SeekCurrent);
                }

                // load ER_FLASH only
                dst =(BYTE *) EXCODE_BASEADDRESS  ;
                
                
                stream.Read( &dst, CODE_SIZE );
                

                CPU_DrainWriteBuffers();
            }
            
        }
    
    }

    return EXCODE_BASEADDRESS;
}
Esempio n. 3
0
    void Initialize()
    {
#if defined(PLATFORM_ARM_MOTE2)
        if (COM_IsUsb(HalSystemConfig.DebugTextPort))
            WaitInterval = 5000;        // The USB port must be selected and the Start button pressed all during this time
        else
            WaitInterval = 2000;        // The USART port may be selected before powering on the Imote2, so it takes less time
#else
        WaitInterval     = 2000;
#endif

        SerialPortActive = FALSE;

        UsartPort        = USART_DEFAULT_PORT;

        UsingUsb         = FALSE;
        UsbPort          = USB1;
        UsbEventCode     = USB_DEBUG_EVENT_IN;

        //--//

        // wait an extra second for buttons and COM port to stabilize
        Events_WaitForEvents( 0, 1000 );

        // COM init is now delayed for TinyBootloader, so we need to initialize it here
        CPU_InitializeCommunication();

        //--//

        // set default baud rate
        if(UsartPort != DEBUG_TEXT_PORT)
        {
            DebuggerPort_Initialize( UsartPort );
        }
        // extra time to allow USB setup, so that we can see the printf
        Events_WaitForEvents( 0, 1000 );


        hal_printf( "PortBooter v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION);
        hal_printf( "Build Date: %s %s\r\n",  __DATE__, __TIME__);

#if defined(__GNUC__)
        hal_printf( "GNU Compiler version %d\r\n", __GNUC__);
#elif defined(__ADSPBLACKFIN__)
        hal_printf( "Blackfin Compiler version %d\r\n", __VERSIONNUM__ );
#else
        hal_printf( "ARM Compiler version %d\r\n", __ARMCC_VERSION);
#endif
       
        //--//

        BlockStorageStream stream;
        FLASH_WORD ProgramWordCheck;

        if(!stream.Initialize(BlockUsage::CODE)) return;



        do
        {
            do
            {
            
                UINT32 addr = stream.CurrentAddress();
    			FLASH_WORD *pWord = &ProgramWordCheck;

                stream.Read( (BYTE**)&pWord, sizeof(FLASH_WORD) );

                if(*pWord == PROGRAM_WORD_CHECK)
                {
                    hal_printf("*** nXIP Program found at 0x%08x\r\n", addr );
    				Programs[ProgramCount++] = (UINT32)addr;
                }

                if(ProgramCount == MAX_PROGRAMS) break;
            }
            while( stream.Seek( BlockStorageStream::STREAM_SEEK_NEXT_BLOCK, BlockStorageStream::SeekCurrent ) );

        } while(stream.NextStream());

    }
BOOL MicroBooterUpdateProvider::InstallUpdate( MFUpdate* pUpdate, UINT8* pValidation, INT32 validationLen )
{
    if(pUpdate->Providers->Storage == NULL) return FALSE;

    if(!pUpdate->IsValidated()) return FALSE;

    switch(pUpdate->Header.UpdateType)
    {
        case MFUPDATE_UPDATETYPE_FIRMWARE:
            {
                HAL_UPDATE_CONFIG cfg;

                if(sizeof(cfg.UpdateSignature) < validationLen) return FALSE;
                
                cfg.Header.Enable = TRUE;
                cfg.UpdateID = pUpdate->Header.UpdateID;

                if(validationLen == sizeof(UINT32))
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__CRC;
                }
                else
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__SIGNATURE;
                }
                
                memcpy( cfg.UpdateSignature, pValidation, validationLen );

                if(HAL_CONFIG_BLOCK::UpdateBlockWithName(cfg.GetDriverName(), &cfg, sizeof(cfg), FALSE))
                {
                    CPU_Reset();
                }
            }
            break;
            
        case MFUPDATE_UPDATETYPE_ASSEMBLY:
            {
                BlockStorageStream stream;
                
                if(NULL == BlockStorageList::GetFirstDevice())
                {
                    BlockStorageList::Initialize();
                
                    BlockStorage_AddDevices();
                
                    BlockStorageList::InitializeDevices();
                }

                if(stream.Initialize(BlockUsage::DEPLOYMENT))
                {
                    if(pUpdate->Header.UpdateSubType == MFUPDATE_UPDATESUBTYPE_ASSEMBLY_REPLACE_DEPLOY)
                    {
                        do
                        {
                            stream.Erase(stream.Length);
                        }
                        while(stream.NextStream());

                        stream.Initialize(BlockUsage::DEPLOYMENT);
                    }
                    
                    do
                    {
                        UINT8 buf[512];
                        INT32 offset = 0;
                        INT32 len = sizeof(buf);
                        const BlockDeviceInfo* deviceInfo = stream.Device->GetDeviceInfo();
                        BOOL isXIP = deviceInfo->Attribute.SupportsXIP;
                        
                        const CLR_RECORD_ASSEMBLY* header;
                        INT32  headerInBytes = sizeof(CLR_RECORD_ASSEMBLY);
                        BYTE * headerBuffer  = NULL;
                        
                        if(!isXIP)
                        {
                            headerBuffer = (BYTE*)private_malloc( headerInBytes );  if(!headerBuffer) return FALSE;
                            memset( headerBuffer, 0,  headerInBytes );
                        }
                        
                        while(TRUE)
                        {
                            if(!stream.Read( &headerBuffer, headerInBytes )) break;
                        
                            header = (const CLR_RECORD_ASSEMBLY*)headerBuffer;
                        
                            // check header first before read
                            if(!header->GoodHeader())
                            {
                                stream.Seek(-headerInBytes);
                                
                                if(stream.IsErased(pUpdate->Header.UpdateSize))
                                {
                                    while(offset < pUpdate->Header.UpdateSize)
                                    {
                                        if((pUpdate->Header.UpdateSize - offset) < len)
                                        {
                                            len = pUpdate->Header.UpdateSize - offset;
                                        }
                                        
                                        offset += pUpdate->Providers->Storage->Read(pUpdate->StorageHandle, offset, buf, len);

                                        stream.Write(buf, len);
                                    }

                                    ClrReboot();
                                    return TRUE;
                                }
                                break;
                            }
                        
                            UINT32 AssemblySizeInByte = ROUNDTOMULTIPLE(header->TotalSize(), CLR_UINT32);
                        
                            stream.Seek( AssemblySizeInByte );
                        }
                        if(!isXIP) private_free( headerBuffer );
                    
                    }
                    while(stream.NextStream());
                }

            }
            break;
    }
    
    return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// The TinyBooter_OnStateChange method is an event handler for state changes in 
// the TinyBooter.  It is designed to help porting kit users control the tinybooter
// execution and allow them to add diagnostics.
////////////////////////////////////////////////////////////////////////////////
void TinyBooter_OnStateChange(TinyBooterState state, void* data, void ** retData)
{
	switch (state)
	{
		////////////////////////////////////////////////////////////////////////////////////
		// State_EnterBooterMode - TinyBooter has entered upload mode
		////////////////////////////////////////////////////////////////////////////////////
	case State_EnterBooterMode:
		hal_fprintf(STREAM_LCD, "Waiting\r");
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_ButtonPress - A button was pressed while Tinybooter 
		// The data parameter is a pointer to the timeout value for the booter mode.
		////////////////////////////////////////////////////////////////////////////////////
	case State_ButtonPress:
		if (NULL != data)
		{
			UINT32 down, up;
			INT32* timeout_ms = (INT32*)data;

			// wait forever if a button was pressed
			*timeout_ms = -1;

			// process buttons
			while (Buttons_GetNextStateChange(down, up))
			{
				// leave a way to exit boot mode incase it was accidentally entered
				if (0 != (down & BUTTON_ENTR))
				{
					// force an enumerate and launch
					*timeout_ms = 0;
				}
			}
		}
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_ValidCommunication - TinyBooter has received valid communication from the host
		// The data parameter is a pointer to the timeout value for the booter mode.
		////////////////////////////////////////////////////////////////////////////////////
	case State_ValidCommunication:
		if (NULL != data)
		{
			INT32* timeout_ms = (INT32*)data;

			// if we received any com/usb data then let's change the timeout to at least 20 seconds
			if (*timeout_ms != -1 && *timeout_ms < 20000)
			{
				*timeout_ms = 20000;
			}
		}
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_Timeout - The default timeout for TinyBooter has expired and TinyBooter will 
		// perform an EnumerateAndLaunch
		////////////////////////////////////////////////////////////////////////////////////
	case State_Timeout:
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_MemoryXXX - Identifies memory accesses.
		////////////////////////////////////////////////////////////////////////////////////
	case State_MemoryWrite:
		hal_fprintf(STREAM_LCD, "Wr: 0x%08x\r", (UINT32)data);
		break;
	case State_MemoryErase:
		hal_fprintf(STREAM_LCD, "Er: 0x%08x\r", (UINT32)data);
		break;


		////////////////////////////////////////////////////////////////////////////////////
		// State_CryptoXXX - Start and result of Crypto signature check
		////////////////////////////////////////////////////////////////////////////////////
	case State_CryptoStart:
		hal_fprintf(STREAM_LCD, "Chk signature \r");
		hal_printf("Chk signature \r");
		break;
		// The data parameter is a boolean that represents signature PASS/FAILURE
	case State_CryptoResult:
		if ((bool)data)
		{
			hal_fprintf(STREAM_LCD, "Signature PASS\r\n\r\n");
			hal_printf("Signature PASS\r\n\r\n");
		}
		else
		{
			hal_fprintf(STREAM_LCD, "Signature FAIL\r\n\r\n");
			hal_printf("Signature FAIL\r\n\r\n");
		}
		DebuggerPort_Flush(HalSystemConfig.DebugTextPort);
		break;

		////////////////////////////////////////////////////////////////////////////////////
		// State_Launch - The host has requested to launch an application at a given address, 
		//                or a timeout has occured and TinyBooter is about to launch the 
		//                first application it finds in FLASH.
		//
		// The data parameter is a UINT32 value representing the launch address
		////////////////////////////////////////////////////////////////////////////////////
	case State_Launch:
		UINT32 address = (UINT32)data;

		if (NULL != data)
		{
			hal_fprintf(STREAM_LCD, "Starting application at 0x%08x\r\n", address);
			debug_printf("Starting application at 0x%08x\r\n", address);

			if (address == CODE_BASEADDRESS || address == EXCODE_BASEADDRESS)
			{
				BlockStorageDevice *device;
				ByteAddress ByteAddress;
				UINT32 physicalAddress = CODE_BASEADDRESS;

				if (BlockStorageList::FindDeviceForPhysicalAddress(&device, physicalAddress, ByteAddress))
				{
					BlockStorageStream stream;

					if (stream.Initialize(BlockUsage::CODE, device))
					{
						if (stream.CurrentAddress() != CODE_BASEADDRESS)
						{
							hal_fprintf(STREAM_LCD, "Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
							debug_printf("Warn: at wrong offset: 0x%08x\r\n", (UINT32)stream.CurrentAddress());
							stream.Seek(CODE_BASEADDRESS - stream.CurrentAddress(), BlockStorageStream::SeekCurrent);
						}

						BYTE *dst;
						dst = (BYTE *)EXCODE_BASEADDRESS;

						stream.Read(&dst, CODE_SIZE);

						if (retData != NULL)
						{
							*retData = (void*)EXCODE_BASEADDRESS;
						}

						CPU_DrainWriteBuffers();
					}
				}
			}
			else if (retData != NULL)
			{
				*retData = (void*)data;
			}
		}
		break;
	}

}