fwvolume.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,503 行 · 第 1/3 页
C
1,503 行
CFVConstructor (
VOID
)
{
mFileList = NULL;
mLastFile = NULL;
}
void
CFVDestructor (
VOID
)
{
CFVFreeFileList ();
//
// Free up our firmware volume list
//
while (mFVList != NULL) {
mFVListLast = mFVList->Next;
FREE (mFVList);
mFVList = mFVListLast;
}
}
static
void
CFVFreeFileList (
VOID
)
{
FILE_LIST *Next;
while (mFileList != NULL) {
if (mFileList->FileName != NULL) {
free (mFileList->FileName);
}
if (mFileList->FVs != NULL) {
free (mFileList->FVs);
}
free (mFileList->BaseFileName);
if (mFileList->BaseName != NULL) {
free (mFileList->BaseName);
}
if (mFileList->Processor != NULL) {
free (mFileList->Processor);
}
if (mFileList->Guid != NULL) {
free (mFileList->Guid);
}
Next = mFileList->Next;
free (mFileList);
mFileList = Next;
}
mFileList = NULL;
}
int
CFVWriteInfFiles (
DSC_FILE *DSC,
FILE *MakeFptr
)
/*++
Routine Description:
After processing all components in a DSC file, create the firmware
volume INF files. We actually do a lot more here.
* Create the FVxxx.inf file that is used by GenFvImage
* Create the Apriori files for each firmware volume that requires one
* Create makefile.out macros for FVxxx_FILES = FVxxx_FILES AnotherFile
so you can do incremental builds of firmware volumes.
* For each FV, emit its build commands to makefile.out
Arguments:
DSC - pointer to a DSC_FILE object to extract info from
MakeFptr - pointer to the output makefile
Returns:
0 if successful
non-zero otherwise
--*/
{
FILE_LIST *FileListPtr;
FV_LIST *FVList;
FV_LIST *LastFVList;
FV_LIST *FVPtr;
SECTION *Section;
char *StartCptr;
char *EndCptr;
char CSave;
char Str[MAX_PATH];
char Line[MAX_LINE_LEN];
char ExpandedLine[MAX_LINE_LEN];
char FVDir[MAX_PATH];
FILE *XRefFptr;
int AprioriCounter;
int AprioriCount;
int AprioriPosition;
BOOLEAN AprioriFound;
int ComponentsInstance;
int ComponentCount;
//
// Use this to keep track of all the firmware volume names
//
FVList = NULL;
LastFVList = NULL;
//
// See if they specified a FV directory to dump the FV files out to. If not,
// then use the default. Then create the output directory.
//
StartCptr = GetSymbolValue (FV_INF_DIR);
if (StartCptr == NULL) {
strcpy (Str, DEFAULT_FV_INF_DIR);
ExpandMacros (Str, FVDir, sizeof (FVDir), 0);
} else {
strcpy (FVDir, StartCptr);
}
//
// Make sure the fv directory path ends in /
//
CSave = FVDir[strlen (FVDir) - 1];
if ((CSave != '\\') && (CSave != '/')) {
strcat (FVDir, "\\");
}
//
// Traverse the list of all files, determine which FV each is in, then
// write out the file's name to the output FVxxx.inf file.
//
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
//
// Parse all the "FV1,FV2..." in the FVs
//
if (FileListPtr->FVs != NULL) {
//
// Process each fv this file is in
//
StartCptr = FileListPtr->FVs;
while (*StartCptr) {
EndCptr = StartCptr;
while (*EndCptr && (*EndCptr != ',')) {
EndCptr++;
}
CSave = *EndCptr;
*EndCptr = 0;
//
// Ok, we have a fv name, now see if we've already opened
// an fv output file of this name.
//
for (FVPtr = FVList; FVPtr != NULL; FVPtr = FVPtr->Next) {
if (_stricmp (FVPtr->FVFileName, StartCptr) == 0) {
break;
}
}
//
// If we didn't find one, then create a new one
//
if (FVPtr == NULL) {
//
// Create a new one, add it to the list
//
FVPtr = (FV_LIST *) malloc (sizeof (FV_LIST));
if (FVPtr == NULL) {
Error (NULL, 0, 0, NULL, "failed to allocate memory for FV");
return STATUS_ERROR;
}
memset ((char *) FVPtr, 0, sizeof (FV_LIST));
//
// Add it to the end of our list
//
if (FVList == NULL) {
FVList = FVPtr;
} else {
LastFVList->Next = FVPtr;
}
LastFVList = FVPtr;
//
// Save the FV name in the FileName pointer so we can compare
// for any future FV names specified.
//
strcpy (FVPtr->FVFileName, StartCptr);
//
// Add a symbol for the FV filename
//
UpperCaseString (FVPtr->FVFileName);
AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE);
//
// Now create the FVx.inf filename from the fv name and
// default filename extension. Dump it in the FV directory
// as well.
//
strcpy (Str, FVDir);
strcat (Str, FVPtr->FVFileName);
strcat (Str, ".inf");
//
// Create the directory path for our new fv.inf output file.
//
MakeFilePath (Str);
if ((FVPtr->FVFilePtr = fopen (Str, "w")) == NULL) {
Error (NULL, 0, 0, Str, "could not open FV output file");
return STATUS_ERROR;
}
//
// Now copy the [fv.$(FV).options] to the fv INF file
//
sprintf (Str, "fv.%s.options", StartCptr);
Section = DSCFileFindSection (DSC, Str);
if (Section != NULL) {
fprintf (FVPtr->FVFilePtr, "[options]\n");
while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) {
ExpandMacros (
Line,
ExpandedLine,
sizeof (ExpandedLine),
EXPANDMODE_NO_DESTDIR | EXPANDMODE_NO_SOURCEDIR
);
fprintf (FVPtr->FVFilePtr, ExpandedLine);
GetBaseAddress (ExpandedLine, FVPtr->BaseAddress);
}
} else {
Error (NULL, 0, 0, Str, "could not find FV section in description file");
}
//
// Copy the [fv.$(FV).attributes] to the fv INF file
//
sprintf (Str, "fv.%s.attributes", StartCptr);
Section = DSCFileFindSection (DSC, Str);
if (Section != NULL) {
fprintf (FVPtr->FVFilePtr, "[attributes]\n");
while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) {
fprintf (FVPtr->FVFilePtr, Line);
}
} else {
Error (NULL, 0, 0, Str, "Could not find FV section in description file");
}
//
// Start the files section
//
fprintf (FVPtr->FVFilePtr, "\n[files]\n");
}
//
// Now write the FV filename to the FV.inf file. Prepend $(PROCESSOR) on
// it.
//
fprintf (FVPtr->FVFilePtr, "EFI_FILE_NAME = %s\n", FileListPtr->FileName);
//
// Next FV on the FV list
//
*EndCptr = CSave;
StartCptr = EndCptr;
if (*StartCptr) {
StartCptr++;
}
}
}
}
//
// Now we walk the list of firmware volumes and create the APRIORI list
// file for it .
//
for (FVPtr = FVList; FVPtr != NULL; FVPtr = FVPtr->Next) {
//
// Run through all the files and count up how many are to be
// added to the apriori list for this FV. Then when we're done
// we'll make sure we processed them all. We do this in case they
// skipped an apriori index for a given FV.
//
AprioriCount = 0;
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
if (OrderInFvList (FileListPtr->Apriori, FVPtr->FVFileName, &AprioriPosition)) {
//
// Emit an error if the index was 0, or they didn't give one.
//
if (AprioriPosition == 0) {
Error (
GetSymbolValue (DSC_FILENAME),
1,
0,
"apriori indexes are 1-based",
"component %s:APRIORI=%s",
FileListPtr->BaseName,
FileListPtr->Apriori
);
} else {
AprioriCount++;
}
}
}
//
// Now scan the files as we increment our apriori index
//
AprioriCounter = 0;
do {
AprioriFound = 0;
AprioriCounter++;
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
//
// If in the apriori list for this fv, print the name. Open the
// file first if we have to.
//
if ((FileListPtr->Apriori[0] != 0) &&
(OrderInFvList (FileListPtr->Apriori, FVPtr->FVFileName, &AprioriPosition))
) {
if (AprioriPosition == AprioriCounter) {
//
// If we've already found one for this index, emit an error. Decrement the
// count of how files we are to process so we don't emit another error for
// a miscount below.
//
if (AprioriFound) {
Error (
GetSymbolValue (DSC_FILENAME),
1,
0,
"duplicate apriori index found",
"%s:%d",
FVPtr->FVFileName,
AprioriCounter
);
AprioriCount--;
}
AprioriFound = 1;
//
// Open the apriori output file if we haven't already
//
if (FVPtr->AprioriFilePtr == NULL) {
strcpy (Str, FVDir);
strcat (Str, FVPtr->FVFileName);
strcat (Str, ".apr");
if ((FVPtr->AprioriFilePtr = fopen (Str, "w")) == NULL) {
Error (NULL, 0, 0, Str, "could not open output Apriori file for writing");
return STATUS_ERROR;
}
}
fprintf (FVPtr->AprioriFilePtr, "%s\n", FileListPtr->BaseFileName);
}
}
}
} while (AprioriFound);
//
// See if they skipped an apriori position for this FV
//
if (AprioriCount != (AprioriCounter - 1)) {
Error (
GetSymbolValue (DSC_FILENAME),
1,
0,
"apriori index skipped",
"%s:%d",
FVPtr->FVFileName,
AprioriCounter
);
}
}
//
// Traverse the list of all files again, and create a macro in the output makefile
// that defines all the files in each fv. For example, for each FV file, create a line:
// FV0001_FILES = $(FV_0001_FILES) xxxx-yyy.dxe.
// This can then be used as a dependency in their makefile.
// Also if they wanted us to dump a cross-reference, do that now.
//
if (mXRefFileName != NULL) {
if ((XRefFptr = fopen (mXRefFileName, "w")) == NULL) {
Message (
0,
"Failed to open cross-reference file '%s' for writing\n",
mXRefFileName
);
}
} else {
XRefFptr = NULL;
}
for (FileListPtr = mFileList; FileListPtr != NULL; FileListPtr = FileListPtr->Next) {
//
// Parse all the "FV1,FV2..." in the FV field that came from FV=FVa,FVb,... on the
// component line in the DSC file.
//
if (FileListPtr->FVs != NULL) {
//
// If generating a cross-reference file, dump the data
//
if (XRefFptr != NULL) {
if ((FileListPtr->Guid != NULL) && (FileListPtr->BaseName != NULL) && (FileListPtr->Processor)) {
fprintf (
XRefFptr,
"%s %s %s\n",
FileListPtr->Guid,
FileListPtr->BaseName,
FileListPtr->Processor
);
}
}
//
// Convert to uppercase since we're going to use the name as a macro variable name
// in the makefile.
//
UpperCaseString (FileListPtr->FVs);
//
// Process each FV this file is in to write fvxxx_FILES = $(fvxxx_FILES) Guid-BaseName.ffs
//
StartCptr = FileListPtr->FVs;
while (*StartCptr) {
EndCptr = StartCptr;
while (*EndCptr && (*EndCptr != ',')) {
EndCptr++;
}
CSave = *EndCptr;
*EndCptr = 0;
fprintf (
MakeFptr,
"%s_FILES = $(%s_FILES) %s\n",
StartCptr,
StartCptr,
FileListPtr->FileName
);
//
// Next FV on the FV list
//
*EndCptr = CSave;
StartCptr = EndCptr;
if (*StartCptr) {
StartCptr++;
}
}
}
}
fprintf (MakeFptr, "\n");
//
// Now go through the list of all NonFFS FVs they specified and search for
// a [build.fv.$(FV)] or [build.fv] command and emit the commands to the
// output makefile. Add them to the "fvs" target as well.
//
if (mNonFfsFVList != NULL) {
fprintf (MakeFptr, "fvs ::");
FVPtr = mNonFfsFVList;
while (FVPtr != NULL) {
fprintf (MakeFptr, " %s%s.fv", FVDir, FVPtr->FVFileName);
FVPtr = FVPtr->Next;
}
fprintf (MakeFptr, "\n\n");
FVPtr = mNonFfsFVList;
while (FVPtr != NULL) {
//
// Save the position in the file
//
DSCFileSavePosition (DSC);
//
// first try to find a build section specific for this fv.
//
sprintf (Str, "build.fv.%s", FVPtr->FVFileName);
Section = DSCFileFindSection (DSC, Str);
if (Section == NULL) {
sprintf (Str, "build.fv");
Section = DSCFileFindSection (DSC, Str);
}
if (Section == NULL) {
Warning (
NULL,
0,
0,
NULL,
"No [build.fv.%s] nor [%s] section found in description file for building %s",
FVPtr->FVFileName,
Str,
FVPtr->FVFileName
);
} else {
//
// Add a symbol for the FV filename
//
UpperCaseString (FVPtr->FVFileName);
AddSymbol (FV_FILENAME, FVPtr->FVFileName, SYM_LOCAL | SYM_OVERWRITE);
AddSymbol (EFI_BASE_ADDRESS, FVPtr->BaseAddress, SYM_LOCAL | SYM_OVERWRITE);
//
// Now copy the build commands from the section to the makefile
//
while (DSCFileGetLine (DSC, Line, sizeof (Line)) != NULL) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?