⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 可在VMWare workstation中的运行的wince 5 bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  
    main.c
    
Abstract:  
    Serial boot loader main module. This file contains the C main
    for the boot loader.    NOTE: The firmware "entry" point (the real
    entry point is _EntryPoint in init assembler file.

    The Windows CE boot loader is the code that is executed on a Windows CE
    development system at power-on reset and loads the Windows CE
    operating system. The boot loader also provides code that monitors
    the behavior of a Windows CE platform between the time the boot loader
    starts running and the time the full operating system debugger is 
    available. Windows CE OEMs are supplied with sample boot loader code 
    that runs on a particular development platform and CPU.
    
Functions:


Notes: 

--*/

#include <windows.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <bootarg.h>

#include <pc.h>
#include <wdm.h>
#include <ceddk.h>
#include <pehdr.h>
#include <romldr.h>
#include "blcommon.h"

#define DEF_BAUD_RATE 115200
// DEF_BAUD_RATE must be one of 115200, 57600, 38400, 19200, 9600

// Use the serial bootloader in conjunction with the serial kitl transport
// Both the transport and the download service expect packets with the
// same header format. Packets not of type DLREQ, DLPKT, or DLACK are 
// ignored by the serial bootloader.

#define KITL_MAX_DEV_NAMELEN      16
#define KITL_MTU                  1520

// serial packet header and trailer definitions
static const UCHAR packetHeaderSig[] = { 'k', 'I', 'T', 'L' };
#define HEADER_SIG_BYTES    sizeof(packetHeaderSig)

#define KS_PKT_KITL         0xAA
#define KS_PKT_DLREQ        0xBB
#define KS_PKT_DLPKT        0xCC
#define KS_PKT_DLACK        0xDD
#define KS_PKT_JUMP         0xEE

// packet header
#include <pshpack1.h>
typedef struct tagSERIAL_PACKET_HEADER 
{
    UCHAR headerSig[HEADER_SIG_BYTES];
    UCHAR pktType;
    UCHAR Reserved;
    USHORT payloadSize; // not including this header    
    UCHAR crcData;
    UCHAR crcHdr;

} SERIAL_PACKET_HEADER, *PSERIAL_PACKET_HEADER;
#include <poppack.h>

// packet payload
typedef struct tagSERIAL_BOOT_REQUEST 
{
    UCHAR PlatformId[KITL_MAX_DEV_NAMELEN+1];
    UCHAR DeviceName[KITL_MAX_DEV_NAMELEN+1];
    USHORT reserved;

} SERIAL_BOOT_REQUEST, *PSERIAL_BOOT_REQUEST;

typedef struct tagSERIAL_BOOT_ACK
{
    DWORD fJumping;

} SERIAL_BOOT_ACK, *PSERIAL_BOOT_ACK;

typedef struct tagSERIAL_JUMP_REQUST
{
    DWORD dwKitlTransport;
    
} SERIAL_JUMP_REQUEST, *PSERIAL_JUMP_REQUEST;

typedef struct tagSERIAL_BLOCK_HEADER
{
    DWORD uBlockNum;
    
} SERIAL_BLOCK_HEADER, *PSERIAL_BLOCK_HEADER;

#define BOOT_ARG_PTR_LOCATION_NP    0x001FFFFC
#define BOOT_ARG_LOCATION_NP        0x001FFF00

#define PLATFORM_STRING "CEPC"

// serial port definitions
#define COM_RTS             0x02
#define COM_DTR             0x01

// line status register
#define LS_TSR_EMPTY        0x40
#define LS_THR_EMPTY        0x20
#define LS_RX_BREAK         0x10
#define LS_RX_FRAMING_ERR   0x08
#define LS_RX_PARITY_ERR    0x04
#define LS_RX_OVERRUN       0x02
#define LS_RX_DATA_READY    0x01
#define LS_RX_ERRORS        ( LS_RX_FRAMING_ERR | LS_RX_PARITY_ERR | LS_RX_OVERRUN )

// modem status register
#define MS_CARRIER_DETECT   0x80
#define MS_RING             0x40
#define MS_DSR              0x20
#define MS_CTS              0x10
#define MS_DELTA_DCD        0x08
#define MS_TRAIL_EDGE_RI    0x04
#define MS_DELTA_DSR        0x02
#define MS_DELTA_CTS        0x01

#define DEF_BAUD_DIVISOR    (115200/DEF_BAUD_RATE)

static BOOT_ARGS *pBootArgs;
__declspec(align(4)) BYTE g_buffer[KITL_MTU];
static PUCHAR DlIoPortBase = 0;

// OS launch function type
typedef void (*PFN_LAUNCH)();

// prototypes
BOOL OEMSerialSendRaw(LPBYTE pbFrame, USHORT cbFrame);
BOOL OEMSerialRecvRaw(LPBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite);
BOOL RecvHeader(PSERIAL_PACKET_HEADER pHeader, BOOLEAN bWaitInfinite);
BOOL RecvPacket(PSERIAL_PACKET_HEADER pHeader, PBYTE pbFrame, PUSHORT pcbFrame, BOOLEAN bWaitInfinite);
BOOL WaitForJump(VOID);
BOOL WaitForBootAck(BOOL *pfJump);
BOOL SerialSendBlockAck(DWORD uBlockNumber);
BOOL SerialSendBootRequest(VOID);

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SpinForever(void)
{
    EdbgOutputDebugString("SpinForever...\r\n");
    while(1);
}

BOOL OEMDebugInit (void)
{
    //
    // Initialize the monitor port (for development system)
    // This should be done first since otherwise we can not
    // print any message onto the monitor
    //
    OEMInitDebugSerial();
    return TRUE;
}

//------------------------------------------------------------------------------
BOOL OEMPlatformInit (void)
//------------------------------------------------------------------------------
{    
    extern void BootUp (void);
    
    EdbgOutputDebugString("Microsoft Windows CE Serial Bootloader for CE/PC (%s)\n", __DATE__);
    
    //
    // Get pointer to Boot Args...
    //
    pBootArgs = (BOOT_ARGS *) ((ULONG)(*(PBYTE *)BOOT_ARG_PTR_LOCATION_NP));

    pBootArgs->dwEBootAddr = (DWORD)BootloaderMain;
    pBootArgs->ucLoaderFlags = 0;   

    // set up comm port
    DlIoPortBase = (PUCHAR)COM2_BASE;
    WRITE_PORT_UCHAR(DlIoPortBase+comIntEnable,     0x00);  // Interrupts off
    WRITE_PORT_UCHAR(DlIoPortBase+comLineControl,   0x80);  // Access Baud Divisor (DLB)
    WRITE_PORT_UCHAR(DlIoPortBase+comDivisorLow,    DEF_BAUD_DIVISOR);
    WRITE_PORT_UCHAR(DlIoPortBase+comDivisorHigh,   0x00);  // 
    WRITE_PORT_UCHAR(DlIoPortBase+comFIFOControl,   0x07);  // FIFO on, reset
    WRITE_PORT_UCHAR(DlIoPortBase+comLineControl,   0x03);  // 8 Data Bits, 1 Stop Bit, No Parity
    WRITE_PORT_UCHAR(DlIoPortBase+comModemControl,  0x00);  // de-assert DTR, de-assert RTS

    // clear comm errors
    READ_PORT_UCHAR(DlIoPortBase+comLineStatus);

    EdbgOutputDebugString("Comm Port initialized @ 0x%x\n", DlIoPortBase);
    
    return TRUE;
}

//------------------------------------------------------------------------------
DWORD OEMPreDownload (void)
//------------------------------------------------------------------------------
{   
    BOOL fGotJump = FALSE;

    // send boot requests indefinitely
    do
    {
        EdbgOutputDebugString("Sending boot request...\r\n");
        if(!SerialSendBootRequest())
        {
            EdbgOutputDebugString("Failed to send boot request\r\n");
            return BL_ERROR;
        }
    }
    while(!WaitForBootAck(&fGotJump));

    // ack block zero to start the download
    SerialSendBlockAck(0);

    EdbgOutputDebugString("Received boot request ack... starting download\r\n");

    return fGotJump  ? BL_JUMP : BL_DOWNLOAD;
}

//------------------------------------------------------------------------------
void OEMLaunch (DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
//------------------------------------------------------------------------------
{    
    EdbgOutputDebugString ("Download successful! Jumping to image at %Xh...\r\n", dwLaunchAddr);

    // if no launch address specified, get it from boot args
    if(!dwLaunchAddr) 
    {
        dwLaunchAddr = pBootArgs->dwLaunchAddr;
    }

    // save launch address in the boot args
    else
    {
        pBootArgs->dwLaunchAddr = dwLaunchAddr;
    }

    // wait for jump packet indefinitely
    if(WaitForJump())
    {
        ((PFN_LAUNCH)(dwLaunchAddr))();
    }

    EdbgOutputDebugString("Failed to wait for jump message\r\n");
    
    SpinForever ();
}

//------------------------------------------------------------------------------
BOOL OEMReadData (DWORD cbData, LPBYTE pbData)
//------------------------------------------------------------------------------
{
    static DWORD dwBlockNumber = 0;
    
    static USHORT cbDataBuffer = 0;    
    static BYTE dataBuffer[KITL_MTU] = {0};

    // the first DWORD in the local buffer is the block header which contains
    // the sequence number of the block received
    static PSERIAL_BLOCK_HEADER pBlockHeader = (PSERIAL_BLOCK_HEADER)dataBuffer;
    static PBYTE pBlock = dataBuffer + sizeof(PSERIAL_BLOCK_HEADER);

    SERIAL_PACKET_HEADER header;
    USHORT cbPacket;

    LPBYTE pOutBuffer = pbData;

    while(cbData)
    {
        // if there is no data in the local buffer, read some
        //
        while(0 == cbDataBuffer)
        {
             // read from port
             cbPacket = sizeof(dataBuffer);
             if(RecvPacket(&header, dataBuffer, &cbPacket, TRUE))
             {
                // ignore non-download packet types
                if(KS_PKT_DLPKT == header.pktType)
                {                    
                    // make sure we received the correct block in the sequence
                    if(dwBlockNumber == pBlockHeader->uBlockNum)
                    {
                        cbDataBuffer = header.payloadSize - sizeof(SERIAL_BLOCK_HEADER);
                        dwBlockNumber++;
                    }
                    else
                    {
                        EdbgOutputDebugString("Received out of sequence block %u\r\n", pBlockHeader->uBlockNum);
                        EdbgOutputDebugString("Expected block %u\r\n", dwBlockNumber);
                    }
                    
                    // ack, or re-ack the sender
                    if(dwBlockNumber > 0)
                    {
                        // block number has already been incremented when appropriate
                        SerialSendBlockAck(dwBlockNumber - 1);
                    }
                }
             }
        }
        
        // copy from local buffer into output buffer
        //

        // if there are more than the requested bytes, copy and shift
        // the local data buffer
        if(cbDataBuffer > cbData)
        {
            // copy requested bytes from local buffer into output buffer            
            memcpy(pOutBuffer, pBlock, cbData);
            cbDataBuffer -= (USHORT)cbData;

            // shift the local buffer accordingly because not all data was used
            memmove(pBlock, pBlock + cbData, cbDataBuffer);
            cbData = 0;
        }
        else // cbDataBuffer <= cbData
        {
            // copy all bytes in local buffer to output buffer
            memcpy(pOutBuffer, pBlock, cbDataBuffer);
            cbData -= cbDataBuffer;
            pOutBuffer += cbDataBuffer;
            cbDataBuffer = 0;
        }
    }

    return TRUE;
}

//
// Memory mapping related functions
//
LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{
    // map address into physical address
    return (LPBYTE) (dwAddr & ~0x80000000);
}

//
// CEPC doesn't have FLASH, LED, stub the related functions
//
void OEMShowProgress (DWORD dwPacketNum)
{
}

BOOL OEMIsFlashAddr (DWORD dwAddr)
{
    return FALSE;
}

BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
    return FALSE;
}

void OEMContinueEraseFlash (void)
{
}

BOOL OEMFinishEraseFlash (void)
{
    return FALSE;
}

BOOL OEMWriteFlash (DWORD dwStartAddr, DWORD dwLength)
{
    return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -