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

📄 main.c

📁 WINCE BOIS启动源码
💻 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: Utility to update the active partition boot sector and update the first root directory
          entry to support finding and loading the Windows CE BIOS bootloader.  It also transfers
		  the bootloader image.

Functions:

Notes:

    The following assumptions have been made - these are areas that might be revisited in a future release:
	
	* The boot sector and bootloader designs assume the loader image will be a contiguous grouping of sectors
	  on the storage device.  To help ensure this is true, the storage device should first be formatted and
	  before copying other files, this utility should be run to transfer the loader.  Note that bad sectors
	  are not accounted for in this utility and could cause problems.
	  
	* It's assumed that the storage device is fully prepared before running this utility.  Prepared means that
	  there is an configured Active partition on the storage device and that it has been formatted (not to
	  include DOS system files).
	  
	* The bootloader is assumed to lie in the root directory of the storage device.  If it needs to be placed
	  somewhere else, this utility and the boot sector will need to be updated. 

--*/

#include <stdio.h>
#include <malloc.h>      
#include <memory.h>

//
// FAT filesystem constants.
//
#define SECTOR_SIZE 	 0x200
#define PARTTBL_SIZE 	    64
#define PARTSIG_SIZE 	     2
#define PARTACTV_FLAG 	  0x80
#define MAX_PARTITION 	     4

//
// Disk constants.
//
#define FIXED_DISK_ID     0x80
#define FLOPPY_DISK_ID       0
#define FLOPPY_IO_RETRIES    2
#define FIXDISK_IO_RETRIES   0

#define TRUE	             1
#define FALSE	             0

//
// Helper macros.
//
#define TOLOWER(a) ((a >= 0x41 && a <= 0x5a) ? (a + 0x20) : a)

//
// FAT directory entry structure.
//
#pragma pack(1)
typedef struct
{
    unsigned char  FileName[8];
    unsigned char  FileExt[3];
    unsigned char  FATTr;
    unsigned char  FOO[10];
    unsigned short LModTime;
    unsigned short LModDate;
    unsigned short FirstClust;
    unsigned long  FileSize;
} DIRENTRY, *PDIRENTRY;

//
// BIOS parameter block structure.
//
#pragma pack(1)
typedef struct BIOSPB_TAG
{
    unsigned char  VersionId[8];
    unsigned short BytesPerSect;
    unsigned char  SectsPerClust;
    unsigned short RsvdSects;
    unsigned char  NumFATs;
    unsigned short NumRootEntries;
    unsigned short SectsPerPart;
    unsigned char  MediaDesc;
    unsigned short SectsPerFAT;
    unsigned short SectsPerTrack;
    unsigned short NumHeads;
    unsigned short NumHiddenSectL;
    unsigned short NumHiddenSectH;
    unsigned short TotalSectorsL;
    unsigned short TotalSectorsH;
    unsigned char  DriveId;
    unsigned char  TempVal;
    unsigned char  ExtRecordSig;
    unsigned short VolSerNumL;
    unsigned short VolSerNumH;
    unsigned char  VolLabel[11];
    unsigned char  TypeFAT[8];
} BIOSPB, *PBIOSPB;

//
// MBR partition table entry structure.
//
#pragma pack(1)
typedef struct
{
    unsigned char ActiveFlag;
    unsigned char SSector;
    unsigned char SHead;
    unsigned char SCylinder;
    unsigned char Type;
    unsigned char ESector;
    unsigned char EHead;
    unsigned char ECylinder;
    unsigned long SLBA;
    unsigned long Size;
} PARTTE, *PPARTTE;

//
// User parameters structure.
//
typedef struct
{
	unsigned short Offset;
	unsigned char *pSectorFileName;
	unsigned char *pLoaderFileName;
	unsigned char  DriveNum;
	unsigned char  DriveLetter;
} PARAMS, *PPARAMS;

//
// Globals.
//
unsigned long gActivePartLBA;			// LBA address of active partition.
unsigned char gTempSector[SECTOR_SIZE];	// Buffer for sector reads.

//
// Function prototypes.
//
static int ReadSector(unsigned char Drive, unsigned short Cylinder, unsigned char Head, unsigned char Sector, unsigned char *pBuffer);
static int WriteSector(unsigned char Drive, unsigned short Cylinder, unsigned char Head, unsigned char Sector, unsigned char *pBuffer);
static int WriteBootSector(unsigned char *pSector, unsigned char DriveNum, unsigned short Offset, PBIOSPB pBPB);
static int ParseArguments(int ArgC, char **ArgV, PPARAMS pUserParams);
static int TransferLoader(PPARAMS pParams, PBIOSPB pBPB);
static void LBA2PCHS(unsigned long LBA, unsigned short *pCylinder, unsigned char  *pHead, unsigned char  *pSector, PBIOSPB pBPB);


//
// Main routine.
//
int main(int ArgC, char **ArgV)
{
	PARAMS UserParams;
	FILE *FP = NULL;
    BIOSPB BPB;
	unsigned short DataSize = 0;
    unsigned char Sector[SECTOR_SIZE];

    // If no parameters provided, user is looking for help.
	//
	if (ArgC == 1)
		goto UsageMessage;

	// Parse user arguments.
	//
    if (ParseArguments(ArgC, ArgV, &UserParams))
	{
		printf("ERROR: Invalid command line.\r\n");
		goto UsageMessage;
	}

	// Open the boot sector file for reading.
	//
    FP = fopen(UserParams.pSectorFileName, "rb");
	if (FP == NULL)
	{
		printf("ERROR: Unable to open boot sector image (%s) for reading.\r\n", UserParams.pSectorFileName);
		goto Done;
	}

	// Read file into sector buffer (terminate with EOF encountered or we reach the
	// end of the sector buffer).
	//
	memset(Sector, 0, sizeof(SECTOR_SIZE));
	for (DataSize = 0 ; DataSize < SECTOR_SIZE && !feof(FP) ; DataSize++)
	{
		*(unsigned char *)(Sector + DataSize) = fgetc(FP);
	}

	// Update the boot sector.
	//
    if (WriteBootSector(Sector, UserParams.DriveNum, UserParams.Offset, &BPB))
	{
		printf("ERROR: Unable to write to boot sector.\r\n");
		goto Done;
	}

    // Transfer bootloader (copy it to the storage device, updating the root directory).
    //
    if (TransferLoader(&UserParams, &BPB))
	{
		printf("ERROR: Unable to copy to bootloader.\r\n");
		goto Done;
	}
    
Done:
    if (FP != NULL)
        fclose(FP);

    return(0);

UsageMessage:
    printf("Prepares the storage device to run the Windows CE BIOS bootloader.\r\n\r\n");
    printf("%s [-b:offset] bsectfile bldrfile drive\r\n\r\n", ArgV[0]);
	printf("[-b:offset]      - offsets specified bytes into the sector before writing\r\n");
	printf("bsectfile        - name of file that contains sector data\r\n");
	printf("bldrfile         - name of bootloader executable file\r\n");
	printf("drive            - driver letter (a:, c:, etc.)\r\n");

    return(0);
}


// 
// Write the specified sector buffer, with offset applied, to the boot sector and return the BIOS parameter
// block (BPB) contents to the caller.
//
static int WriteBootSector(unsigned char *pSector, unsigned char DriveNum, unsigned short Offset, PBIOSPB pBPB)
{
	int Status = 0;
	unsigned short Cylinder;
	unsigned char Head, Sector;
	unsigned char Count;
    PPARTTE pPartTable = NULL;

	// Check parameters.
    //
	if (!pSector || !pBPB)
		return(-1);

	// To find the active boot partition on a fixed disk, we need to look at the MBR.
	// At the end of the MBR is the partition table information.  An active flag
	// denotes the active partition entry and from this we can find the location 
	// of the boot sector.
    //
	// Note - we can skip much of this if we're writing to a floppy because the boot
	// sector is the first sector on the floppy.
	//

	if (DriveNum & FIXED_DISK_ID)	// Fixed disk.
	{
		// Read MBR.
		//
		if ((Status = ReadSector(DriveNum, 0, 0, 1, gTempSector)) != 0)
		{
			printf("ERROR: Unable to read the MBR (status=0x%x).\r\n", Status);
			return(-1);
		}

		// Search through partition table in the MBR for the active partition.
		//
		pPartTable = (PPARTTE)(gTempSector + SECTOR_SIZE - PARTSIG_SIZE - PARTTBL_SIZE);

		for(Count = 0 ; (Count < MAX_PARTITION) && (pPartTable->ActiveFlag != PARTACTV_FLAG); ++Count)
			++pPartTable;

		// Find active partition?
		//
		if (Count == MAX_PARTITION)
		{
			printf("ERROR: Unable to find active partition on drive 0x%x.\r\n", DriveNum);
			return(-1);
		}

		// Record starting cylinder, header, and sector values of active partition - this is the 
		// location of the partition's boot sector.
		//
		Cylinder = pPartTable->SCylinder;
		Head     = pPartTable->SHead;
		Sector   = pPartTable->SSector;

		gActivePartLBA = pPartTable->SLBA;

	#if 0
		printf("INFO: Found active partition (C:H:S = 0x%x:0x%x:0x%x).\r\n\r\n", Cylinder, Head, Sector);

		printf("Active Flag ...... 0x%02x\r\n", pPartTable->ActiveFlag);
		printf("Start Cylinder ... 0x%02x\r\n", pPartTable->SCylinder);
		printf("Start Head ....... 0x%02x\r\n", pPartTable->SHead);
		printf("Start Sector ..... 0x%02x\r\n", pPartTable->SSector);
		printf("Type ............. 0x%02x\r\n", pPartTable->Type);
		printf("End Cylinder ..... 0x%02x\r\n", pPartTable->ECylinder);
		printf("End Head ......... 0x%02x\r\n", pPartTable->EHead);
		printf("End Sector ....... 0x%02x\r\n", pPartTable->ESector);
		printf("Start LBA ........ 0x%08x\r\n", pPartTable->SLBA);
		printf("Size in Sectors .. 0x%08x\r\n\r\n", pPartTable->Size);
	#endif

	}
	else			// Floppy.
	{
		Cylinder = 0;
		Head     = 0;

⌨️ 快捷键说明

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