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

📄 edbg.c

📁 windows wm5 下的bootloader代码
💻 C
字号:
//
// 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:
   edbg.c

Abstract:  
   Routines to communicate with eshell program on the desktop to get our
   configuration information (which services are configured over Ethernet,
   and what the host addresses are).
   
Functions:


Notes: 

--*/

#include <windows.h>
#include <halether.h>
#include <ethdbg.h>

#include "udp.h"

/*
 * ProcessEDBG
 *
 *  Receive handler to process messages from eshell program.
 *
 *  Return value:
 *   Return TRUE if message was valid edbg msg, else FALSE
 */
BOOL
EbootProcessEDBG(
    EDBG_ADDR *pMyAddr,     // IN - Our IP/ethernet address
    EDBG_ADDR *pEshellHost, // IN - Host running eshell program, if known. We will only accept
                            //      commands from this host.
                            // OUT- If valid cmd received, filled in with eshell host addr
    BYTE   *pFrameBuffer,   // IN - Pointer to frame buffer (for extracting src IP)
    UINT16 *pwUDPData,      // IN - Recvd UDP data
    UINT16 cwUDPDataLength, // IN - Len of recvd data    
    BOOL   *pfJump,         // OUT - Set to TRUE if JUMPIMG command received
    EDBG_OS_CONFIG_DATA **ppCfgData) // OUT - If pfJump is set, this will contain a pointer to the
                                     // configuration paramters passed from eshell
{
    ETH_DBG_HDR *pHdr = (ETH_DBG_HDR *)pwUDPData;
    EDBG_ADDR SrcAddr;

    *pfJump = FALSE;
    
    if (pHdr->Id != EDBG_ID)
        return FALSE;

    // Toss all except admin messages
    if (pHdr->Service != EDBG_SVC_ADMIN)
        return TRUE;
    
    // Check and see if anyone has started a download.  If so, don't accept
    // any commands from different hosts.
    SrcAddrFromFrame(&SrcAddr,pFrameBuffer);
    if (pEshellHost && pEshellHost->dwIP && (pEshellHost->dwIP != SrcAddr.dwIP)) {
        char PeerIPString[16];  // inet_ntoa uses a static buffer
        strncpy(PeerIPString, inet_ntoa(SrcAddr.dwIP), 15);
        PeerIPString[15] = '\0';
        EdbgOutputDebugString("TFTP download started previously by host %s, ignoring cmd from %s\r\n",
                           inet_ntoa(pEshellHost->dwIP), PeerIPString);
        return TRUE;
    }
    
    switch (pHdr->Cmd)
    {
        case EDBG_CMD_JUMPIMG:
            EdbgOutputDebugString("Got EDBG_CMD_JUMPIMG\r\n");
            *pfJump = TRUE;
            
            // Set field in driver globals indicating address of host that is starting us
            if (pEshellHost)
                memcpy(pEshellHost, &SrcAddr, sizeof(EDBG_ADDR));
            
            // Fall through (data field is same as CONFIG command)
            
        case EDBG_CMD_OS_CONFIG:
        {
            EdbgOutputDebugString("Got EDBG_CMD_CONFIG, flags:0x%X\r\n",
                                  ((PEDBG_OS_CONFIG_DATA)pHdr->Data)->Flags);
            
            if (ppCfgData)
                *ppCfgData = (PEDBG_OS_CONFIG_DATA)pHdr->Data;
        }
        break;
        
        default:
            //EdbgOutputDebugString("Unrecognized EDBG cmd: 0x%X\r\n",pHdr->Cmd);
            return TRUE;
    }

    // Respond with ack
    {
        BYTE AckBuf[100];
        ETH_DBG_HDR *pAckHdr = (ETH_DBG_HDR *)(AckBuf+UDP_DATA_FRAME_OFFSET);
        EDBG_ADDR HostAddr;
        UINT16 AckLen = EDBG_DATA_OFFSET;
        
        memcpy(pAckHdr, pwUDPData, EDBG_DATA_OFFSET);
        pAckHdr->Flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;

        // Copy the address from the received frame
        SrcAddrFromFrame(&HostAddr, pFrameBuffer);
        pMyAddr->wPort = HostAddr.wPort;
        
        if (!EbootSendUDP(AckBuf, &HostAddr, pMyAddr, (BYTE *)pAckHdr, AckLen))
            EdbgOutputDebugString("Error in SendUDP\r\n");
    }

    return TRUE;
}


/*
 * SendBootme
 *
 *   Send a broadcast UDP packet to identify us as available to receive images
 *   Later, possibly investigate use of multicast instead, to reduce overhead
 *   for machines that don't care about these frames, and to extend the reach
 *   of these packets off the subnet.
 */
static UCHAR BootmeSeqNum = 0;

void
EbootSendBootme(EDBG_ADDR *pMyAddr, UCHAR VersionMajor, UCHAR VersionMinor, char *szPlatformString, char *szDeviceName, UCHAR CPUId, DWORD dwBootFlags)
{
    EDBG_ADDR DestAddr;
    UCHAR BootmeBuf[sizeof(ETH_DBG_HDR)+sizeof(EDBG_BOOTME_DATA)+UDP_DATA_FRAME_OFFSET];
    char DevNumBuf[6];
    ETH_DBG_HDR      *pHdr = (ETH_DBG_HDR *)(BootmeBuf + UDP_DATA_FRAME_OFFSET);
    EDBG_BOOTME_DATA *pData = (EDBG_BOOTME_DATA *)(pHdr->Data);

    // Format BOOTME message
    pHdr->Id = EDBG_ID;
    pHdr->Service = EDBG_SVC_ADMIN;
    pHdr->Flags = EDBG_FL_FROM_DEV;
    pHdr->SeqNum = BootmeSeqNum++;
    pHdr->Cmd = EDBG_CMD_BOOTME;

    memset(pData,0,sizeof(EDBG_BOOTME_DATA));
    pData->VersionMajor = VersionMajor;
    pData->VersionMinor = VersionMinor;
    pData->uBootmeVer = EDBG_CURRENT_BOOTME_VERSION;
    pData->dwBootFlags = dwBootFlags;
    memcpy(&pData->MACAddr, pMyAddr->wMAC, sizeof(pData->MACAddr));
    memcpy(&pData->IPAddr, &pMyAddr->dwIP, sizeof(pData->IPAddr));
    strncpy(pData->PlatformId, szPlatformString, sizeof(pData->PlatformId) - 1);
    pData->PlatformId[sizeof(pData->PlatformId) - 1] = '\0';

    if (szDeviceName) {
        strncpy(pData->DeviceName, szDeviceName, sizeof(pData->DeviceName) - 1);
        pData->DeviceName[sizeof(pData->DeviceName) - 1] = '\0';
    } else {
        // Device name based on platform ID and last word of MAC address
        strncpy(pData->DeviceName, szPlatformString, sizeof(pData->DeviceName) - 6);
        pData->DeviceName[sizeof(pData->DeviceName) - 6] = '\0';
        strcat(pData->DeviceName, _itoa(ntohs(pMyAddr->wMAC[2]), DevNumBuf, 10));
    }
   
    pData->CPUId      = CPUId;
    
#if 0
    // Send as a broadcast UDP frame on our subnet
    memcpy(&DestAddr.dwIP, &pMyAddr->dwIP, sizeof(DestAddr.dwIP));
    DestAddr.dwIP |= ~SubnetMask;
#else
    // Use local broadcast for now
    memset(&DestAddr.dwIP, 0xFF, sizeof(DestAddr.dwIP));
#endif    
    memset(&DestAddr.wMAC, 0xFF, sizeof(DestAddr.wMAC));
    DestAddr.wPort = htons(EDBG_DOWNLOAD_PORT);

    pMyAddr->wPort = htons(EDBG_DOWNLOAD_PORT);
    
    if (!EbootSendUDP(BootmeBuf, &DestAddr, pMyAddr, (BYTE *)pHdr,
                      EDBG_DATA_OFFSET+sizeof(EDBG_BOOTME_DATA)))
        EdbgOutputDebugString("SendBootme()::Error on SendUDP() call\r\n");
    else
        EdbgOutputDebugString("Sent BOOTME to %s\r\n", inet_ntoa(DestAddr.dwIP));
}

⌨️ 快捷键说明

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