Add CWD and thus a cd command to EBL shell. Fix WatchdogTimout code in EBL, it was inside a PCD feature flag and should have been outside of the PCD so it is in all paths.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9958 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish 2010-02-10 00:46:41 +00:00
parent 99ff63cf03
commit 16ccac42cf
4 changed files with 204 additions and 18 deletions

View File

@ -52,7 +52,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gFvFileType[] = {
only print out files that contain the string *.efi only print out files that contain the string *.efi
dir fv1:\ ; perform a dir on fv1: device in the efi directory dir fv1:\ ; perform a dir on fv1: device in the efi directory
NOTE: fv devices do not contian subdirs NOTE: fv devices do not contian subdirs
dir fv1:\ * PEIM ; will match all files of type SEC dir fv1:\ * PEIM ; will match all files of type PEIM
@param Argc Number of command arguments in Argv @param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line. @param Argv Array of strings that represent the parsed command line.
@ -88,14 +88,19 @@ EblDirCmd (
UINTN Length; UINTN Length;
UINTN BestMatchCount; UINTN BestMatchCount;
CHAR16 UnicodeFileName[MAX_CMD_LINE]; CHAR16 UnicodeFileName[MAX_CMD_LINE];
CHAR8 *Path;
if (Argc <= 1) { if (Argc <= 1) {
// CWD not currently supported Path = EfiGetCwd ();
return EFI_SUCCESS; if (Path == NULL) {
return EFI_SUCCESS;
}
} else {
Path = Argv[1];
} }
File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0); File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
if (File == NULL) { if (File == NULL) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -277,6 +282,32 @@ Done:
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Change the Current Working Directory
Argv[0] - "cd"
Argv[1] - Device Name:path. Path is optional
@param Argc Number of command arguments in Argv
@param Argv Array of strings that represent the parsed command line.
Argv[0] is the comamnd name
@return EFI_SUCCESS
**/
EFI_STATUS
EblCdCmd (
IN UINTN Argc,
IN CHAR8 **Argv
)
{
if (Argc <= 1) {
return EFI_SUCCESS;
}
return EfiSetCwd (Argv[1]);
}
GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] = GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =
@ -286,6 +317,12 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mCmdDirTemplate[] =
" dirdev [*match]; directory listing of dirdev. opt match a substring", " dirdev [*match]; directory listing of dirdev. opt match a substring",
NULL, NULL,
EblDirCmd EblDirCmd
},
{
"cd",
" device - set the current working directory",
NULL,
EblCdCmd
} }
}; };

View File

@ -464,7 +464,7 @@ EblPrompt (
) )
{ {
EblSetTextColor (EFI_YELLOW); EblSetTextColor (EFI_YELLOW);
AsciiPrint ((CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt)); AsciiPrint ((CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());
EblSetTextColor (0); EblSetTextColor (0);
AsciiPrint ("%a", ">"); AsciiPrint ("%a", ">");
} }
@ -559,6 +559,9 @@ EdkBootLoaderEntry (
EblInitializeExternalCmd (); EblInitializeExternalCmd ();
EblInitializeNetworkCmd(); EblInitializeNetworkCmd();
// Disable the 5 minute EFI watchdog time so we don't get automatically reset
gBS->SetWatchdogTimer (0, 0, 0, NULL);
if (FeaturePcdGet (PcdEmbeddedMacBoot)) { if (FeaturePcdGet (PcdEmbeddedMacBoot)) {
// A MAC will boot in graphics mode, so turn it back to text here // A MAC will boot in graphics mode, so turn it back to text here
// This protocol was removed from edk2. It is only an edk thing. We need to make our own copy. // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.
@ -567,8 +570,6 @@ EdkBootLoaderEntry (
// Enable the biggest output screen size possible // Enable the biggest output screen size possible
gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1); gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);
// Disable the 5 minute EFI watchdog time so we don't get automatically reset
gBS->SetWatchdogTimer (0, 0, 0, NULL);
} }
// Save current screen mode // Save current screen mode

View File

@ -341,7 +341,7 @@ EfiSetCwd (
**/ **/
CHAR8 * CHAR8 *
EfiGettCwd ( EfiGetCwd (
VOID VOID
); );

View File

@ -647,7 +647,7 @@ EfiOpen (
File->FvSectionType = SectionType; File->FvSectionType = SectionType;
StrLen = AsciiStrSize (PathName); StrLen = AsciiStrSize (PathName);
if (StrLen <= 2) { if (StrLen <= 1) {
// Smallest valid path is 1 char and a null // Smallest valid path is 1 char and a null
return NULL; return NULL;
} }
@ -659,7 +659,7 @@ EfiOpen (
} }
} }
if (FileStart == 0) { if (FileStart == StrLen) {
if (gCwd == NULL) { if (gCwd == NULL) {
// No CWD // No CWD
return NULL; return NULL;
@ -671,8 +671,31 @@ EfiOpen (
return NULL; return NULL;
} }
AsciiStrCpy (CwdPlusPathName, gCwd); if ((PathName[0] == '/') || (PathName[0] == '\\')) {
// PathName starts in / so this means we go to the root of the device in the CWD.
CwdPlusPathName[0] = '\0';
for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
CwdPlusPathName[FileStart] = gCwd[FileStart];
if (gCwd[FileStart] == ':') {
FileStart++;
CwdPlusPathName[FileStart] = '\0';
break;
}
}
} else {
AsciiStrCpy (CwdPlusPathName, gCwd);
StrLen = AsciiStrLen (gCwd);
if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
AsciiStrCat (CwdPlusPathName, "/");
}
}
AsciiStrCat (CwdPlusPathName, PathName); AsciiStrCat (CwdPlusPathName, PathName);
if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
// Extra error check to make sure we don't recusre and blow stack
return NULL;
}
File = EfiOpen (CwdPlusPathName, OpenMode, SectionType); File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
FreePool (CwdPlusPathName); FreePool (CwdPlusPathName);
return File; return File;
@ -690,6 +713,10 @@ EfiOpen (
AsciiStrCpy (File->DeviceName, PathName); AsciiStrCpy (File->DeviceName, PathName);
File->DeviceName[FileStart - 1] = '\0'; File->DeviceName[FileStart - 1] = '\0';
File->FileName = &File->DeviceName[FileStart]; File->FileName = &File->DeviceName[FileStart];
if (File->FileName[0] == '\0') {
// if it is just a file name use / as root
File->FileName = "/";
}
// //
// Use best match algorithm on the dev names so we only need to look at the // Use best match algorithm on the dev names so we only need to look at the
@ -1500,6 +1527,82 @@ EfiWrite (
} }
/**
Given Cwd expand Path to remove .. and replace them with real
directory names.
@param Cwd Current Working Directory
@param Path Path to expand
@return NULL Cwd or Path are not valid
@return 'other' Path with .. expanded
**/
CHAR8 *
ExpandPath (
IN CHAR8 *Cwd,
IN CHAR8 *Path
)
{
CHAR8 *NewPath;
CHAR8 *Work, *Start, *End;
UINTN StrLen;
UINTN i;
if (Cwd == NULL || Path == NULL) {
return NULL;
}
StrLen = AsciiStrSize (Cwd);
if (StrLen <= 2) {
// Smallest valid path is 1 char and a null
return NULL;
}
StrLen = AsciiStrSize (Path);
NewPath = AllocatePool (AsciiStrSize (Cwd) + StrLen + 1);
if (NewPath == NULL) {
return NULL;
}
AsciiStrCpy (NewPath, Cwd);
End = Path + StrLen;
for (Start = Path ;;) {
Work = AsciiStrStr (Start, "..") ;
if (Work == NULL) {
// Remaining part of Path contains no more ..
break;
}
// append path prior to ..
AsciiStrnCat (NewPath, Start, Work - Start);
StrLen = AsciiStrLen (NewPath);
for (i = StrLen; i >= 0; i--) {
if (NewPath[i] == ':') {
// too many ..
return NULL;
}
if (NewPath[i] == '/' || NewPath[i] == '\\') {
if ((i > 0) && (NewPath[i-1] == ':')) {
// leave the / before a :
NewPath[i+1] = '\0';
} else {
// replace / will Null to remove trailing file/dir reference
NewPath[i] = '\0';
}
break;
}
}
Start = Work + 3;
}
// Handle the path that remains after the ..
AsciiStrnCat (NewPath, Start, End - Start);
return NewPath;
}
/** /**
Set the Curent Working Directory (CWD). If a call is made to EfiOpen () and Set the Curent Working Directory (CWD). If a call is made to EfiOpen () and
@ -1518,23 +1621,65 @@ EfiSetCwd (
) )
{ {
EFI_OPEN_FILE *File; EFI_OPEN_FILE *File;
UINTN Len;
CHAR8 *Path;
File = EfiOpen (Cwd, EFI_FILE_MODE_READ, 0); if (Cwd == NULL) {
if (File == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
EfiClose (File); if (AsciiStrCmp (Cwd, ".") == 0) {
// cd . is a no-op
return EFI_SUCCESS;
}
Path = Cwd;
if (AsciiStrStr (Cwd, "..") != NULL) {
if (gCwd == NULL) {
// no parent
return EFI_SUCCESS;
}
Len = AsciiStrLen (gCwd);
if ((gCwd[Len-2] == ':') && ((gCwd[Len-1] == '/') || (gCwd[Len-1] == '\\'))) {
// parent is device so nothing to do
return EFI_SUCCESS;
}
// Expand .. in Cwd, given we know current working directory
Path = ExpandPath (gCwd, Cwd);
if (Path == NULL) {
return EFI_NOT_FOUND;
}
}
File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
if (File == NULL) {
return EFI_INVALID_PARAMETER;
}
if (gCwd != NULL) { if (gCwd != NULL) {
FreePool (gCwd); FreePool (gCwd);
} }
gCwd = AllocatePool (AsciiStrSize (Cwd)); // Use the info returned from EfiOpen as it can add in CWD if needed. So Cwd could be
// relative to the current gCwd or not.
gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 1);
if (gCwd == NULL) { if (gCwd == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
AsciiStrCpy (gCwd, Cwd); AsciiStrCpy (gCwd, File->DeviceName);
if (File->FileName == NULL) {
AsciiStrCat (gCwd, ":\\");
} else {
AsciiStrCat (gCwd, ":");
AsciiStrCat (gCwd, File->FileName);
}
EfiClose (File);
if (Path != Cwd) {
FreePool (Path);
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1549,15 +1694,18 @@ EfiSetCwd (
@param Cwd Current Working Directory @param Cwd Current Working Directory
@return NULL No CWD set @return "" No CWD set
@return 'other' Returns buffer that contains CWD. @return 'other' Returns buffer that contains CWD.
**/ **/
CHAR8 * CHAR8 *
EfiGettCwd ( EfiGetCwd (
VOID VOID
) )
{ {
if (gCwd == NULL) {
return "";
}
return gCwd; return gCwd;
} }