Add Linux version of GenBootSector for DuetPkg to generate Boot image.Now only floppy...
authorqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 24 Mar 2009 09:11:18 +0000 (09:11 +0000)
committerqhuang8 <qhuang8@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 24 Mar 2009 09:11:18 +0000 (09:11 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1532 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/GnuGenBootSector/FatFormat.h [new file with mode: 0644]
Source/C/GnuGenBootSector/GNUmakefile [new file with mode: 0644]
Source/C/GnuGenBootSector/GnuGenBootSector.c [new file with mode: 0644]

diff --git a/Source/C/GnuGenBootSector/FatFormat.h b/Source/C/GnuGenBootSector/FatFormat.h
new file mode 100644 (file)
index 0000000..f24b4ee
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file\r
+\r
+  Fat file system structure and definition.\r
+\r
+Copyright 2006 - 2008, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+--*/\r
+\r
+#ifndef _FAT_BPB_H_\r
+#define _FAT_BPB_H_\r
+\r
+#include "CommonLib.h"\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  //\r
+  // Fat common field\r
+  //\r
+  UINT8              BS_jmpBoot[3];\r
+  CHAR8              BS_OEMName[8];\r
+  UINT16             BPB_BytsPerSec;\r
+  UINT8              BPB_SecPerClus;\r
+  UINT16             BPB_RsvdSecCnt;\r
+  UINT8              BPB_NumFATs;\r
+  UINT16             BPB_RootEntCnt;\r
+  UINT16             BPB_TotSec16;\r
+  UINT8              BPB_Media;\r
+  UINT16             BPB_FATSz16;\r
+  UINT16             BPB_SecPerTrk;\r
+  UINT16             BPB_NumHeads;\r
+  UINT32             BPB_HiddSec;\r
+  UINT32             BPB_TotSec32;\r
+\r
+  //\r
+  // Fat12/16 specific field\r
+  //\r
+  UINT8              BS_DrvNum;\r
+  UINT8              BS_Reserved1;\r
+  UINT8              BS_BootSig;\r
+  UINT32             BS_VolID;\r
+  CHAR8              BS_VolLab[11];\r
+  CHAR8              BS_FilSysType[8];\r
+\r
+  //\r
+  // Boot Code and Data\r
+  //\r
+  UINT8              Reserved[448];\r
+\r
+  //\r
+  // Fat common signature - 0xAA55\r
+  //\r
+  UINT16             Signature;\r
+} FAT12_16_BPB_STRUCT;\r
+\r
+typedef struct {\r
+  //\r
+  // Fat common field\r
+  //\r
+  UINT8              BS_jmpBoot[3];\r
+  CHAR8              BS_OEMName[8];\r
+  UINT16             BPB_BytsPerSec;\r
+  UINT8              BPB_SecPerClus;\r
+  UINT16             BPB_RsvdSecCnt;\r
+  UINT8              BPB_NumFATs;\r
+  UINT16             BPB_RootEntCnt;\r
+  UINT16             BPB_TotSec16;\r
+  UINT8              BPB_Media;\r
+  UINT16             BPB_FATSz16;\r
+  UINT16             BPB_SecPerTrk;\r
+  UINT16             BPB_NumHeads;\r
+  UINT32             BPB_HiddSec;\r
+  UINT32             BPB_TotSec32;\r
+\r
+  //\r
+  // Fat32 specific field\r
+  //\r
+  UINT32             BPB_FATSz32;\r
+  UINT16             BPB_ExtFlags;\r
+  UINT16             BPB_FSVer;\r
+  UINT32             BPB_RootClus;\r
+  UINT16             BPB_FSInfo;\r
+  UINT16             BPB_BkBootSec;\r
+  UINT8              BPB_Reserved[12];\r
+  UINT8              BS_DrvNum;\r
+  UINT8              BS_Reserved1;\r
+  UINT8              BS_BootSig;\r
+  UINT32             BS_VolID;\r
+  CHAR8              BS_VolLab[11];\r
+  CHAR8              BS_FilSysType[8];\r
+\r
+  //\r
+  // Boot Code and Data\r
+  //\r
+  UINT8              Reserved[420];\r
+\r
+  //\r
+  // Fat common signature - 0xAA55\r
+  //\r
+  UINT16             Signature;\r
+} FAT32_BPB_STRUCT;\r
+\r
+typedef union {\r
+  FAT12_16_BPB_STRUCT   Fat12_16;\r
+  FAT32_BPB_STRUCT      Fat32;\r
+} FAT_BPB_STRUCT;\r
+\r
+typedef enum {\r
+  FatTypeUnknown,\r
+  FatTypeFat12,\r
+  FatTypeFat16,\r
+  FatTypeFat32,\r
+  FatTypeMax\r
+} FAT_TYPE;\r
+\r
+typedef struct {\r
+  CHAR8              DIR_Name[11];\r
+  UINT8              DIR_Attr;\r
+  UINT8              DIR_NTRes;\r
+  UINT8              DIR_CrtTimeTenth;\r
+  UINT16             DIR_CrtTime;\r
+  UINT16             DIR_CrtDate;\r
+  UINT16             DIR_LstAccDate;\r
+  UINT16             DIR_FstClusHI;\r
+  UINT16             DIR_WrtTime;\r
+  UINT16             DIR_WrtDate;\r
+  UINT16             DIR_FstClusLO;\r
+  UINT32             DIR_FileSize;\r
+} FAT_DIRECTORY_ENTRY;\r
+\r
+#pragma pack()\r
+\r
+#define FAT_MAX_FAT12_CLUSTER         0xFF5\r
+#define FAT_MAX_FAT16_CLUSTER         0xFFF5\r
+\r
+#define FAT_BS_SIGNATURE      0xAA55\r
+#define FAT_BS_BOOTSIG        0x29\r
+#define FAT_BS_JMP1           0xEB\r
+#define FAT_BS_JMP2           0xE9\r
+#define FAT_FILSYSTYPE        "FAT     "\r
+#define FAT12_FILSYSTYPE      "FAT12   "\r
+#define FAT16_FILSYSTYPE      "FAT16   "\r
+#define FAT32_FILSYSTYPE      "FAT32   "\r
+\r
+#endif\r
diff --git a/Source/C/GnuGenBootSector/GNUmakefile b/Source/C/GnuGenBootSector/GNUmakefile
new file mode 100644 (file)
index 0000000..c0261e9
--- /dev/null
@@ -0,0 +1,10 @@
+ARCH ?= IA32
+MAKEROOT ?= ..
+
+APPNAME = GnuGenBootSector
+
+LIBS = -lCommon
+
+OBJECTS = GnuGenBootSector.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/Source/C/GnuGenBootSector/GnuGenBootSector.c b/Source/C/GnuGenBootSector/GnuGenBootSector.c
new file mode 100644 (file)
index 0000000..869f879
--- /dev/null
@@ -0,0 +1,380 @@
+/** @file\r
+\r
+Copyright 2006 - 2009, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  GnuGenBootSector.c\r
+  \r
+Abstract:\r
+  Reading/writing MBR/DBR.\r
+  NOTE:\r
+    If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.\r
+    If we process DBR, we will patch MBR to set first partition active if no active partition exists.\r
+\r
+**/\r
+\r
+#include "CommonLib.h"\r
+#include <errno.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+//\r
+// Utility Name\r
+//\r
+#define UTILITY_NAME  "GnuGenBootSector"\r
+\r
+//\r
+// Utility version information\r
+//\r
+#define UTILITY_MAJOR_VERSION 0\r
+#define UTILITY_MINOR_VERSION 1\r
+\r
+#define MAX_DRIVE                             26\r
+#define PARTITION_TABLE_OFFSET                0x1BE\r
+\r
+#define SIZE_OF_PARTITION_ENTRY               0x10\r
+\r
+#define PARTITION_ENTRY_STARTLBA_OFFSET       8\r
+\r
+#define PARTITION_ENTRY_NUM                   4\r
+\r
+#define DRIVE_UNKNOWN     0\r
+#define DRIVE_NO_ROOT_DIR 1\r
+#define DRIVE_REMOVABLE   2\r
+#define DRIVE_FIXED       3\r
+#define DRIVE_REMOTE      4\r
+#define DRIVE_CDROM       5\r
+#define DRIVE_RAMDISK     6\r
+\r
+typedef struct _DRIVE_TYPE_DESC {\r
+  UINTN  Type;\r
+  CHAR8  *Description;\r
+} DRIVE_TYPE_DESC;\r
+\r
+#define DRIVE_TYPE_ITEM(x) {x, #x}\r
+\r
+DRIVE_TYPE_DESC DriveTypeDesc[] = {\r
+  DRIVE_TYPE_ITEM (DRIVE_UNKNOWN),\r
+  DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR),\r
+  DRIVE_TYPE_ITEM (DRIVE_REMOVABLE),\r
+  DRIVE_TYPE_ITEM (DRIVE_FIXED),\r
+  DRIVE_TYPE_ITEM (DRIVE_REMOTE),\r
+  DRIVE_TYPE_ITEM (DRIVE_CDROM),\r
+  DRIVE_TYPE_ITEM (DRIVE_RAMDISK),\r
+  {(UINTN) -1, NULL}\r
+};\r
+\r
+typedef struct _DRIVE_INFO {\r
+  CHAR8             VolumeLetter;\r
+  DRIVE_TYPE_DESC   *DriveType;\r
+  UINTN             DiskNumber;\r
+} DRIVE_INFO;\r
+\r
+typedef enum {\r
+  PathUnknown,\r
+  PathFile,\r
+  PathFloppy,\r
+  PathUsb,\r
+  PathIde\r
+} PATH_TYPE;\r
+\r
+typedef struct _PATH_INFO {\r
+  CHAR8            *Path;\r
+  CHAR8            PhysicalPath[260];\r
+  PATH_TYPE        Type;\r
+  BOOLEAN          Input;\r
+} PATH_INFO;\r
+\r
+typedef enum {\r
+  ErrorSuccess,\r
+  ErrorFileCreate,\r
+  ErrorFileReadWrite,\r
+  ErrorNoMbr,\r
+  ErrorFatType,\r
+  ErrorPath,\r
+} ERROR_STATUS;\r
+\r
+CHAR8 *ErrorStatusDesc[] = {\r
+  "Success",\r
+  "Failed to create files",\r
+  "Failed to read/write files",\r
+  "No MBR exists",\r
+  "Failed to detect Fat type",\r
+  "Inavlid path"\r
+};\r
+\r
+\r
+//UnSupported Windows API functions.\r
+UINTN GetLogicalDrives(void) { return 1; }\r
+\r
+\r
+\r
+/**\r
+  Get path information, including physical path for Linux platform.\r
+\r
+  @param PathInfo   Point to PATH_INFO structure.\r
+\r
+  @return whether path is valid.\r
+**/\r
+ERROR_STATUS\r
+GetPathInfo (\r
+  PATH_INFO   *PathInfo\r
+  )\r
+{\r
+  FILE        *f;\r
+\r
+  if (strncmp(PathInfo->Path, "/dev/", 5) == 0) {\r
+    //\r
+    // Process disk path here.\r
+    // \r
+    \r
+    // Process floppy disk\r
+    if (PathInfo->Path[5] == 'f' && PathInfo->Path[6] == 'd' && PathInfo->Path[8] == '\0') {\r
+      PathInfo->Type = PathFloppy;\r
+      strcpy (PathInfo->PhysicalPath, PathInfo->Path);\r
+      \r
+      return ErrorSuccess;\r
+    } else {\r
+    // Other disk types is not supported yet.\r
+    fprintf (stderr, "ERROR: It's not a floppy disk!\n");\r
+    return ErrorPath;\r
+    }  \r
+     \r
+    // Try to open the device.   \r
+    f = fopen(PathInfo->Path,"r");\r
+    if (f == NULL) {\r
+      printf ("error :open device failed!\n");\r
+      return ErrorPath;\r
+    }\r
+    fclose (f);\r
+    return ErrorSuccess;\r
+  }\r
\r
+  // Process file path here.\r
+  PathInfo->Type = PathFile;\r
+  if (PathInfo->Input) {\r
+    // If path is file path, check whether file is valid.\r
+    printf("Path = %s\n",PathInfo->Path);\r
+    f = fopen (PathInfo->Path, "r");\r
+    if (f == NULL) {\r
+      fprintf (stderr, "Test error E2003: File was not provided!\n");\r
+      return ErrorPath;\r
+    }\r
+    fclose (f);\r
+  }\r
+\r
+  strcpy(PathInfo->PhysicalPath, PathInfo->Path);\r
+  return ErrorSuccess;\r
+\r
+}\r
+\r
+VOID\r
+ListDrive (\r
+  VOID\r
+  )\r
+{\r
+  printf("-l or -list not supported!\n");\r
+}\r
+\r
+/**\r
+  Writing or reading boot sector or MBR according to the argument. \r
+   \r
+  @param InputInfo PATH_INFO instance for input path\r
+  @param OutputInfo PATH_INFO instance for output path\r
+  @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector\r
+  \r
+  @return ERROR_STATUS\r
+ **/\r
+ERROR_STATUS\r
+ProcessBsOrMbr (\r
+  PATH_INFO     *InputInfo,\r
+  PATH_INFO     *OutputInfo,\r
+  BOOLEAN       ProcessMbr\r
+  )\r
+{\r
+  CHAR8 FirstSector[0x200] = {0};\r
+  CHAR8 FirstSectorBackup[0x200] = {0};\r
+  \r
+  FILE *InputFile;\r
+  FILE *OutputFile;\r
+  \r
+  \r
+  InputFile = fopen(InputInfo->PhysicalPath, "r");\r
+  if (InputFile == NULL) {\r
+    return ErrorFileReadWrite;\r
+  }\r
+   \r
+  if (0x200 != fread(FirstSector, 1, 0x200, InputFile)) {\r
+    fclose(InputFile);\r
+    return ErrorFileReadWrite;\r
+  }\r
+  \r
+  fclose(InputFile);\r
+  \r
+  //Not support USB and IDE.\r
+  if (InputInfo->Type == PathUsb) {\r
+    printf("USB has not been supported yet!");\r
+    return ErrorSuccess;\r
+  }\r
+  \r
+  if (InputInfo->Type == PathIde) {\r
+    printf("IDE has not been supported yet!");\r
+    return ErrorSuccess;\r
+  } \r
+  \r
+  //Process Floppy Disk\r
+  OutputFile = fopen(OutputInfo->PhysicalPath, "w");\r
+  if (OutputFile == NULL) {\r
+    return ErrorFileReadWrite;\r
+  }  \r
+  \r
+  if (OutputInfo->Type != PathFile) {\r
+    if (ProcessMbr) {\r
+      //\r
+      // Use original partition table\r
+      //\r
+      if (0x200 != fread (FirstSectorBackup, 1, 0x200, OutputFile)) {\r
+        fclose(OutputFile);\r
+        return ErrorFileReadWrite; \r
+        }\r
+      memcpy (FirstSector + 0x1BE, FirstSectorBackup + 0x1BE, 0x40);  \r
+    }\r
+  }\r
+  if(0x200 != fwrite(FirstSector, 1, 0x200, OutputFile)) {\r
+    fclose(OutputFile);\r
+    return ErrorFileReadWrite;\r
+  }\r
+  \r
+  fclose(OutputFile);\r
+  return ErrorSuccess;\r
+}\r
+\r
+\r
+/**\r
+\r
+  Displays the standard utility information to SDTOUT\r
+\r
+**/\r
+VOID\r
+Version (\r
+  VOID\r
+  )\r
+{\r
+  printf ("%s v%d.%d -Utility to retrieve and update the boot sector or MBR.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n");\r
+}\r
+\r
+\r
+VOID\r
+PrintUsage (\r
+  VOID\r
+    )\r
+{\r
+  Version();\r
+  printf ("\nUsage: \n\\r
+   GenBootSector\n\\r
+     [-l, --list list disks]\n\\r
+     [-i, --input Filename]\n\\r
+     [-o, --output Filename]\n\\r
+     [-m, --mbr process the MBR also]\n\\r
+     [-v, --verbose]\n\\r
+     [--version]\n\\r
+     [-q, --quiet disable all messages except fatal errors]\n\\r
+     [-d, --debug[#]\n\\r
+     [-h, --help]\n");\r
+}\r
+\r
+INTN\r
+main (\r
+  INTN  argc,\r
+  CHAR8 *argv[]\r
+  )\r
+{\r
+  CHAR8          *AppName;\r
+  INTN           Index;\r
+  BOOLEAN        ProcessMbr;\r
+  ERROR_STATUS   Status;\r
+  PATH_INFO      InputPathInfo;\r
+  PATH_INFO      OutputPathInfo;\r
+  \r
+  ZeroMem(&InputPathInfo, sizeof(PATH_INFO));\r
+  ZeroMem(&OutputPathInfo, sizeof(PATH_INFO));\r
+  \r
+  AppName = *argv;\r
+  argv ++;\r
+  argc --;\r
+  \r
+  ProcessMbr    = FALSE;\r
+\r
+  if (argc == 0) {\r
+    PrintUsage();\r
+    return 0;\r
+  }\r
+   \r
+  //\r
+  // Parse command line\r
+  //\r
+  for (Index = 0; Index < argc; Index ++) {\r
+    if ((stricmp (argv[Index], "-l") == 0) || (stricmp (argv[0], "--list") == 0)) {\r
+      ListDrive ();\r
+      return 0;\r
+    }\r
+    else if ((stricmp (argv[Index], "-m") == 0) || (stricmp (argv[Index], "--mbr") == 0)) {\r
+      ProcessMbr = TRUE;\r
+    }\r
+    else if ((stricmp (argv[Index], "-i") == 0) || (stricmp (argv[Index], "--input") == 0)) {\r
+      InputPathInfo.Path  = argv[Index + 1];\r
+      InputPathInfo.Input = TRUE;\r
+      ++Index;\r
+    }\r
+    else if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {\r
+      OutputPathInfo.Path  = argv[Index + 1];\r
+      OutputPathInfo.Input = FALSE;\r
+      ++Index;\r
+    }\r
+    else {\r
+      PrintUsage ();\r
+      return 1;\r
+    }\r
+  }\r
+\r
+\r
+  if ((GetPathInfo(&InputPathInfo)  != ErrorSuccess) ||\r
+      (GetPathInfo(&OutputPathInfo) != ErrorSuccess)) {\r
+    return 1;\r
+  }\r
+  \r
+  //\r
+  // Process DBR (Patch or Read)\r
+  //\r
+  Status = ProcessBsOrMbr (&InputPathInfo, &OutputPathInfo, ProcessMbr);\r
+\r
+  if (Status == ErrorSuccess) {\r
+    fprintf (\r
+      stdout, \r
+      "%s %s: successful!\n", \r
+      (OutputPathInfo.Type != PathFile) ? "Write" : "Read", \r
+      ProcessMbr ? "MBR" : "DBR"\r
+      );\r
+    return 0;\r
+  } else {\r
+    fprintf (\r
+      stderr, \r
+      "%s: %s %s: failed - %s (LastError: 0x%x)!\n",\r
+      (Status == ErrorNoMbr) ? "WARNING" : "ERROR",\r
+      (OutputPathInfo.Type != PathFile) ? "Write" : "Read", \r
+      ProcessMbr ? "MBR" : "DBR", \r
+      ErrorStatusDesc[Status],\r
+      errno \r
+      );\r
+    return 1;\r
+  }\r
+}\r