* [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
@ 2019-05-28 1:32 Zhang, Shenglei
2019-05-28 16:48 ` [edk2-devel] " Michael D Kinney
0 siblings, 1 reply; 4+ messages in thread
From: Zhang, Shenglei @ 2019-05-28 1:32 UTC (permalink / raw)
To: devel
GenBiosId is a tool to generate the BIOS ID binary file which uses
the data from the configuration file.
https://bugzilla.tianocore.org/show_bug.cgi?id=1846
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
---
BaseTools/Source/C/GenBiosId/GenBiosId.c | 627 +++++++++++++++++++++++
BaseTools/Source/C/GNUmakefile | 3 +-
BaseTools/Source/C/GenBiosId/BiosId.env | 27 +
BaseTools/Source/C/GenBiosId/GNUmakefile | 14 +
BaseTools/Source/C/GenBiosId/GenBiosId.h | 105 ++++
BaseTools/Source/C/GenBiosId/Makefile | 14 +
BaseTools/Source/C/Makefile | 3 +-
7 files changed, 791 insertions(+), 2 deletions(-)
create mode 100644 BaseTools/Source/C/GenBiosId/GenBiosId.c
create mode 100644 BaseTools/Source/C/GenBiosId/BiosId.env
create mode 100644 BaseTools/Source/C/GenBiosId/GNUmakefile
create mode 100644 BaseTools/Source/C/GenBiosId/GenBiosId.h
create mode 100644 BaseTools/Source/C/GenBiosId/Makefile
diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.c b/BaseTools/Source/C/GenBiosId/GenBiosId.c
new file mode 100644
index 000000000000..21d71d4ebd51
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GenBiosId.c
@@ -0,0 +1,627 @@
+/** @file
+This tool generates the BIOS ID binary file using the data from the configuration file.
+
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "GenBiosId.h"
+
+CHAR8 InputFileName[FILE_NAME_SIZE];
+CHAR8 OutputFileName[FILE_NAME_SIZE];
+CHAR8 OutputBatchFileName[FILE_NAME_SIZE];
+
+FILE *InputFile;
+FILE *OutputFile;
+FILE *OutputBatchFile;
+
+BIOS_ID_IMAGE BiosIdImage = {
+ { '$', 'I', 'B', 'I', 'O', 'S', 'I', '$' },
+ {
+ { ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' ') },
+ ATOU (' '),
+ ATOU ('.'),
+ { ATOU (' '), ATOU (' '), ATOU (' ') },
+ ATOU ('.'),
+ { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0') },
+ ATOU ('.'),
+ ATOU (' '),
+ { ATOU ('0'), ATOU ('0') },
+ ATOU ('.'),
+ { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
+ ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0') },
+ ATOU ('\0')
+ }
+};
+
+VOID
+PrintBanner (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ printf ("\n");
+ printf ("GenBiosId utility, version: v1.0 05/27/2018 \n");
+ printf ("Copyright (c) 2019, Intel Corporation. All rights reserved. \n");
+ printf ("\n");
+}
+
+VOID
+PrintUsage (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ printf ("Usage:\n");
+ printf ("GenBiosId -i ConfigFile -o OutputFile [-ob OutputBatchFile] \n");
+ printf ("\n");
+}
+
+CHAR8 *
+StripLeadingWhiteSpace (
+ IN CHAR8 *StrInput
+ )
+/*++
+
+Routine Description:
+
+ Strip the leading whitespoace off the given ASCII string.
+
+Arguments:
+
+ StrInput - the ASCII string that should be processed.
+
+Returns:
+
+ A pointer to the first non-whitespace character in the given string,
+ or NULL if the string was all whitespace.
+
+--*/
+{
+ if (StrInput == NULL) {
+ return NULL;
+ }
+
+ while (*StrInput != 0) {
+ if ((*StrInput == ' ') || (*StrInput == '\t') || (*StrInput == '\n')) {
+ ++StrInput;
+ } else {
+ return StrInput;
+ }
+ }
+
+ return NULL;
+}
+
+VOID
+ConvertToUnicode (
+ IN CHAR8 *StrAscii,
+ OUT CHAR16 *StrUnicode
+ )
+/*++
+
+Routine Description:
+
+ Convert the given ASCII string to Unicode without appending terminating 0x0000.
+
+Arguments:
+
+ StrAscii - the source ASCII string, null-terminated.
+
+ StrUnicode - the resulted Unicode string will be put here, without the terminating 0x0000.
+
+Returns:
+
+--*/
+{
+ if ((StrAscii == NULL) || (StrUnicode == NULL)) {
+ return;
+ }
+
+ while (*StrAscii != 0) {
+ *StrUnicode = ATOU (*StrAscii);
+ ++StrAscii;
+ ++StrUnicode;
+ }
+}
+
+VOID
+FillTimeStamp (
+ OUT CHAR16 *StrTimeStampUnicode
+ )
+/*++
+
+Routine Description:
+ The function generates the current timestamp in "YYMMDDHHMM" format
+ and puts it into the Unicode string supplied, without the null-terminator.
+
+Arguments:
+
+ StrTimeStampUnicode - The Unicode string which is filled on return with the current timestamp.
+
+Returns:
+
+--*/
+{
+ struct tm *Time;
+ time_t CurTime;
+ CHAR8 StrTime[11];
+
+ //
+ // Fetch the current time based on UTC timezone
+ //
+ time (&CurTime);
+ Time = gmtime (&CurTime);
+
+ if (NULL == Time) {
+ return;
+ }
+
+ sprintf (
+ StrTime,
+ "%02d%02d%02d%02d%02d",
+ (Time->tm_year + 1900) % 100, // Year is 1900-based, need only 2 digits.
+ Time->tm_mon + 1, // Month is zero based.
+ Time->tm_mday,
+ Time->tm_hour,
+ Time->tm_min
+ );
+
+ ConvertToUnicode (StrTime, StrTimeStampUnicode);
+}
+
+VOID
+ConvertToAscii (
+ IN CHAR16 *StrUnicode,
+ OUT CHAR8 *StrAscii
+ )
+/*++
+
+Routine Description:
+
+ Convert the given Unicode string to ASCII with appending terminating 0x00.
+
+Arguments:
+
+ StrUnicode - the source Unicode string, null-terminated.
+
+ StrAscii - the resulted ASCII string will be put here, with the terminating 0x00.
+
+Returns:
+
+--*/
+{
+ if ((StrUnicode == NULL) || (StrAscii == NULL)) {
+ return;
+ }
+
+ while (*StrUnicode != 0) {
+ *StrAscii = UTOA (*StrUnicode);
+ ++StrUnicode;
+ ++StrAscii;
+ }
+ *StrAscii = 0;
+}
+
+VOID
+PrintUnicodeString (
+ IN CHAR16 *StrUnicode
+ )
+/*++
+
+Routine Description:
+
+ Print the given Unicode string.
+
+Arguments:
+
+ StrUnicode - the null-terminated Unicode string to print.
+
+Returns:
+
+--*/
+{
+ if (StrUnicode == NULL) {
+ return;
+ }
+
+ while (*StrUnicode != 0) {
+ putchar ((CHAR8)(*StrUnicode));
+ ++StrUnicode;
+ }
+}
+
+EFI_STATUS
+ParseInputFile (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Parse the BIOS ID definition file and fill the BIOS ID structure, including timestamp.
+
+Arguments:
+
+Returns:
+
+ EFI_SUCCESS - The input file was parsed successfully.
+
+ EFI_INVALID_PARAMETER - The input file has incorrect format.
+
+--*/
+{
+ CHAR8 StrLine[MAX_LINE_SIZE];
+ CHAR8 StrFieldName[MAX_LINE_SIZE];
+ CHAR8 StrFieldValue[MAX_LINE_SIZE];
+ CHAR8 *Str;
+ UINT16 FieldsSet;
+ CHAR8 FormatString[MAX_FORMAT_STRING_SIZE];
+
+ FieldsSet = 0;
+ Str = NULL;
+
+ //
+ // Generate the format string for sscanf() function.
+ //
+ sprintf (FormatString, "%%%us = %%%us", (unsigned int) sizeof (StrFieldName) - 1, (unsigned int) sizeof (StrFieldValue) - 1);
+
+ while (fgets (StrLine, sizeof (StrLine) - 1, InputFile) != NULL) {
+ Str = StripLeadingWhiteSpace (StrLine);
+
+ //
+ // Check for whitespace string.
+ //
+ if (Str == NULL) {
+ continue;
+ }
+
+ //
+ // Check for comment string.
+ //
+ if (*Str == '#') {
+ continue;
+ }
+
+ if (sscanf (Str, FormatString, StrFieldName, StrFieldValue) != 2) {
+ continue;
+ }
+
+ if (strcmp (StrFieldName, NAME_BOARD_ID) == 0) {
+ if (strlen (StrFieldValue) == CHARS_BOARD_ID) {
+ ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.BoardId);
+ FieldsSet |= FIELD_BOARD_ID;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_ID, CHARS_BOARD_ID);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_BOARD_REV) == 0) {
+ if (strlen (StrFieldValue) == CHARS_BOARD_REV) {
+ ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.BoardRev));
+ FieldsSet |= FIELD_BOARD_REV;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_REV, CHARS_BOARD_REV);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_BOARD_EXT) == 0) {
+ if (strlen (StrFieldValue) == CHARS_BOARD_EXT) {
+ ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.BoardExt);
+ FieldsSet |= FIELD_BOARD_EXT;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_BOARD_EXT, CHARS_BOARD_EXT);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_BUILD_TYPE) == 0) {
+ if (strlen (StrFieldValue) == CHARS_BUILD_TYPE) {
+ if ((strcmp (StrFieldValue, "D") == 0) ||
+ (strcmp (StrFieldValue, "A") == 0) ||
+ (strcmp (StrFieldValue, "B") == 0) ||
+ (strcmp (StrFieldValue, "P") == 0)) {
+ ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.BuildType));
+ FieldsSet |= FIELD_BUILD_TYPE;
+ } else {
+ printf ("Error: value of %s should be one of %s, %s, %s or %s\n", NAME_BUILD_TYPE, "D", "A", "B", "P");
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_BUILD_TYPE, CHARS_BUILD_TYPE);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_VERSION_MAJOR) == 0) {
+ if (strlen (StrFieldValue) == CHARS_VERSION_MAJOR) {
+ ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.VersionMajor);
+ FieldsSet |= FIELD_VERSION_MAJOR;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_VERSION_MAJOR, CHARS_VERSION_MAJOR);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_VERSION_MINOR) == 0) {
+ if (strlen (StrFieldValue) == CHARS_VERSION_MINOR) {
+ ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.VersionMinor);
+ FieldsSet |= FIELD_VERSION_MINOR;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_VERSION_MINOR, CHARS_VERSION_MINOR);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_DATE) == 0) {
+ if (strlen (StrFieldValue) == CHARS_DATE) {
+ ConvertToUnicode (StrFieldValue, BiosIdImage.BiosIdString.TimeStamp);
+ FieldsSet |= FIELD_DATE;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_DATE, CHARS_DATE);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (strcmp (StrFieldName, NAME_TIME) == 0) {
+ if (strlen (StrFieldValue) == CHARS_TIME) {
+ ConvertToUnicode (StrFieldValue, &(BiosIdImage.BiosIdString.TimeStamp[CHARS_DATE]));
+ FieldsSet |= FIELD_TIME;
+ } else {
+ printf ("Error: value of %s should have exactly %d chars\n", NAME_TIME, CHARS_TIME);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ }
+
+ if ((FieldsSet & (FIELD_DATE | FIELD_TIME)) != (FIELD_DATE | FIELD_TIME)) {
+ //
+ // Fill the timestamp.
+ //
+ FillTimeStamp (BiosIdImage.BiosIdString.TimeStamp);
+ FieldsSet |= (FIELD_DATE | FIELD_TIME);
+ }
+
+ //
+ // Exit if not all fields were supplied.
+ //
+ if ((FieldsSet & FIELD_ALL) != FIELD_ALL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteOutputFile (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Write the BIOS ID structure to the output file.
+
+Arguments:
+
+Returns:
+
+ EFI_SUCCESS - The output file was created successfully.
+
+ EFI_DEVICE_ERROR - There was a file write error.
+
+--*/
+{
+ if (fwrite (&BiosIdImage, sizeof (BIOS_ID_IMAGE), 1, OutputFile) != 1) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteOutputBatchFile (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Write "SET BIOS_ID=" and BIOS ID string to the batch file.
+
+Arguments:
+
+Returns:
+
+ EFI_SUCCESS - The output batch file was created successfully.
+
+ EFI_DEVICE_ERROR - There was a file write error.
+
+--*/
+{
+#ifndef __GNUC__
+ CHAR8 BatchFileContent[MAX_LINE_SIZE] = "SET BIOS_ID=";
+#else
+ CHAR8 BatchFileContent[MAX_LINE_SIZE] = "export BIOS_ID=";
+#endif
+
+ CHAR8 BiosIdString[sizeof (BIOS_ID_STRING)];
+
+ ConvertToAscii ((CHAR16 *) (&(BiosIdImage.BiosIdString)), BiosIdString);
+ strcat (BatchFileContent, BiosIdString);
+
+ if (fwrite (BatchFileContent, strlen (BatchFileContent), 1, OutputBatchFile) != 1) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+int
+main (
+ IN int argc,
+ IN CHAR8 *argv[]
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ argc - Number of command-line arguments.
+
+ argv - Array of command-line arguments.
+
+Returns:
+
+ 0 - The operation completed successfully.
+
+ -1 - An error occurred.
+
+--*/
+{
+ int Status;
+
+ Status = 0;
+
+ PrintBanner ();
+
+ if ((argc != 5) && (argc != 7)) {
+ PrintUsage ();
+ Status = -1;
+ goto Done;
+ }
+
+ if (strcmp (argv[1], "-i") == 0) {
+ if (strlen (argv[2])> sizeof (InputFileName) - 1) {
+ printf ("The InputFileName %s is too long \n", argv[2]);
+ Status = -1;
+ goto Done;
+ }
+ strncpy (InputFileName, argv[2], sizeof (InputFileName) - 1);
+ InputFileName[sizeof (InputFileName) - 1] = 0;
+ } else {
+ PrintUsage ();
+ Status = -1;
+ goto Done;
+ }
+
+ if (strcmp (argv[3], "-o") == 0) {
+ if (strlen (argv[4])> sizeof (OutputFileName) - 1) {
+ printf ("OutputFileName %s is too long \n", argv[4]);
+ Status = -1;
+ goto Done;
+ }
+ strncpy (OutputFileName, argv[4], sizeof (OutputFileName) - 1);
+ OutputFileName[sizeof (OutputFileName) - 1] = 0;
+ } else {
+ PrintUsage ();
+ Status = -1;
+ goto Done;
+ }
+
+ if (argc == 7) {
+ if (strcmp (argv[5], "-ob") == 0) {
+ if (strlen (argv[6])> sizeof (OutputBatchFileName) - 1) {
+ printf ("The OutputBatchFileName %s is too long \n", argv[6]);
+ Status = -1;
+ goto Done;
+ }
+ strncpy (OutputBatchFileName, argv[6], sizeof (OutputBatchFileName) - 1);
+ OutputBatchFileName[sizeof (OutputBatchFileName) - 1] = 0;
+ } else {
+ PrintUsage ();
+ Status = -1;
+ goto Done;
+ }
+ }
+
+ InputFile = NULL;
+ OutputFile = NULL;
+ OutputBatchFile = NULL;
+
+ InputFile = fopen (InputFileName, "r");
+ if (InputFile == NULL) {
+ printf ("Error opening input file: %s\n", InputFileName);
+ Status = -1;
+ goto Done;
+ }
+
+ OutputFile = fopen (OutputFileName, "wb");
+ if (OutputFile == NULL) {
+ printf ("Error creating output file: %s\n", OutputFileName);
+ Status = -1;
+ goto Done;
+ }
+
+ if (argc == 7) {
+ OutputBatchFile = fopen (OutputBatchFileName, "wb");
+ if (OutputBatchFile == NULL) {
+ printf ("Error creating output batch file: %s\n", OutputBatchFileName);
+ Status = -1;
+ goto Done;
+ }
+ }
+
+ if (ParseInputFile () != EFI_SUCCESS) {
+ printf ("Invalid config file format: %s\n", InputFileName);
+ Status = -1;
+ goto Done;
+ }
+
+ if (WriteOutputFile () != EFI_SUCCESS) {
+ printf ("Can't write output file: %s\n", OutputFileName);
+ Status = -1;
+ goto Done;
+ }
+
+ if (argc == 7) {
+ if (WriteOutputBatchFile () != EFI_SUCCESS) {
+ printf ("Can't write output batch file: %s\n", OutputBatchFileName);
+ Status = -1;
+ goto Done;
+ }
+ }
+
+ printf ("BIOS ID created: ");
+ PrintUnicodeString ((CHAR16 *)(&(BiosIdImage.BiosIdString)));
+ printf ("\n");
+ printf ("BIOS ID binary file created: %s\n", OutputFileName);
+
+Done:
+
+ if (InputFile != NULL) {
+ fclose (InputFile);
+ }
+
+ if (OutputFile != NULL) {
+ fclose (OutputFile);
+ }
+
+ if (OutputBatchFile != NULL) {
+ fclose (OutputBatchFile);
+ }
+
+ return Status;
+}
+
diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile
index 37bcce519c7e..9dbf1a4b06db 100644
--- a/BaseTools/Source/C/GNUmakefile
+++ b/BaseTools/Source/C/GNUmakefile
@@ -1,7 +1,7 @@
## @file
# GNU/Linux makefile for C tools build.
#
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -47,6 +47,7 @@ VFRAUTOGEN = VfrCompile/VfrLexer.h
APPLICATIONS = \
BrotliCompress \
VfrCompile \
+ GenBiosId \
EfiRom \
GenFfs \
GenFv \
diff --git a/BaseTools/Source/C/GenBiosId/BiosId.env b/BaseTools/Source/C/GenBiosId/BiosId.env
new file mode 100644
index 000000000000..de54273107bd
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/BiosId.env
@@ -0,0 +1,27 @@
+## @file
+# This file is used to define the BIOS ID parameters of the build.
+# This file is processed by GenBiosId.
+# Here, it is just a template and can be customized by user.
+#
+# BIOS ID string format:
+# $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+# All fields must have a fixed length. YYMMDDHHMM is UTC time.
+# Example: "OVMF.000.0008.D03.1501301017"
+#
+# If DATE is specified for YYMMDD and TIME is specified for HHMM like below,
+# GenBiosId will use the value of DATE and TIME to fill YYMMDDHHMM,
+# otherwise GenBiosId will fill YYMMDDHHMM with current UTC time of the build machine.
+# DATE = 150130
+# TIME = 1017
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+BOARD_ID = OVMF
+BOARD_REV = 1
+BOARD_EXT = 000
+BUILD_TYPE = D
+VERSION_MAJOR = 0008
+VERSION_MINOR = 03
diff --git a/BaseTools/Source/C/GenBiosId/GNUmakefile b/BaseTools/Source/C/GenBiosId/GNUmakefile
new file mode 100644
index 000000000000..90a918c13f96
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GNUmakefile
@@ -0,0 +1,14 @@
+## @file
+# makefile for building the GenBiosId utility.
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+MAKEROOT ?= ..
+
+APPNAME = GenBiosId
+
+OBJECTS = GenBiosId.o
+
+include $(MAKEROOT)/Makefiles/app.makefile
diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.h b/BaseTools/Source/C/GenBiosId/GenBiosId.h
new file mode 100644
index 000000000000..660fba77e90b
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/GenBiosId.h
@@ -0,0 +1,105 @@
+/** @file
+Definitions for the GenBiosId tool.
+
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GEN_BIOS_ID_
+#define _GEN_BIOS_ID_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <Common/UefiBaseTypes.h>
+
+#define FILE_NAME_SIZE 256
+#define MAX_LINE_SIZE 256
+#define MAX_FORMAT_STRING_SIZE 64
+
+#define ATOU(a) (CHAR16) ((UINT8) (a))
+#define UTOA(a) (CHAR8) ((UINT16) (a))
+
+//
+// BIOS ID field names.
+//
+#define NAME_BOARD_ID "BOARD_ID"
+#define NAME_BOARD_REV "BOARD_REV"
+#define NAME_BOARD_EXT "BOARD_EXT"
+#define NAME_BUILD_TYPE "BUILD_TYPE"
+#define NAME_VERSION_MAJOR "VERSION_MAJOR"
+#define NAME_VERSION_MINOR "VERSION_MINOR"
+#define NAME_DATE "DATE"
+#define NAME_TIME "TIME"
+
+//
+// Number of ASCII characters in each field
+//
+#define CHARS_BOARD_ID 7
+#define CHARS_BOARD_REV 1
+#define CHARS_BOARD_EXT 3
+#define CHARS_BUILD_TYPE 1
+#define CHARS_VERSION_MAJOR 4
+#define CHARS_VERSION_MINOR 2
+#define CHARS_DATE 6
+#define CHARS_TIME 4
+
+#define FIELD_BOARD_ID 0x0001
+#define FIELD_BOARD_REV 0x0002
+#define FIELD_BOARD_EXT 0x0004
+#define FIELD_BUILD_TYPE 0x0008
+#define FIELD_VERSION_MAJOR 0x0010
+#define FIELD_VERSION_MINOR 0x0020
+#define FIELD_DATE 0x0040
+#define FIELD_TIME 0x0080
+
+#define FIELD_ALL ( \
+ FIELD_BOARD_ID | \
+ FIELD_BOARD_REV | \
+ FIELD_BOARD_EXT | \
+ FIELD_BUILD_TYPE | \
+ FIELD_VERSION_MAJOR | \
+ FIELD_VERSION_MINOR | \
+ FIELD_DATE | \
+ FIELD_TIME)
+
+//
+// BIOS ID string format:
+//
+// $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+//
+// Example: "TRFTCRB1.000.0008.D03.1501301017"
+//
+// The format should be same as platform BIOS ID definition
+//
+#pragma pack(1)
+
+typedef struct {
+ CHAR16 BoardId[7]; // "TRFTCRB"
+ CHAR16 BoardRev; // "1"
+ CHAR16 Dot1; // "."
+ CHAR16 BoardExt[3]; // "000"
+ CHAR16 Dot2; // "."
+ CHAR16 VersionMajor[4]; // "0008"
+ CHAR16 Dot3; // "."
+ CHAR16 BuildType; // "D"
+ CHAR16 VersionMinor[2]; // "03"
+ CHAR16 Dot4; // "."
+ CHAR16 TimeStamp[10]; // "YYMMDDHHMM"
+ CHAR16 NullTerminator; // 0x0000
+} BIOS_ID_STRING;
+
+//
+// A signature precedes the BIOS ID string in the FV to enable search by external tools.
+//
+typedef struct {
+ UINT8 Signature[8]; // "$IBIOSI$"
+ BIOS_ID_STRING BiosIdString; // "TRFTCRB1.000.0008.D03.1501301017"
+} BIOS_ID_IMAGE;
+
+#pragma pack()
+
+
+#endif // _GEN_BIOS_ID_
diff --git a/BaseTools/Source/C/GenBiosId/Makefile b/BaseTools/Source/C/GenBiosId/Makefile
new file mode 100644
index 000000000000..967a1809b635
--- /dev/null
+++ b/BaseTools/Source/C/GenBiosId/Makefile
@@ -0,0 +1,14 @@
+## @file
+# makefile for building the GenBiosId utility.
+#
+# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+!INCLUDE ..\Makefiles\ms.common
+
+APPNAME = GenBiosId
+
+OBJECTS = GenBiosId.obj
+
+!INCLUDE ..\Makefiles\ms.app
+
diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile
index 217fc2b91d7b..748565bba9ff 100644
--- a/BaseTools/Source/C/Makefile
+++ b/BaseTools/Source/C/Makefile
@@ -1,7 +1,7 @@
## @file
# Windows makefile for C tools build.
#
-# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
HOST_ARCH = IA32
@@ -12,6 +12,7 @@ LIBRARIES = Common
APPLICATIONS = \
VfrCompile \
BrotliCompress \
+ GenBiosId \
EfiRom \
GenCrc32 \
GenFfs \
--
2.18.0.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
2019-05-28 1:32 [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId Zhang, Shenglei
@ 2019-05-28 16:48 ` Michael D Kinney
2019-05-31 6:36 ` Zhang, Shenglei
0 siblings, 1 reply; 4+ messages in thread
From: Michael D Kinney @ 2019-05-28 16:48 UTC (permalink / raw)
To: devel@edk2.groups.io, Zhang, Shenglei, Kinney, Michael D
Could this tools be ported to Python using the python
struct module to access C structures?
The implementation may be much simpler if python was
used for command line parsing. And this capability
could also be provided as a python module to support
direct access from pre/post build steps implemented in
python.
Thanks,
Mike
> -----Original Message-----
> From: devel@edk2.groups.io
> [mailto:devel@edk2.groups.io] On Behalf Of Zhang,
> Shenglei
> Sent: Monday, May 27, 2019 6:32 PM
> To: devel@edk2.groups.io
> Subject: [edk2-devel] [PATCH] BaseTools/GenBiosId: Add
> a new tool GenBiosId
>
> GenBiosId is a tool to generate the BIOS ID binary file
> which uses
> the data from the configuration file.
> https://bugzilla.tianocore.org/show_bug.cgi?id=1846
>
> Signed-off-by: Shenglei Zhang
> <shenglei.zhang@intel.com>
> ---
> BaseTools/Source/C/GenBiosId/GenBiosId.c | 627
> +++++++++++++++++++++++
> BaseTools/Source/C/GNUmakefile | 3 +-
> BaseTools/Source/C/GenBiosId/BiosId.env | 27 +
> BaseTools/Source/C/GenBiosId/GNUmakefile | 14 +
> BaseTools/Source/C/GenBiosId/GenBiosId.h | 105 ++++
> BaseTools/Source/C/GenBiosId/Makefile | 14 +
> BaseTools/Source/C/Makefile | 3 +-
> 7 files changed, 791 insertions(+), 2 deletions(-)
> create mode 100644
> BaseTools/Source/C/GenBiosId/GenBiosId.c
> create mode 100644
> BaseTools/Source/C/GenBiosId/BiosId.env
> create mode 100644
> BaseTools/Source/C/GenBiosId/GNUmakefile
> create mode 100644
> BaseTools/Source/C/GenBiosId/GenBiosId.h
> create mode 100644
> BaseTools/Source/C/GenBiosId/Makefile
>
> diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.c
> b/BaseTools/Source/C/GenBiosId/GenBiosId.c
> new file mode 100644
> index 000000000000..21d71d4ebd51
> --- /dev/null
> +++ b/BaseTools/Source/C/GenBiosId/GenBiosId.c
> @@ -0,0 +1,627 @@
> +/** @file
> +This tool generates the BIOS ID binary file using the
> data from the configuration file.
> +
> +Copyright (c) 2015 - 2019, Intel Corporation. All
> rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "GenBiosId.h"
> +
> +CHAR8 InputFileName[FILE_NAME_SIZE];
> +CHAR8 OutputFileName[FILE_NAME_SIZE];
> +CHAR8 OutputBatchFileName[FILE_NAME_SIZE];
> +
> +FILE *InputFile;
> +FILE *OutputFile;
> +FILE *OutputBatchFile;
> +
> +BIOS_ID_IMAGE BiosIdImage = {
> + { '$', 'I', 'B', 'I', 'O', 'S', 'I', '$' },
> + {
> + { ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '),
> ATOU (' '), ATOU (' '), ATOU (' ') },
> + ATOU (' '),
> + ATOU ('.'),
> + { ATOU (' '), ATOU (' '), ATOU (' ') },
> + ATOU ('.'),
> + { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0')
> },
> + ATOU ('.'),
> + ATOU (' '),
> + { ATOU ('0'), ATOU ('0') },
> + ATOU ('.'),
> + { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
> ATOU ('0'),
> + ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
> ATOU ('0') },
> + ATOU ('\0')
> + }
> +};
> +
> +VOID
> +PrintBanner (
> + VOID
> + )
> +/*++
> +
> +Routine Description:
> +
> +Arguments:
> +
> +Returns:
> +
> +--*/
> +{
> + printf ("\n");
> + printf ("GenBiosId utility, version: v1.0 05/27/2018
> \n");
> + printf ("Copyright (c) 2019, Intel Corporation. All
> rights reserved. \n");
> + printf ("\n");
> +}
> +
> +VOID
> +PrintUsage (
> + VOID
> + )
> +/*++
> +
> +Routine Description:
> +
> +Arguments:
> +
> +Returns:
> +
> +--*/
> +{
> + printf ("Usage:\n");
> + printf ("GenBiosId -i ConfigFile -o OutputFile [-ob
> OutputBatchFile] \n");
> + printf ("\n");
> +}
> +
> +CHAR8 *
> +StripLeadingWhiteSpace (
> + IN CHAR8 *StrInput
> + )
> +/*++
> +
> +Routine Description:
> +
> + Strip the leading whitespoace off the given ASCII
> string.
> +
> +Arguments:
> +
> + StrInput - the ASCII string that should be
> processed.
> +
> +Returns:
> +
> + A pointer to the first non-whitespace character in
> the given string,
> + or NULL if the string was all whitespace.
> +
> +--*/
> +{
> + if (StrInput == NULL) {
> + return NULL;
> + }
> +
> + while (*StrInput != 0) {
> + if ((*StrInput == ' ') || (*StrInput == '\t') ||
> (*StrInput == '\n')) {
> + ++StrInput;
> + } else {
> + return StrInput;
> + }
> + }
> +
> + return NULL;
> +}
> +
> +VOID
> +ConvertToUnicode (
> + IN CHAR8 *StrAscii,
> + OUT CHAR16 *StrUnicode
> + )
> +/*++
> +
> +Routine Description:
> +
> + Convert the given ASCII string to Unicode without
> appending terminating 0x0000.
> +
> +Arguments:
> +
> + StrAscii - the source ASCII string, null-
> terminated.
> +
> + StrUnicode - the resulted Unicode string will be
> put here, without the terminating 0x0000.
> +
> +Returns:
> +
> +--*/
> +{
> + if ((StrAscii == NULL) || (StrUnicode == NULL)) {
> + return;
> + }
> +
> + while (*StrAscii != 0) {
> + *StrUnicode = ATOU (*StrAscii);
> + ++StrAscii;
> + ++StrUnicode;
> + }
> +}
> +
> +VOID
> +FillTimeStamp (
> + OUT CHAR16 *StrTimeStampUnicode
> + )
> +/*++
> +
> +Routine Description:
> + The function generates the current timestamp in
> "YYMMDDHHMM" format
> + and puts it into the Unicode string supplied,
> without the null-terminator.
> +
> +Arguments:
> +
> + StrTimeStampUnicode - The Unicode string which is
> filled on return with the current timestamp.
> +
> +Returns:
> +
> +--*/
> +{
> + struct tm *Time;
> + time_t CurTime;
> + CHAR8 StrTime[11];
> +
> + //
> + // Fetch the current time based on UTC timezone
> + //
> + time (&CurTime);
> + Time = gmtime (&CurTime);
> +
> + if (NULL == Time) {
> + return;
> + }
> +
> + sprintf (
> + StrTime,
> + "%02d%02d%02d%02d%02d",
> + (Time->tm_year + 1900) % 100, // Year is 1900-
> based, need only 2 digits.
> + Time->tm_mon + 1, // Month is zero
> based.
> + Time->tm_mday,
> + Time->tm_hour,
> + Time->tm_min
> + );
> +
> + ConvertToUnicode (StrTime, StrTimeStampUnicode);
> +}
> +
> +VOID
> +ConvertToAscii (
> + IN CHAR16 *StrUnicode,
> + OUT CHAR8 *StrAscii
> + )
> +/*++
> +
> +Routine Description:
> +
> + Convert the given Unicode string to ASCII with
> appending terminating 0x00.
> +
> +Arguments:
> +
> + StrUnicode - the source Unicode string, null-
> terminated.
> +
> + StrAscii - the resulted ASCII string will be put
> here, with the terminating 0x00.
> +
> +Returns:
> +
> +--*/
> +{
> + if ((StrUnicode == NULL) || (StrAscii == NULL)) {
> + return;
> + }
> +
> + while (*StrUnicode != 0) {
> + *StrAscii = UTOA (*StrUnicode);
> + ++StrUnicode;
> + ++StrAscii;
> + }
> + *StrAscii = 0;
> +}
> +
> +VOID
> +PrintUnicodeString (
> + IN CHAR16 *StrUnicode
> + )
> +/*++
> +
> +Routine Description:
> +
> + Print the given Unicode string.
> +
> +Arguments:
> +
> + StrUnicode - the null-terminated Unicode string to
> print.
> +
> +Returns:
> +
> +--*/
> +{
> + if (StrUnicode == NULL) {
> + return;
> + }
> +
> + while (*StrUnicode != 0) {
> + putchar ((CHAR8)(*StrUnicode));
> + ++StrUnicode;
> + }
> +}
> +
> +EFI_STATUS
> +ParseInputFile (
> + VOID
> + )
> +/*++
> +
> +Routine Description:
> +
> + Parse the BIOS ID definition file and fill the BIOS
> ID structure, including timestamp.
> +
> +Arguments:
> +
> +Returns:
> +
> + EFI_SUCCESS - The input file was parsed
> successfully.
> +
> + EFI_INVALID_PARAMETER - The input file has incorrect
> format.
> +
> +--*/
> +{
> + CHAR8 StrLine[MAX_LINE_SIZE];
> + CHAR8 StrFieldName[MAX_LINE_SIZE];
> + CHAR8 StrFieldValue[MAX_LINE_SIZE];
> + CHAR8 *Str;
> + UINT16 FieldsSet;
> + CHAR8 FormatString[MAX_FORMAT_STRING_SIZE];
> +
> + FieldsSet = 0;
> + Str = NULL;
> +
> + //
> + // Generate the format string for sscanf() function.
> + //
> + sprintf (FormatString, "%%%us = %%%us", (unsigned
> int) sizeof (StrFieldName) - 1, (unsigned int) sizeof
> (StrFieldValue) - 1);
> +
> + while (fgets (StrLine, sizeof (StrLine) - 1,
> InputFile) != NULL) {
> + Str = StripLeadingWhiteSpace (StrLine);
> +
> + //
> + // Check for whitespace string.
> + //
> + if (Str == NULL) {
> + continue;
> + }
> +
> + //
> + // Check for comment string.
> + //
> + if (*Str == '#') {
> + continue;
> + }
> +
> + if (sscanf (Str, FormatString, StrFieldName,
> StrFieldValue) != 2) {
> + continue;
> + }
> +
> + if (strcmp (StrFieldName, NAME_BOARD_ID) == 0) {
> + if (strlen (StrFieldValue) == CHARS_BOARD_ID) {
> + ConvertToUnicode (StrFieldValue,
> BiosIdImage.BiosIdString.BoardId);
> + FieldsSet |= FIELD_BOARD_ID;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_BOARD_ID, CHARS_BOARD_ID);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_BOARD_REV) == 0) {
> + if (strlen (StrFieldValue) == CHARS_BOARD_REV) {
> + ConvertToUnicode (StrFieldValue,
> &(BiosIdImage.BiosIdString.BoardRev));
> + FieldsSet |= FIELD_BOARD_REV;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_BOARD_REV, CHARS_BOARD_REV);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_BOARD_EXT) == 0) {
> + if (strlen (StrFieldValue) == CHARS_BOARD_EXT) {
> + ConvertToUnicode (StrFieldValue,
> BiosIdImage.BiosIdString.BoardExt);
> + FieldsSet |= FIELD_BOARD_EXT;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_BOARD_EXT, CHARS_BOARD_EXT);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_BUILD_TYPE) == 0) {
> + if (strlen (StrFieldValue) == CHARS_BUILD_TYPE)
> {
> + if ((strcmp (StrFieldValue, "D") == 0) ||
> + (strcmp (StrFieldValue, "A") == 0) ||
> + (strcmp (StrFieldValue, "B") == 0) ||
> + (strcmp (StrFieldValue, "P") == 0)) {
> + ConvertToUnicode (StrFieldValue,
> &(BiosIdImage.BiosIdString.BuildType));
> + FieldsSet |= FIELD_BUILD_TYPE;
> + } else {
> + printf ("Error: value of %s should be one of
> %s, %s, %s or %s\n", NAME_BUILD_TYPE, "D", "A", "B",
> "P");
> + return EFI_INVALID_PARAMETER;
> + }
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_BUILD_TYPE,
> CHARS_BUILD_TYPE);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_VERSION_MAJOR) ==
> 0) {
> + if (strlen (StrFieldValue) ==
> CHARS_VERSION_MAJOR) {
> + ConvertToUnicode (StrFieldValue,
> BiosIdImage.BiosIdString.VersionMajor);
> + FieldsSet |= FIELD_VERSION_MAJOR;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_VERSION_MAJOR,
> CHARS_VERSION_MAJOR);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_VERSION_MINOR) ==
> 0) {
> + if (strlen (StrFieldValue) ==
> CHARS_VERSION_MINOR) {
> + ConvertToUnicode (StrFieldValue,
> BiosIdImage.BiosIdString.VersionMinor);
> + FieldsSet |= FIELD_VERSION_MINOR;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_VERSION_MINOR,
> CHARS_VERSION_MINOR);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_DATE) == 0) {
> + if (strlen (StrFieldValue) == CHARS_DATE) {
> + ConvertToUnicode (StrFieldValue,
> BiosIdImage.BiosIdString.TimeStamp);
> + FieldsSet |= FIELD_DATE;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_DATE, CHARS_DATE);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + if (strcmp (StrFieldName, NAME_TIME) == 0) {
> + if (strlen (StrFieldValue) == CHARS_TIME) {
> + ConvertToUnicode (StrFieldValue,
> &(BiosIdImage.BiosIdString.TimeStamp[CHARS_DATE]));
> + FieldsSet |= FIELD_TIME;
> + } else {
> + printf ("Error: value of %s should have
> exactly %d chars\n", NAME_TIME, CHARS_TIME);
> + return EFI_INVALID_PARAMETER;
> + }
> + }
> +
> + }
> +
> + if ((FieldsSet & (FIELD_DATE | FIELD_TIME)) !=
> (FIELD_DATE | FIELD_TIME)) {
> + //
> + // Fill the timestamp.
> + //
> + FillTimeStamp
> (BiosIdImage.BiosIdString.TimeStamp);
> + FieldsSet |= (FIELD_DATE | FIELD_TIME);
> + }
> +
> + //
> + // Exit if not all fields were supplied.
> + //
> + if ((FieldsSet & FIELD_ALL) != FIELD_ALL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +WriteOutputFile (
> + VOID
> + )
> +/*++
> +
> +Routine Description:
> +
> + Write the BIOS ID structure to the output file.
> +
> +Arguments:
> +
> +Returns:
> +
> + EFI_SUCCESS - The output file was created
> successfully.
> +
> + EFI_DEVICE_ERROR - There was a file write error.
> +
> +--*/
> +{
> + if (fwrite (&BiosIdImage, sizeof (BIOS_ID_IMAGE), 1,
> OutputFile) != 1) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +WriteOutputBatchFile (
> + VOID
> + )
> +/*++
> +
> +Routine Description:
> +
> + Write "SET BIOS_ID=" and BIOS ID string to the batch
> file.
> +
> +Arguments:
> +
> +Returns:
> +
> + EFI_SUCCESS - The output batch file was
> created successfully.
> +
> + EFI_DEVICE_ERROR - There was a file write error.
> +
> +--*/
> +{
> +#ifndef __GNUC__
> + CHAR8 BatchFileContent[MAX_LINE_SIZE] = "SET
> BIOS_ID=";
> +#else
> + CHAR8 BatchFileContent[MAX_LINE_SIZE] = "export
> BIOS_ID=";
> +#endif
> +
> + CHAR8 BiosIdString[sizeof (BIOS_ID_STRING)];
> +
> + ConvertToAscii ((CHAR16 *)
> (&(BiosIdImage.BiosIdString)), BiosIdString);
> + strcat (BatchFileContent, BiosIdString);
> +
> + if (fwrite (BatchFileContent, strlen
> (BatchFileContent), 1, OutputBatchFile) != 1) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +int
> +main (
> + IN int argc,
> + IN CHAR8 *argv[]
> + )
> +/*++
> +
> +Routine Description:
> +
> +Arguments:
> +
> + argc - Number of command-line arguments.
> +
> + argv - Array of command-line arguments.
> +
> +Returns:
> +
> + 0 - The operation completed successfully.
> +
> + -1 - An error occurred.
> +
> +--*/
> +{
> + int Status;
> +
> + Status = 0;
> +
> + PrintBanner ();
> +
> + if ((argc != 5) && (argc != 7)) {
> + PrintUsage ();
> + Status = -1;
> + goto Done;
> + }
> +
> + if (strcmp (argv[1], "-i") == 0) {
> + if (strlen (argv[2])> sizeof (InputFileName) - 1)
> {
> + printf ("The InputFileName %s is too long \n",
> argv[2]);
> + Status = -1;
> + goto Done;
> + }
> + strncpy (InputFileName, argv[2], sizeof
> (InputFileName) - 1);
> + InputFileName[sizeof (InputFileName) - 1] = 0;
> + } else {
> + PrintUsage ();
> + Status = -1;
> + goto Done;
> + }
> +
> + if (strcmp (argv[3], "-o") == 0) {
> + if (strlen (argv[4])> sizeof (OutputFileName) - 1)
> {
> + printf ("OutputFileName %s is too long \n",
> argv[4]);
> + Status = -1;
> + goto Done;
> + }
> + strncpy (OutputFileName, argv[4], sizeof
> (OutputFileName) - 1);
> + OutputFileName[sizeof (OutputFileName) - 1] = 0;
> + } else {
> + PrintUsage ();
> + Status = -1;
> + goto Done;
> + }
> +
> + if (argc == 7) {
> + if (strcmp (argv[5], "-ob") == 0) {
> + if (strlen (argv[6])> sizeof
> (OutputBatchFileName) - 1) {
> + printf ("The OutputBatchFileName %s is too
> long \n", argv[6]);
> + Status = -1;
> + goto Done;
> + }
> + strncpy (OutputBatchFileName, argv[6], sizeof
> (OutputBatchFileName) - 1);
> + OutputBatchFileName[sizeof (OutputBatchFileName)
> - 1] = 0;
> + } else {
> + PrintUsage ();
> + Status = -1;
> + goto Done;
> + }
> + }
> +
> + InputFile = NULL;
> + OutputFile = NULL;
> + OutputBatchFile = NULL;
> +
> + InputFile = fopen (InputFileName, "r");
> + if (InputFile == NULL) {
> + printf ("Error opening input file: %s\n",
> InputFileName);
> + Status = -1;
> + goto Done;
> + }
> +
> + OutputFile = fopen (OutputFileName, "wb");
> + if (OutputFile == NULL) {
> + printf ("Error creating output file: %s\n",
> OutputFileName);
> + Status = -1;
> + goto Done;
> + }
> +
> + if (argc == 7) {
> + OutputBatchFile = fopen (OutputBatchFileName,
> "wb");
> + if (OutputBatchFile == NULL) {
> + printf ("Error creating output batch file:
> %s\n", OutputBatchFileName);
> + Status = -1;
> + goto Done;
> + }
> + }
> +
> + if (ParseInputFile () != EFI_SUCCESS) {
> + printf ("Invalid config file format: %s\n",
> InputFileName);
> + Status = -1;
> + goto Done;
> + }
> +
> + if (WriteOutputFile () != EFI_SUCCESS) {
> + printf ("Can't write output file: %s\n",
> OutputFileName);
> + Status = -1;
> + goto Done;
> + }
> +
> + if (argc == 7) {
> + if (WriteOutputBatchFile () != EFI_SUCCESS) {
> + printf ("Can't write output batch file: %s\n",
> OutputBatchFileName);
> + Status = -1;
> + goto Done;
> + }
> + }
> +
> + printf ("BIOS ID created: ");
> + PrintUnicodeString ((CHAR16
> *)(&(BiosIdImage.BiosIdString)));
> + printf ("\n");
> + printf ("BIOS ID binary file created: %s\n",
> OutputFileName);
> +
> +Done:
> +
> + if (InputFile != NULL) {
> + fclose (InputFile);
> + }
> +
> + if (OutputFile != NULL) {
> + fclose (OutputFile);
> + }
> +
> + if (OutputBatchFile != NULL) {
> + fclose (OutputBatchFile);
> + }
> +
> + return Status;
> +}
> +
> diff --git a/BaseTools/Source/C/GNUmakefile
> b/BaseTools/Source/C/GNUmakefile
> index 37bcce519c7e..9dbf1a4b06db 100644
> --- a/BaseTools/Source/C/GNUmakefile
> +++ b/BaseTools/Source/C/GNUmakefile
> @@ -1,7 +1,7 @@
> ## @file
> # GNU/Linux makefile for C tools build.
> #
> -# Copyright (c) 2007 - 2017, Intel Corporation. All
> rights reserved.<BR>
> +# Copyright (c) 2007 - 2019, Intel Corporation. All
> rights reserved.<BR>
> #
> # SPDX-License-Identifier: BSD-2-Clause-Patent
> #
> @@ -47,6 +47,7 @@ VFRAUTOGEN = VfrCompile/VfrLexer.h
> APPLICATIONS = \
> BrotliCompress \
> VfrCompile \
> + GenBiosId \
> EfiRom \
> GenFfs \
> GenFv \
> diff --git a/BaseTools/Source/C/GenBiosId/BiosId.env
> b/BaseTools/Source/C/GenBiosId/BiosId.env
> new file mode 100644
> index 000000000000..de54273107bd
> --- /dev/null
> +++ b/BaseTools/Source/C/GenBiosId/BiosId.env
> @@ -0,0 +1,27 @@
> +## @file
> +# This file is used to define the BIOS ID parameters
> of the build.
> +# This file is processed by GenBiosId.
> +# Here, it is just a template and can be customized
> by user.
> +#
> +# BIOS ID string format:
> +#
> $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$
> (BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
> +# All fields must have a fixed length. YYMMDDHHMM is
> UTC time.
> +# Example: "OVMF.000.0008.D03.1501301017"
> +#
> +# If DATE is specified for YYMMDD and TIME is
> specified for HHMM like below,
> +# GenBiosId will use the value of DATE and TIME to
> fill YYMMDDHHMM,
> +# otherwise GenBiosId will fill YYMMDDHHMM with
> current UTC time of the build machine.
> +# DATE = 150130
> +# TIME = 1017
> +#
> +# Copyright (c) 2015 - 2019, Intel Corporation. All
> rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +BOARD_ID = OVMF
> +BOARD_REV = 1
> +BOARD_EXT = 000
> +BUILD_TYPE = D
> +VERSION_MAJOR = 0008
> +VERSION_MINOR = 03
> diff --git a/BaseTools/Source/C/GenBiosId/GNUmakefile
> b/BaseTools/Source/C/GenBiosId/GNUmakefile
> new file mode 100644
> index 000000000000..90a918c13f96
> --- /dev/null
> +++ b/BaseTools/Source/C/GenBiosId/GNUmakefile
> @@ -0,0 +1,14 @@
> +## @file
> +# makefile for building the GenBiosId utility.
> +#
> +# Copyright (c) 2015 - 2019, Intel Corporation. All
> rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +MAKEROOT ?= ..
> +
> +APPNAME = GenBiosId
> +
> +OBJECTS = GenBiosId.o
> +
> +include $(MAKEROOT)/Makefiles/app.makefile
> diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.h
> b/BaseTools/Source/C/GenBiosId/GenBiosId.h
> new file mode 100644
> index 000000000000..660fba77e90b
> --- /dev/null
> +++ b/BaseTools/Source/C/GenBiosId/GenBiosId.h
> @@ -0,0 +1,105 @@
> +/** @file
> +Definitions for the GenBiosId tool.
> +
> +Copyright (c) 2015 - 2019, Intel Corporation. All
> rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _GEN_BIOS_ID_
> +#define _GEN_BIOS_ID_
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <time.h>
> +#include <Common/UefiBaseTypes.h>
> +
> +#define FILE_NAME_SIZE 256
> +#define MAX_LINE_SIZE 256
> +#define MAX_FORMAT_STRING_SIZE 64
> +
> +#define ATOU(a) (CHAR16) ((UINT8) (a))
> +#define UTOA(a) (CHAR8) ((UINT16) (a))
> +
> +//
> +// BIOS ID field names.
> +//
> +#define NAME_BOARD_ID "BOARD_ID"
> +#define NAME_BOARD_REV "BOARD_REV"
> +#define NAME_BOARD_EXT "BOARD_EXT"
> +#define NAME_BUILD_TYPE "BUILD_TYPE"
> +#define NAME_VERSION_MAJOR "VERSION_MAJOR"
> +#define NAME_VERSION_MINOR "VERSION_MINOR"
> +#define NAME_DATE "DATE"
> +#define NAME_TIME "TIME"
> +
> +//
> +// Number of ASCII characters in each field
> +//
> +#define CHARS_BOARD_ID 7
> +#define CHARS_BOARD_REV 1
> +#define CHARS_BOARD_EXT 3
> +#define CHARS_BUILD_TYPE 1
> +#define CHARS_VERSION_MAJOR 4
> +#define CHARS_VERSION_MINOR 2
> +#define CHARS_DATE 6
> +#define CHARS_TIME 4
> +
> +#define FIELD_BOARD_ID 0x0001
> +#define FIELD_BOARD_REV 0x0002
> +#define FIELD_BOARD_EXT 0x0004
> +#define FIELD_BUILD_TYPE 0x0008
> +#define FIELD_VERSION_MAJOR 0x0010
> +#define FIELD_VERSION_MINOR 0x0020
> +#define FIELD_DATE 0x0040
> +#define FIELD_TIME 0x0080
> +
> +#define FIELD_ALL ( \
> + FIELD_BOARD_ID | \
> + FIELD_BOARD_REV | \
> + FIELD_BOARD_EXT | \
> + FIELD_BUILD_TYPE | \
> + FIELD_VERSION_MAJOR | \
> + FIELD_VERSION_MINOR | \
> + FIELD_DATE | \
> + FIELD_TIME)
> +
> +//
> +// BIOS ID string format:
> +//
> +//
> $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$
> (BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
> +//
> +// Example: "TRFTCRB1.000.0008.D03.1501301017"
> +//
> +// The format should be same as platform BIOS ID
> definition
> +//
> +#pragma pack(1)
> +
> +typedef struct {
> + CHAR16 BoardId[7]; // "TRFTCRB"
> + CHAR16 BoardRev; // "1"
> + CHAR16 Dot1; // "."
> + CHAR16 BoardExt[3]; // "000"
> + CHAR16 Dot2; // "."
> + CHAR16 VersionMajor[4]; // "0008"
> + CHAR16 Dot3; // "."
> + CHAR16 BuildType; // "D"
> + CHAR16 VersionMinor[2]; // "03"
> + CHAR16 Dot4; // "."
> + CHAR16 TimeStamp[10]; // "YYMMDDHHMM"
> + CHAR16 NullTerminator; // 0x0000
> +} BIOS_ID_STRING;
> +
> +//
> +// A signature precedes the BIOS ID string in the FV
> to enable search by external tools.
> +//
> +typedef struct {
> + UINT8 Signature[8]; // "$IBIOSI$"
> + BIOS_ID_STRING BiosIdString; //
> "TRFTCRB1.000.0008.D03.1501301017"
> +} BIOS_ID_IMAGE;
> +
> +#pragma pack()
> +
> +
> +#endif // _GEN_BIOS_ID_
> diff --git a/BaseTools/Source/C/GenBiosId/Makefile
> b/BaseTools/Source/C/GenBiosId/Makefile
> new file mode 100644
> index 000000000000..967a1809b635
> --- /dev/null
> +++ b/BaseTools/Source/C/GenBiosId/Makefile
> @@ -0,0 +1,14 @@
> +## @file
> +# makefile for building the GenBiosId utility.
> +#
> +# Copyright (c) 2015 - 2019, Intel Corporation. All
> rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +!INCLUDE ..\Makefiles\ms.common
> +
> +APPNAME = GenBiosId
> +
> +OBJECTS = GenBiosId.obj
> +
> +!INCLUDE ..\Makefiles\ms.app
> +
> diff --git a/BaseTools/Source/C/Makefile
> b/BaseTools/Source/C/Makefile
> index 217fc2b91d7b..748565bba9ff 100644
> --- a/BaseTools/Source/C/Makefile
> +++ b/BaseTools/Source/C/Makefile
> @@ -1,7 +1,7 @@
> ## @file
> # Windows makefile for C tools build.
> #
> -# Copyright (c) 2009 - 2018, Intel Corporation. All
> rights reserved.<BR>
> +# Copyright (c) 2009 - 2019, Intel Corporation. All
> rights reserved.<BR>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
> #
> HOST_ARCH = IA32
> @@ -12,6 +12,7 @@ LIBRARIES = Common
> APPLICATIONS = \
> VfrCompile \
> BrotliCompress \
> + GenBiosId \
> EfiRom \
> GenCrc32 \
> GenFfs \
> --
> 2.18.0.windows.1
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
2019-05-28 16:48 ` [edk2-devel] " Michael D Kinney
@ 2019-05-31 6:36 ` Zhang, Shenglei
0 siblings, 0 replies; 4+ messages in thread
From: Zhang, Shenglei @ 2019-05-31 6:36 UTC (permalink / raw)
To: Kinney, Michael D, devel@edk2.groups.io
> -----Original Message-----
> From: Kinney, Michael D
> Sent: Wednesday, May 29, 2019 12:49 AM
> To: devel@edk2.groups.io; Zhang, Shenglei <shenglei.zhang@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: RE: [edk2-devel] [PATCH] BaseTools/GenBiosId: Add a new tool
> GenBiosId
>
> Could this tools be ported to Python using the python
> struct module to access C structures?
>
> The implementation may be much simpler if python was
> used for command line parsing. And this capability
> could also be provided as a python module to support
> direct access from pre/post build steps implemented in
> python.
>
I think it's feasible to using the python structure to substitute C structure.
I'll investigate on it.
Best Regards,
Shenglei
> Thanks,
>
> Mike
>
> > -----Original Message-----
> > From: devel@edk2.groups.io
> > [mailto:devel@edk2.groups.io] On Behalf Of Zhang,
> > Shenglei
> > Sent: Monday, May 27, 2019 6:32 PM
> > To: devel@edk2.groups.io
> > Subject: [edk2-devel] [PATCH] BaseTools/GenBiosId: Add
> > a new tool GenBiosId
> >
> > GenBiosId is a tool to generate the BIOS ID binary file
> > which uses
> > the data from the configuration file.
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1846
> >
> > Signed-off-by: Shenglei Zhang
> > <shenglei.zhang@intel.com>
> > ---
> > BaseTools/Source/C/GenBiosId/GenBiosId.c | 627
> > +++++++++++++++++++++++
> > BaseTools/Source/C/GNUmakefile | 3 +-
> > BaseTools/Source/C/GenBiosId/BiosId.env | 27 +
> > BaseTools/Source/C/GenBiosId/GNUmakefile | 14 +
> > BaseTools/Source/C/GenBiosId/GenBiosId.h | 105 ++++
> > BaseTools/Source/C/GenBiosId/Makefile | 14 +
> > BaseTools/Source/C/Makefile | 3 +-
> > 7 files changed, 791 insertions(+), 2 deletions(-)
> > create mode 100644
> > BaseTools/Source/C/GenBiosId/GenBiosId.c
> > create mode 100644
> > BaseTools/Source/C/GenBiosId/BiosId.env
> > create mode 100644
> > BaseTools/Source/C/GenBiosId/GNUmakefile
> > create mode 100644
> > BaseTools/Source/C/GenBiosId/GenBiosId.h
> > create mode 100644
> > BaseTools/Source/C/GenBiosId/Makefile
> >
> > diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.c
> > b/BaseTools/Source/C/GenBiosId/GenBiosId.c
> > new file mode 100644
> > index 000000000000..21d71d4ebd51
> > --- /dev/null
> > +++ b/BaseTools/Source/C/GenBiosId/GenBiosId.c
> > @@ -0,0 +1,627 @@
> > +/** @file
> > +This tool generates the BIOS ID binary file using the
> > data from the configuration file.
> > +
> > +Copyright (c) 2015 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "GenBiosId.h"
> > +
> > +CHAR8 InputFileName[FILE_NAME_SIZE];
> > +CHAR8 OutputFileName[FILE_NAME_SIZE];
> > +CHAR8 OutputBatchFileName[FILE_NAME_SIZE];
> > +
> > +FILE *InputFile;
> > +FILE *OutputFile;
> > +FILE *OutputBatchFile;
> > +
> > +BIOS_ID_IMAGE BiosIdImage = {
> > + { '$', 'I', 'B', 'I', 'O', 'S', 'I', '$' },
> > + {
> > + { ATOU (' '), ATOU (' '), ATOU (' '), ATOU (' '),
> > ATOU (' '), ATOU (' '), ATOU (' ') },
> > + ATOU (' '),
> > + ATOU ('.'),
> > + { ATOU (' '), ATOU (' '), ATOU (' ') },
> > + ATOU ('.'),
> > + { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0')
> > },
> > + ATOU ('.'),
> > + ATOU (' '),
> > + { ATOU ('0'), ATOU ('0') },
> > + ATOU ('.'),
> > + { ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
> > ATOU ('0'),
> > + ATOU ('0'), ATOU ('0'), ATOU ('0'), ATOU ('0'),
> > ATOU ('0') },
> > + ATOU ('\0')
> > + }
> > +};
> > +
> > +VOID
> > +PrintBanner (
> > + VOID
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > +Arguments:
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + printf ("\n");
> > + printf ("GenBiosId utility, version: v1.0 05/27/2018
> > \n");
> > + printf ("Copyright (c) 2019, Intel Corporation. All
> > rights reserved. \n");
> > + printf ("\n");
> > +}
> > +
> > +VOID
> > +PrintUsage (
> > + VOID
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > +Arguments:
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + printf ("Usage:\n");
> > + printf ("GenBiosId -i ConfigFile -o OutputFile [-ob
> > OutputBatchFile] \n");
> > + printf ("\n");
> > +}
> > +
> > +CHAR8 *
> > +StripLeadingWhiteSpace (
> > + IN CHAR8 *StrInput
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Strip the leading whitespoace off the given ASCII
> > string.
> > +
> > +Arguments:
> > +
> > + StrInput - the ASCII string that should be
> > processed.
> > +
> > +Returns:
> > +
> > + A pointer to the first non-whitespace character in
> > the given string,
> > + or NULL if the string was all whitespace.
> > +
> > +--*/
> > +{
> > + if (StrInput == NULL) {
> > + return NULL;
> > + }
> > +
> > + while (*StrInput != 0) {
> > + if ((*StrInput == ' ') || (*StrInput == '\t') ||
> > (*StrInput == '\n')) {
> > + ++StrInput;
> > + } else {
> > + return StrInput;
> > + }
> > + }
> > +
> > + return NULL;
> > +}
> > +
> > +VOID
> > +ConvertToUnicode (
> > + IN CHAR8 *StrAscii,
> > + OUT CHAR16 *StrUnicode
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Convert the given ASCII string to Unicode without
> > appending terminating 0x0000.
> > +
> > +Arguments:
> > +
> > + StrAscii - the source ASCII string, null-
> > terminated.
> > +
> > + StrUnicode - the resulted Unicode string will be
> > put here, without the terminating 0x0000.
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + if ((StrAscii == NULL) || (StrUnicode == NULL)) {
> > + return;
> > + }
> > +
> > + while (*StrAscii != 0) {
> > + *StrUnicode = ATOU (*StrAscii);
> > + ++StrAscii;
> > + ++StrUnicode;
> > + }
> > +}
> > +
> > +VOID
> > +FillTimeStamp (
> > + OUT CHAR16 *StrTimeStampUnicode
> > + )
> > +/*++
> > +
> > +Routine Description:
> > + The function generates the current timestamp in
> > "YYMMDDHHMM" format
> > + and puts it into the Unicode string supplied,
> > without the null-terminator.
> > +
> > +Arguments:
> > +
> > + StrTimeStampUnicode - The Unicode string which is
> > filled on return with the current timestamp.
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + struct tm *Time;
> > + time_t CurTime;
> > + CHAR8 StrTime[11];
> > +
> > + //
> > + // Fetch the current time based on UTC timezone
> > + //
> > + time (&CurTime);
> > + Time = gmtime (&CurTime);
> > +
> > + if (NULL == Time) {
> > + return;
> > + }
> > +
> > + sprintf (
> > + StrTime,
> > + "%02d%02d%02d%02d%02d",
> > + (Time->tm_year + 1900) % 100, // Year is 1900-
> > based, need only 2 digits.
> > + Time->tm_mon + 1, // Month is zero
> > based.
> > + Time->tm_mday,
> > + Time->tm_hour,
> > + Time->tm_min
> > + );
> > +
> > + ConvertToUnicode (StrTime, StrTimeStampUnicode);
> > +}
> > +
> > +VOID
> > +ConvertToAscii (
> > + IN CHAR16 *StrUnicode,
> > + OUT CHAR8 *StrAscii
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Convert the given Unicode string to ASCII with
> > appending terminating 0x00.
> > +
> > +Arguments:
> > +
> > + StrUnicode - the source Unicode string, null-
> > terminated.
> > +
> > + StrAscii - the resulted ASCII string will be put
> > here, with the terminating 0x00.
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + if ((StrUnicode == NULL) || (StrAscii == NULL)) {
> > + return;
> > + }
> > +
> > + while (*StrUnicode != 0) {
> > + *StrAscii = UTOA (*StrUnicode);
> > + ++StrUnicode;
> > + ++StrAscii;
> > + }
> > + *StrAscii = 0;
> > +}
> > +
> > +VOID
> > +PrintUnicodeString (
> > + IN CHAR16 *StrUnicode
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Print the given Unicode string.
> > +
> > +Arguments:
> > +
> > + StrUnicode - the null-terminated Unicode string to
> > print.
> > +
> > +Returns:
> > +
> > +--*/
> > +{
> > + if (StrUnicode == NULL) {
> > + return;
> > + }
> > +
> > + while (*StrUnicode != 0) {
> > + putchar ((CHAR8)(*StrUnicode));
> > + ++StrUnicode;
> > + }
> > +}
> > +
> > +EFI_STATUS
> > +ParseInputFile (
> > + VOID
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Parse the BIOS ID definition file and fill the BIOS
> > ID structure, including timestamp.
> > +
> > +Arguments:
> > +
> > +Returns:
> > +
> > + EFI_SUCCESS - The input file was parsed
> > successfully.
> > +
> > + EFI_INVALID_PARAMETER - The input file has incorrect
> > format.
> > +
> > +--*/
> > +{
> > + CHAR8 StrLine[MAX_LINE_SIZE];
> > + CHAR8 StrFieldName[MAX_LINE_SIZE];
> > + CHAR8 StrFieldValue[MAX_LINE_SIZE];
> > + CHAR8 *Str;
> > + UINT16 FieldsSet;
> > + CHAR8 FormatString[MAX_FORMAT_STRING_SIZE];
> > +
> > + FieldsSet = 0;
> > + Str = NULL;
> > +
> > + //
> > + // Generate the format string for sscanf() function.
> > + //
> > + sprintf (FormatString, "%%%us = %%%us", (unsigned
> > int) sizeof (StrFieldName) - 1, (unsigned int) sizeof
> > (StrFieldValue) - 1);
> > +
> > + while (fgets (StrLine, sizeof (StrLine) - 1,
> > InputFile) != NULL) {
> > + Str = StripLeadingWhiteSpace (StrLine);
> > +
> > + //
> > + // Check for whitespace string.
> > + //
> > + if (Str == NULL) {
> > + continue;
> > + }
> > +
> > + //
> > + // Check for comment string.
> > + //
> > + if (*Str == '#') {
> > + continue;
> > + }
> > +
> > + if (sscanf (Str, FormatString, StrFieldName,
> > StrFieldValue) != 2) {
> > + continue;
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_BOARD_ID) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_BOARD_ID) {
> > + ConvertToUnicode (StrFieldValue,
> > BiosIdImage.BiosIdString.BoardId);
> > + FieldsSet |= FIELD_BOARD_ID;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_BOARD_ID, CHARS_BOARD_ID);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_BOARD_REV) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_BOARD_REV) {
> > + ConvertToUnicode (StrFieldValue,
> > &(BiosIdImage.BiosIdString.BoardRev));
> > + FieldsSet |= FIELD_BOARD_REV;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_BOARD_REV, CHARS_BOARD_REV);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_BOARD_EXT) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_BOARD_EXT) {
> > + ConvertToUnicode (StrFieldValue,
> > BiosIdImage.BiosIdString.BoardExt);
> > + FieldsSet |= FIELD_BOARD_EXT;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_BOARD_EXT, CHARS_BOARD_EXT);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_BUILD_TYPE) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_BUILD_TYPE)
> > {
> > + if ((strcmp (StrFieldValue, "D") == 0) ||
> > + (strcmp (StrFieldValue, "A") == 0) ||
> > + (strcmp (StrFieldValue, "B") == 0) ||
> > + (strcmp (StrFieldValue, "P") == 0)) {
> > + ConvertToUnicode (StrFieldValue,
> > &(BiosIdImage.BiosIdString.BuildType));
> > + FieldsSet |= FIELD_BUILD_TYPE;
> > + } else {
> > + printf ("Error: value of %s should be one of
> > %s, %s, %s or %s\n", NAME_BUILD_TYPE, "D", "A", "B",
> > "P");
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_BUILD_TYPE,
> > CHARS_BUILD_TYPE);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_VERSION_MAJOR) ==
> > 0) {
> > + if (strlen (StrFieldValue) ==
> > CHARS_VERSION_MAJOR) {
> > + ConvertToUnicode (StrFieldValue,
> > BiosIdImage.BiosIdString.VersionMajor);
> > + FieldsSet |= FIELD_VERSION_MAJOR;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_VERSION_MAJOR,
> > CHARS_VERSION_MAJOR);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_VERSION_MINOR) ==
> > 0) {
> > + if (strlen (StrFieldValue) ==
> > CHARS_VERSION_MINOR) {
> > + ConvertToUnicode (StrFieldValue,
> > BiosIdImage.BiosIdString.VersionMinor);
> > + FieldsSet |= FIELD_VERSION_MINOR;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_VERSION_MINOR,
> > CHARS_VERSION_MINOR);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_DATE) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_DATE) {
> > + ConvertToUnicode (StrFieldValue,
> > BiosIdImage.BiosIdString.TimeStamp);
> > + FieldsSet |= FIELD_DATE;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_DATE, CHARS_DATE);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + if (strcmp (StrFieldName, NAME_TIME) == 0) {
> > + if (strlen (StrFieldValue) == CHARS_TIME) {
> > + ConvertToUnicode (StrFieldValue,
> > &(BiosIdImage.BiosIdString.TimeStamp[CHARS_DATE]));
> > + FieldsSet |= FIELD_TIME;
> > + } else {
> > + printf ("Error: value of %s should have
> > exactly %d chars\n", NAME_TIME, CHARS_TIME);
> > + return EFI_INVALID_PARAMETER;
> > + }
> > + }
> > +
> > + }
> > +
> > + if ((FieldsSet & (FIELD_DATE | FIELD_TIME)) !=
> > (FIELD_DATE | FIELD_TIME)) {
> > + //
> > + // Fill the timestamp.
> > + //
> > + FillTimeStamp
> > (BiosIdImage.BiosIdString.TimeStamp);
> > + FieldsSet |= (FIELD_DATE | FIELD_TIME);
> > + }
> > +
> > + //
> > + // Exit if not all fields were supplied.
> > + //
> > + if ((FieldsSet & FIELD_ALL) != FIELD_ALL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +WriteOutputFile (
> > + VOID
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Write the BIOS ID structure to the output file.
> > +
> > +Arguments:
> > +
> > +Returns:
> > +
> > + EFI_SUCCESS - The output file was created
> > successfully.
> > +
> > + EFI_DEVICE_ERROR - There was a file write error.
> > +
> > +--*/
> > +{
> > + if (fwrite (&BiosIdImage, sizeof (BIOS_ID_IMAGE), 1,
> > OutputFile) != 1) {
> > + return EFI_DEVICE_ERROR;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +WriteOutputBatchFile (
> > + VOID
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > + Write "SET BIOS_ID=" and BIOS ID string to the batch
> > file.
> > +
> > +Arguments:
> > +
> > +Returns:
> > +
> > + EFI_SUCCESS - The output batch file was
> > created successfully.
> > +
> > + EFI_DEVICE_ERROR - There was a file write error.
> > +
> > +--*/
> > +{
> > +#ifndef __GNUC__
> > + CHAR8 BatchFileContent[MAX_LINE_SIZE] = "SET
> > BIOS_ID=";
> > +#else
> > + CHAR8 BatchFileContent[MAX_LINE_SIZE] = "export
> > BIOS_ID=";
> > +#endif
> > +
> > + CHAR8 BiosIdString[sizeof (BIOS_ID_STRING)];
> > +
> > + ConvertToAscii ((CHAR16 *)
> > (&(BiosIdImage.BiosIdString)), BiosIdString);
> > + strcat (BatchFileContent, BiosIdString);
> > +
> > + if (fwrite (BatchFileContent, strlen
> > (BatchFileContent), 1, OutputBatchFile) != 1) {
> > + return EFI_DEVICE_ERROR;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +int
> > +main (
> > + IN int argc,
> > + IN CHAR8 *argv[]
> > + )
> > +/*++
> > +
> > +Routine Description:
> > +
> > +Arguments:
> > +
> > + argc - Number of command-line arguments.
> > +
> > + argv - Array of command-line arguments.
> > +
> > +Returns:
> > +
> > + 0 - The operation completed successfully.
> > +
> > + -1 - An error occurred.
> > +
> > +--*/
> > +{
> > + int Status;
> > +
> > + Status = 0;
> > +
> > + PrintBanner ();
> > +
> > + if ((argc != 5) && (argc != 7)) {
> > + PrintUsage ();
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (strcmp (argv[1], "-i") == 0) {
> > + if (strlen (argv[2])> sizeof (InputFileName) - 1)
> > {
> > + printf ("The InputFileName %s is too long \n",
> > argv[2]);
> > + Status = -1;
> > + goto Done;
> > + }
> > + strncpy (InputFileName, argv[2], sizeof
> > (InputFileName) - 1);
> > + InputFileName[sizeof (InputFileName) - 1] = 0;
> > + } else {
> > + PrintUsage ();
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (strcmp (argv[3], "-o") == 0) {
> > + if (strlen (argv[4])> sizeof (OutputFileName) - 1)
> > {
> > + printf ("OutputFileName %s is too long \n",
> > argv[4]);
> > + Status = -1;
> > + goto Done;
> > + }
> > + strncpy (OutputFileName, argv[4], sizeof
> > (OutputFileName) - 1);
> > + OutputFileName[sizeof (OutputFileName) - 1] = 0;
> > + } else {
> > + PrintUsage ();
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (argc == 7) {
> > + if (strcmp (argv[5], "-ob") == 0) {
> > + if (strlen (argv[6])> sizeof
> > (OutputBatchFileName) - 1) {
> > + printf ("The OutputBatchFileName %s is too
> > long \n", argv[6]);
> > + Status = -1;
> > + goto Done;
> > + }
> > + strncpy (OutputBatchFileName, argv[6], sizeof
> > (OutputBatchFileName) - 1);
> > + OutputBatchFileName[sizeof (OutputBatchFileName)
> > - 1] = 0;
> > + } else {
> > + PrintUsage ();
> > + Status = -1;
> > + goto Done;
> > + }
> > + }
> > +
> > + InputFile = NULL;
> > + OutputFile = NULL;
> > + OutputBatchFile = NULL;
> > +
> > + InputFile = fopen (InputFileName, "r");
> > + if (InputFile == NULL) {
> > + printf ("Error opening input file: %s\n",
> > InputFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + OutputFile = fopen (OutputFileName, "wb");
> > + if (OutputFile == NULL) {
> > + printf ("Error creating output file: %s\n",
> > OutputFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (argc == 7) {
> > + OutputBatchFile = fopen (OutputBatchFileName,
> > "wb");
> > + if (OutputBatchFile == NULL) {
> > + printf ("Error creating output batch file:
> > %s\n", OutputBatchFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > + }
> > +
> > + if (ParseInputFile () != EFI_SUCCESS) {
> > + printf ("Invalid config file format: %s\n",
> > InputFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (WriteOutputFile () != EFI_SUCCESS) {
> > + printf ("Can't write output file: %s\n",
> > OutputFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > +
> > + if (argc == 7) {
> > + if (WriteOutputBatchFile () != EFI_SUCCESS) {
> > + printf ("Can't write output batch file: %s\n",
> > OutputBatchFileName);
> > + Status = -1;
> > + goto Done;
> > + }
> > + }
> > +
> > + printf ("BIOS ID created: ");
> > + PrintUnicodeString ((CHAR16
> > *)(&(BiosIdImage.BiosIdString)));
> > + printf ("\n");
> > + printf ("BIOS ID binary file created: %s\n",
> > OutputFileName);
> > +
> > +Done:
> > +
> > + if (InputFile != NULL) {
> > + fclose (InputFile);
> > + }
> > +
> > + if (OutputFile != NULL) {
> > + fclose (OutputFile);
> > + }
> > +
> > + if (OutputBatchFile != NULL) {
> > + fclose (OutputBatchFile);
> > + }
> > +
> > + return Status;
> > +}
> > +
> > diff --git a/BaseTools/Source/C/GNUmakefile
> > b/BaseTools/Source/C/GNUmakefile
> > index 37bcce519c7e..9dbf1a4b06db 100644
> > --- a/BaseTools/Source/C/GNUmakefile
> > +++ b/BaseTools/Source/C/GNUmakefile
> > @@ -1,7 +1,7 @@
> > ## @file
> > # GNU/Linux makefile for C tools build.
> > #
> > -# Copyright (c) 2007 - 2017, Intel Corporation. All
> > rights reserved.<BR>
> > +# Copyright (c) 2007 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > #
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > #
> > @@ -47,6 +47,7 @@ VFRAUTOGEN = VfrCompile/VfrLexer.h
> > APPLICATIONS = \
> > BrotliCompress \
> > VfrCompile \
> > + GenBiosId \
> > EfiRom \
> > GenFfs \
> > GenFv \
> > diff --git a/BaseTools/Source/C/GenBiosId/BiosId.env
> > b/BaseTools/Source/C/GenBiosId/BiosId.env
> > new file mode 100644
> > index 000000000000..de54273107bd
> > --- /dev/null
> > +++ b/BaseTools/Source/C/GenBiosId/BiosId.env
> > @@ -0,0 +1,27 @@
> > +## @file
> > +# This file is used to define the BIOS ID parameters
> > of the build.
> > +# This file is processed by GenBiosId.
> > +# Here, it is just a template and can be customized
> > by user.
> > +#
> > +# BIOS ID string format:
> > +#
> > $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$
> > (BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
> > +# All fields must have a fixed length. YYMMDDHHMM is
> > UTC time.
> > +# Example: "OVMF.000.0008.D03.1501301017"
> > +#
> > +# If DATE is specified for YYMMDD and TIME is
> > specified for HHMM like below,
> > +# GenBiosId will use the value of DATE and TIME to
> > fill YYMMDDHHMM,
> > +# otherwise GenBiosId will fill YYMMDDHHMM with
> > current UTC time of the build machine.
> > +# DATE = 150130
> > +# TIME = 1017
> > +#
> > +# Copyright (c) 2015 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +BOARD_ID = OVMF
> > +BOARD_REV = 1
> > +BOARD_EXT = 000
> > +BUILD_TYPE = D
> > +VERSION_MAJOR = 0008
> > +VERSION_MINOR = 03
> > diff --git a/BaseTools/Source/C/GenBiosId/GNUmakefile
> > b/BaseTools/Source/C/GenBiosId/GNUmakefile
> > new file mode 100644
> > index 000000000000..90a918c13f96
> > --- /dev/null
> > +++ b/BaseTools/Source/C/GenBiosId/GNUmakefile
> > @@ -0,0 +1,14 @@
> > +## @file
> > +# makefile for building the GenBiosId utility.
> > +#
> > +# Copyright (c) 2015 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +MAKEROOT ?= ..
> > +
> > +APPNAME = GenBiosId
> > +
> > +OBJECTS = GenBiosId.o
> > +
> > +include $(MAKEROOT)/Makefiles/app.makefile
> > diff --git a/BaseTools/Source/C/GenBiosId/GenBiosId.h
> > b/BaseTools/Source/C/GenBiosId/GenBiosId.h
> > new file mode 100644
> > index 000000000000..660fba77e90b
> > --- /dev/null
> > +++ b/BaseTools/Source/C/GenBiosId/GenBiosId.h
> > @@ -0,0 +1,105 @@
> > +/** @file
> > +Definitions for the GenBiosId tool.
> > +
> > +Copyright (c) 2015 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _GEN_BIOS_ID_
> > +#define _GEN_BIOS_ID_
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <time.h>
> > +#include <Common/UefiBaseTypes.h>
> > +
> > +#define FILE_NAME_SIZE 256
> > +#define MAX_LINE_SIZE 256
> > +#define MAX_FORMAT_STRING_SIZE 64
> > +
> > +#define ATOU(a) (CHAR16) ((UINT8) (a))
> > +#define UTOA(a) (CHAR8) ((UINT16) (a))
> > +
> > +//
> > +// BIOS ID field names.
> > +//
> > +#define NAME_BOARD_ID "BOARD_ID"
> > +#define NAME_BOARD_REV "BOARD_REV"
> > +#define NAME_BOARD_EXT "BOARD_EXT"
> > +#define NAME_BUILD_TYPE "BUILD_TYPE"
> > +#define NAME_VERSION_MAJOR "VERSION_MAJOR"
> > +#define NAME_VERSION_MINOR "VERSION_MINOR"
> > +#define NAME_DATE "DATE"
> > +#define NAME_TIME "TIME"
> > +
> > +//
> > +// Number of ASCII characters in each field
> > +//
> > +#define CHARS_BOARD_ID 7
> > +#define CHARS_BOARD_REV 1
> > +#define CHARS_BOARD_EXT 3
> > +#define CHARS_BUILD_TYPE 1
> > +#define CHARS_VERSION_MAJOR 4
> > +#define CHARS_VERSION_MINOR 2
> > +#define CHARS_DATE 6
> > +#define CHARS_TIME 4
> > +
> > +#define FIELD_BOARD_ID 0x0001
> > +#define FIELD_BOARD_REV 0x0002
> > +#define FIELD_BOARD_EXT 0x0004
> > +#define FIELD_BUILD_TYPE 0x0008
> > +#define FIELD_VERSION_MAJOR 0x0010
> > +#define FIELD_VERSION_MINOR 0x0020
> > +#define FIELD_DATE 0x0040
> > +#define FIELD_TIME 0x0080
> > +
> > +#define FIELD_ALL ( \
> > + FIELD_BOARD_ID | \
> > + FIELD_BOARD_REV | \
> > + FIELD_BOARD_EXT | \
> > + FIELD_BUILD_TYPE | \
> > + FIELD_VERSION_MAJOR | \
> > + FIELD_VERSION_MINOR | \
> > + FIELD_DATE | \
> > + FIELD_TIME)
> > +
> > +//
> > +// BIOS ID string format:
> > +//
> > +//
> > $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$
> > (BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
> > +//
> > +// Example: "TRFTCRB1.000.0008.D03.1501301017"
> > +//
> > +// The format should be same as platform BIOS ID
> > definition
> > +//
> > +#pragma pack(1)
> > +
> > +typedef struct {
> > + CHAR16 BoardId[7]; // "TRFTCRB"
> > + CHAR16 BoardRev; // "1"
> > + CHAR16 Dot1; // "."
> > + CHAR16 BoardExt[3]; // "000"
> > + CHAR16 Dot2; // "."
> > + CHAR16 VersionMajor[4]; // "0008"
> > + CHAR16 Dot3; // "."
> > + CHAR16 BuildType; // "D"
> > + CHAR16 VersionMinor[2]; // "03"
> > + CHAR16 Dot4; // "."
> > + CHAR16 TimeStamp[10]; // "YYMMDDHHMM"
> > + CHAR16 NullTerminator; // 0x0000
> > +} BIOS_ID_STRING;
> > +
> > +//
> > +// A signature precedes the BIOS ID string in the FV
> > to enable search by external tools.
> > +//
> > +typedef struct {
> > + UINT8 Signature[8]; // "$IBIOSI$"
> > + BIOS_ID_STRING BiosIdString; //
> > "TRFTCRB1.000.0008.D03.1501301017"
> > +} BIOS_ID_IMAGE;
> > +
> > +#pragma pack()
> > +
> > +
> > +#endif // _GEN_BIOS_ID_
> > diff --git a/BaseTools/Source/C/GenBiosId/Makefile
> > b/BaseTools/Source/C/GenBiosId/Makefile
> > new file mode 100644
> > index 000000000000..967a1809b635
> > --- /dev/null
> > +++ b/BaseTools/Source/C/GenBiosId/Makefile
> > @@ -0,0 +1,14 @@
> > +## @file
> > +# makefile for building the GenBiosId utility.
> > +#
> > +# Copyright (c) 2015 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +!INCLUDE ..\Makefiles\ms.common
> > +
> > +APPNAME = GenBiosId
> > +
> > +OBJECTS = GenBiosId.obj
> > +
> > +!INCLUDE ..\Makefiles\ms.app
> > +
> > diff --git a/BaseTools/Source/C/Makefile
> > b/BaseTools/Source/C/Makefile
> > index 217fc2b91d7b..748565bba9ff 100644
> > --- a/BaseTools/Source/C/Makefile
> > +++ b/BaseTools/Source/C/Makefile
> > @@ -1,7 +1,7 @@
> > ## @file
> > # Windows makefile for C tools build.
> > #
> > -# Copyright (c) 2009 - 2018, Intel Corporation. All
> > rights reserved.<BR>
> > +# Copyright (c) 2009 - 2019, Intel Corporation. All
> > rights reserved.<BR>
> > # SPDX-License-Identifier: BSD-2-Clause-Patent
> > #
> > HOST_ARCH = IA32
> > @@ -12,6 +12,7 @@ LIBRARIES = Common
> > APPLICATIONS = \
> > VfrCompile \
> > BrotliCompress \
> > + GenBiosId \
> > EfiRom \
> > GenCrc32 \
> > GenFfs \
> > --
> > 2.18.0.windows.1
> >
> >
> >
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId
@ 2019-06-14 7:38 Zhang, Shenglei
0 siblings, 0 replies; 4+ messages in thread
From: Zhang, Shenglei @ 2019-06-14 7:38 UTC (permalink / raw)
To: devel; +Cc: Fan, Zhiju, Bob Feng, Liming Gao
From: "Fan, Zhiju" <zhijux.fan@intel.com>
GenBiosId is a tool to generate the BIOS ID binary file which uses
the data from the configuration file.
https://bugzilla.tianocore.org/show_bug.cgi?id=1846
v2:v1 is a tool of C type and v2 is python type.
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
---
BaseTools/BinWrappers/PosixLike/GenBiosId | 14 +++
.../BinWrappers/WindowsLike/GenBiosId.bat | 3 +
BaseTools/Source/Python/GenBiosId/BiosId.env | 27 +++++
.../Source/Python/GenBiosId/GenBiosId.py | 108 ++++++++++++++++++
4 files changed, 152 insertions(+)
create mode 100644 BaseTools/BinWrappers/PosixLike/GenBiosId
create mode 100644 BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
create mode 100644 BaseTools/Source/Python/GenBiosId/BiosId.env
create mode 100644 BaseTools/Source/Python/GenBiosId/GenBiosId.py
diff --git a/BaseTools/BinWrappers/PosixLike/GenBiosId b/BaseTools/BinWrappers/PosixLike/GenBiosId
new file mode 100644
index 000000000000..9fb68299e4c6
--- /dev/null
+++ b/BaseTools/BinWrappers/PosixLike/GenBiosId
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+#python `dirname $0`/RunToolFromSource.py `basename $0` $*
+
+# If a ${PYTHON_COMMAND} command is available, use it in preference to python
+if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
+ python_exe=${PYTHON_COMMAND}
+fi
+
+full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
+dir=$(dirname "$full_cmd")
+exe=$(basename "$full_cmd")
+
+export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
+exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@"
diff --git a/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat b/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
new file mode 100644
index 000000000000..9616cd893bec
--- /dev/null
+++ b/BaseTools/BinWrappers/WindowsLike/GenBiosId.bat
@@ -0,0 +1,3 @@
+@setlocal
+@set ToolName=%~n0%
+@%PYTHON_COMMAND% %BASE_TOOLS_PATH%\Source\Python\%ToolName%\%ToolName%.py %*
diff --git a/BaseTools/Source/Python/GenBiosId/BiosId.env b/BaseTools/Source/Python/GenBiosId/BiosId.env
new file mode 100644
index 000000000000..92805e3cb78c
--- /dev/null
+++ b/BaseTools/Source/Python/GenBiosId/BiosId.env
@@ -0,0 +1,27 @@
+## @file
+# This file is used to define the BIOS ID parameters of the build.
+# This file is processed by GenBiosId.
+# Here, it is just a template and can be customized by user.
+#
+# BIOS ID string format:
+# $(BOARD_ID)$(BOARD_REV).$(BOARD_EXT).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+# All fields must have a fixed length. YYMMDDHHMM is UTC time.
+# Example: "EMLATOR1.000.0001.D01.1906141517"
+#
+# If DATE is specified for YYMMDD and TIME is specified for HHMM like below,
+# GenBiosId will use the value of DATE and TIME to fill YYMMDDHHMM,
+# otherwise GenBiosId will fill YYMMDDHHMM with current UTC time of the build machine.
+# DATE = 190614
+# TIME = 1517
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[config]
+BOARD_ID = EMLATOR
+BOARD_REV = 1
+BOARD_EXT = 000
+BUILD_TYPE = D
+VERSION_MAJOR = 0001
+VERSION_MINOR = 01
diff --git a/BaseTools/Source/Python/GenBiosId/GenBiosId.py b/BaseTools/Source/Python/GenBiosId/GenBiosId.py
new file mode 100644
index 000000000000..1be99f4a5931
--- /dev/null
+++ b/BaseTools/Source/Python/GenBiosId/GenBiosId.py
@@ -0,0 +1,108 @@
+## @file
+# Trim files preprocessed by compiler
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+##
+# Import Modules
+#
+import Common.LongFilePathOs as os
+import sys
+import struct
+import time
+import datetime
+try:
+ from configparser import ConfigParser
+except:
+ from ConfigParser import ConfigParser
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.DataType import *
+from Common.BuildVersion import gBUILD_VERSION
+import Common.EdkLogger as EdkLogger
+from Common.LongFilePathSupport import OpenLongFilePath as open
+
+_BIOS_Signature = "$IBIOSI$"
+_SectionKeyName = '__name__'
+_SectionName = 'config'
+
+_ConfigItem = {
+ "BOARD_ID" : {'Value' : '', 'Length' : 7},
+ "BOARD_REV" : {'Value' : '', 'Length' : 1},
+ "BOARD_EXT" : { 'Value' : '', 'Length' : 3},
+ "BUILD_TYPE" : {'Value' : '', 'Length' :1},
+ "VERSION_MAJOR" : {'Value' : '0000', 'Length' : 4},
+ "VERSION_MINOR" : {'Value' : '00', 'Length' : 2},
+
+}
+
+
+_Usage = "Usage: GenBiosId -i Configfile -o OutputFile [-ob OutputBatchFile]"
+_ConfigSectionNotDefine = "Not support the config file format, need config section"
+_ConfigLenInvalid = "Config item %s length is invalid"
+_ConfigItemInvalid = "Item %s is invalid"
+
+def Main():
+ try:
+ EdkLogger.Initialize()
+ if len(sys.argv) !=5 and len(sys.argv) != 7:
+ EdkLogger.error("GenBiosId", OPTION_MISSING, ExtraData=_Usage)
+ except FatalError as X:
+ return 1
+ InputFile = ''
+ OutputFile = ''
+ OutputBatchFile = ''
+ for Index, Item in enumerate(sys.argv):
+ if '-i' == Item:
+ InputFile = sys.argv[Index + 1]
+ if '-o' == Item:
+ OutputFile = sys.argv[Index + 1]
+ if '-ob' == Item:
+ OutputBatchFile = sys.argv[Index + 1]
+ if not os.path.exists(InputFile):
+ EdkLogger.error("GenBiosId", FILE_NOT_FOUND, ExtraData="Input file not found")
+ cf = ConfigParser()
+ cf.optionxform = str
+ cf.read(InputFile)
+ if _SectionName not in cf._sections:
+ EdkLogger.error("GenBiosId", FORMAT_NOT_SUPPORTED, ExtraData=_ConfigSectionNotDefine)
+ for Item in cf._sections[_SectionName]:
+ if Item == _SectionKeyName:
+ continue
+ if Item not in _ConfigItem:
+ EdkLogger.error("GenBiosId", FORMAT_INVALID, ExtraData=_ConfigItemInvalid % Item)
+ _ConfigItem[Item]['Value'] = cf._sections[_SectionName][Item]
+ if len(_ConfigItem[Item]['Value']) != _ConfigItem[Item]['Length']:
+ EdkLogger.error("GenBiosId", FORMAT_INVALID, ExtraData=_ConfigLenInvalid % Item)
+ for Item in _ConfigItem:
+ if not _ConfigItem[Item]['Value']:
+ EdkLogger.error("GenBiosId", FORMAT_UNKNOWN_ERROR, ExtraData="Item %s is missing" % Item)
+ utcnow = datetime.datetime.utcnow()
+ TimeStamp = time.strftime("%y%m%d%H%M", utcnow.timetuple())
+
+ Id_Str = _ConfigItem['BOARD_ID']['Value'] + _ConfigItem['BOARD_REV']['Value'] + '.' + _ConfigItem['BOARD_EXT']['Value'] + '.' + _ConfigItem['VERSION_MAJOR']['Value'] + \
+ '.' + _ConfigItem["BUILD_TYPE"]['Value'] + _ConfigItem['VERSION_MINOR']['Value'] + '.' + TimeStamp
+ with open(OutputFile, 'wb') as FdOut:
+ for i in _BIOS_Signature:
+ FdOut.write(struct.pack('B', ord(i)))
+
+ for i in Id_Str:
+ FdOut.write(struct.pack('H', ord(i)))
+
+ FdOut.write(struct.pack('H', 0x00))
+ if OutputBatchFile:
+ with open(OutputBatchFile, 'w') as FdOut:
+ if sys.platform.startswith('win'):
+ Id_Str = 'SET BIOS_ID=' + Id_Str
+ else:
+ Id_Str = 'export BIOS_ID=' + Id_Str
+ FdOut.write(Id_Str)
+ return 0
+
+if __name__ == '__main__':
+ r = Main()
+ ## 0-127 is a safe return range, and 1 is a standard default error
+ if r < 0 or r > 127: r = 1
+ sys.exit(r)
--
2.18.0.windows.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-06-14 7:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-28 1:32 [PATCH] BaseTools/GenBiosId: Add a new tool GenBiosId Zhang, Shenglei
2019-05-28 16:48 ` [edk2-devel] " Michael D Kinney
2019-05-31 6:36 ` Zhang, Shenglei
-- strict thread matches above, loose matches on Subject: below --
2019-06-14 7:38 Zhang, Shenglei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox