Example #1
0
File: Bds.c Project: hzhuang1/uefi
EFI_STATUS
StartDefaultBootOnTimeout (
  VOID
  )
{
  UINTN               Size;
  UINT16              Timeout;
  UINT16              *TimeoutPtr;
  EFI_EVENT           WaitList[2];
  UINTN               WaitIndex;
  UINT16              *BootOrder = NULL;
  UINTN               BootOrderSize = 0;
  UINTN               Index;
  CHAR16              BootVariableName[9];
  EFI_STATUS          Status;
  EFI_INPUT_KEY       Key;
  LIST_ENTRY          BootOptionsList; 
  BOOLEAN             IsFlashBootFirst = FALSE;
  BOOLEAN             FlashBootSupport = FALSE;  

  // Get the Boot Option Order from the environment variable (a default value should have been created)
  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
  if (EFI_ERROR(Status))
  {
    DEBUG((EFI_D_ERROR, "%a(%d):Return a error Status\n", __FUNCTION__,__LINE__));
  }
  
  Status = GetBootDeviceTypeInfo();
  if (EFI_ERROR(Status))
  {
      DEBUG((EFI_D_ERROR, "%a(%d):Return a error Status\n", __FUNCTION__,__LINE__));
  }
  
  Status = OemBootOrderSeting(BootOrder,BootOrderSize,&IsFlashBootFirst,&FlashBootSupport);
  if (EFI_ERROR(Status))
  {
      DEBUG((EFI_D_ERROR, "%a(%d):Return a error Status\n", __FUNCTION__,__LINE__));
  }
  
  // Update (or Create) the BootOrder environment variable
  Status = gRT->SetVariable (
      L"BootOrder",
      &gEfiGlobalVariableGuid,
      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
      BootOrderSize,
      BootOrder
      );
  if (EFI_ERROR(Status))
  {
      DEBUG((EFI_D_ERROR, "%a(%d):SetVariable failed!\n", __FUNCTION__,__LINE__));
  }    
  
  Size = sizeof(UINT16);
  Timeout = (UINT16)PcdGet16 (PcdPlatformBootTimeOut);
  Status = GetGlobalEnvironmentVariable (L"Timeout", &Timeout, &Size, (VOID**)&TimeoutPtr);
  if (!EFI_ERROR (Status)) {
    Timeout = *TimeoutPtr;
    FreePool (TimeoutPtr);
  }

  if (Timeout != 0xFFFF) {
    if (Timeout > 0) {
      // Create the waiting events (keystroke and 1sec timer)
      gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &WaitList[0]);
      gBS->SetTimer (WaitList[0], TimerPeriodic, EFI_SET_TIMER_TO_SECOND);
      WaitList[1] = gST->ConIn->WaitForKey;

      // Start the timer
      WaitIndex = 0;
      Print(L"The default boot selection will start in ");
      while ((Timeout > 0) && (WaitIndex == 0)) {
        Print(L"%3d seconds",Timeout);
        gBS->WaitForEvent (2, WaitList, &WaitIndex);
        if (WaitIndex == 0) {
          Print(L"\b\b\b\b\b\b\b\b\b\b\b");
          Timeout--;
        }
      }
      // Discard key in the buffer
      do {
        Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
      } while(!EFI_ERROR(Status));
      gBS->CloseEvent (WaitList[0]);
      Print(L"\n\r");
    }

    // In case of Timeout we start the default boot selection
    if (Timeout == 0) {
      // Get the Boot Option Order from the environment variable (a default value should have been created)
      Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
      if (EFI_ERROR(Status))
      {
        DEBUG((EFI_D_ERROR, "%a(%d):Return a error Status\n", __FUNCTION__,__LINE__));
      }
      
      //display the final BootOrder EnviromentVariable, we'll start OS with it!
      BootOptionList (&BootOptionsList);
      DisplayBootOptions(&BootOptionsList);
      
      if(FlashBootSupport)
      {
        if(IsFlashBootFirst)
        {
          Print(L"Bds TimeOut First Start Boot Option [FLASH] ....Begin!...\n\r");                  
          Flash_Start_OS ();
          Print(L"Bds TimeOut First Start Boot Option [FLASH] ....Fail!...\n\r");          
        }
      }
      
      for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
        UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOrder[Index]);
        OemPreStartBootOptionAction(BootOrder[Index]);
        Print(L"Bds TimeOut Start Boot Option [%s] ....Begin!...\n\r",BootVariableName);                  
        Status = BdsStartBootOption (BootVariableName);
        if(!EFI_ERROR(Status)){
          // Boot option returned successfully, hence don't need to start next boot option
          break;
        }
        Print(L"Bds TimeOut Start Boot Option [%s] ....Fail!...\n\r",BootVariableName);          
      }
      
      if(FlashBootSupport)
      {
          if(!IsFlashBootFirst)
          {
            Print(L"Bds TimeOut Start Boot Option [FLASH] ....Begin!...\n\r");             
            Flash_Start_OS ();
            Print(L"Bds TimeOut Start Boot Option [FLASH] ....Fail!...\n\r");            
          }
      }else{}
      
      // We only free it if the UEFI Variable 'BootOrder' was already existing
      if (BootOrderSize > sizeof(UINT16)) {
        FreePool (BootOrder);
      }
      
      OpenAlarmLed();
      Print(L"[WARNING]Bds TimeOut: All Boot Option Start Fail! Lighting The Alarm Led!!! \n\r");     
    }
  }
  return EFI_SUCCESS;
}
Example #2
0
EFI_STATUS
BootMenuMain (
  VOID
  )
{
  LIST_ENTRY                    BootOptionsList;
  UINTN                         OptionCount;
  UINTN                         BootOptionCount;
  EFI_STATUS                    Status;
  LIST_ENTRY*                   Entry;
  BDS_LOAD_OPTION*              BootOption;
  UINTN                         BootOptionSelected;
  UINTN                         Index;
  UINTN                         BootMainEntryCount;
  BOOLEAN                       IsUnicode;

  BootOption         = NULL;
  BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY);

  while (TRUE) {
    // Get Boot#### list
    BootOptionList (&BootOptionsList);

    OptionCount = 1;

    // Display the Boot options
    for (Entry = GetFirstNode (&BootOptionsList);
         !IsNull (&BootOptionsList,Entry);
         Entry = GetNextNode (&BootOptionsList,Entry)
         )
    {
      BootOption = LOAD_OPTION_FROM_LINK(Entry);

      Print(L"[%d] %s\n", OptionCount, BootOption->Description);

      DEBUG_CODE_BEGIN();
        CHAR16*                           DevicePathTxt;
        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
        ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;
        UINTN                             CmdLineSize;
        ARM_BDS_LOADER_TYPE               LoaderType;

        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (EFI_ERROR(Status)) {
          // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)
          DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));
          return Status;
        }
        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);

        Print(L"\t- %s\n",DevicePathTxt);

        // If it is a supported BootEntry then print its details
        if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
          OptionalData = BootOption->OptionalData;
          LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);
          if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) {
              CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize);
              DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (
                  GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE);
              Print(L"\t- Initrd: %s\n", DevicePathTxt);
            }
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) {
              Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1));
            }
          }

          switch (LoaderType) {
            case BDS_LOADER_EFI_APPLICATION:
              Print(L"\t- LoaderType: EFI Application\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_ATAG:
              Print(L"\t- LoaderType: Linux kernel with ATAG support\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_FDT:
              Print(L"\t- LoaderType: Linux kernel with FDT support\n");
              break;

            default:
              Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType);
          }
        } else if (BootOption->OptionalData != NULL) {
          if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) {
            if (IsUnicode) {
              Print (L"\t- Arguments: %s\n", BootOption->OptionalData);
            } else {
              AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData);
            }
          }
        }
        FreePool(DevicePathTxt);
      DEBUG_CODE_END();

      OptionCount++;
    }
    BootOptionCount = OptionCount-1;

    // Display the hardcoded Boot entries
    for (Index = 0; Index < BootMainEntryCount; Index++) {
      Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]);
      OptionCount++;
    }

    // Request the boot entry from the user
    BootOptionSelected = 0;
    while (BootOptionSelected == 0) {
      Print(L"Start: ");
      Status = GetHIInputInteger (&BootOptionSelected);
      if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) {
        Print(L"Invalid input (max %d)\n",(OptionCount-1));
        BootOptionSelected = 0;
      }
    }

    // Start the selected entry
    if (BootOptionSelected > BootOptionCount) {
      // Start the hardcoded entry
      Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList);
    } else {
      // Find the selected entry from the Boot#### list
      Index = 1;
      for (Entry = GetFirstNode (&BootOptionsList);
           !IsNull (&BootOptionsList,Entry);
           Entry = GetNextNode (&BootOptionsList,Entry)
           )
      {
        if (Index == BootOptionSelected) {
          BootOption = LOAD_OPTION_FROM_LINK(Entry);
          break;
        }
        Index++;
      }

      Status = BootOptionStart (BootOption);
    }
  }
  // Should never go here
}
Example #3
0
File: Bds.c Project: hzhuang1/uefi
EFI_STATUS
GetBootDeviceTypeInfo (
  VOID
  )
{
    EFI_STATUS        Status = EFI_SUCCESS;
    LIST_ENTRY        BootOptionsList;
    LIST_ENTRY*       Entry;    
    UINT16            *SataDes = NULL;
    UINT16            *MacDes = NULL;
    UINTN             SataDesSize = 0;
    UINTN             MacDesSize = 0; 
    BDS_LOAD_OPTION*  BootOption;
    UINTN             OptionCount = 0;
    CHAR16*           SataStr = L"Sata";
    CHAR16*           MacStr = L"MAC";
    CHAR16*           DevicePathTxt = NULL;
    EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol = NULL;    
    
    // Get Boot#### list
    BootOptionList (&BootOptionsList);
    // Display the Boot options
    for (Entry = GetFirstNode (&BootOptionsList);
     !IsNull (&BootOptionsList,Entry);
     Entry = GetNextNode (&BootOptionsList,Entry)
     )
    {
        BootOption = LOAD_OPTION_FROM_LINK(Entry);
        //Print(L"[%d] %s\n", OptionCount, BootOption->Description);
        //DEBUG_CODE_BEGIN();
        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (EFI_ERROR(Status)) {
            // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)
            DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));
            return Status;
        }
        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);
         //Print(L"\t- %s\n",DevicePathTxt);
        //DEBUG_CODE_END();        
         //FIND SATA BOOT DEVICES       
        if(!(StringFind(DevicePathTxt, SataStr)))
        {                        
            if(SataDesSize != 0)
            {
                SataDes = ReallocatePool (SataDesSize, SataDesSize + sizeof(UINT16), SataDes);
                SataDes[SataDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;
                SataDesSize += sizeof(UINT16);
            }else{
                SataDesSize = sizeof(UINT16);
                SataDes = &(BootOption->LoadOptionIndex);
            }
           // Print(L"liuhuan SATA boot num: %d\n",SataDesSize / sizeof(UINT16));
        }        
        //FIND PXE BOOT DEVICES
        if(!(StringFind(DevicePathTxt, MacStr) ))            
        {                        
            if(MacDesSize != 0)
            {
                MacDes = ReallocatePool (MacDesSize, MacDesSize + sizeof(UINT16), MacDes);
                MacDes[MacDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;
                MacDesSize += sizeof(UINT16);
            }else{
                MacDesSize = sizeof(UINT16);
                MacDes = &(BootOption->LoadOptionIndex);
            }
         //   Print(L"liuhuan PXE boot num: %d\n",MacDesSize / sizeof(UINT16));
        }
        //FreePool(DevicePathTxt);    
        OptionCount++;
    }
     
    OemGetSataBootNum(SataDesSize);
    OemGetPXEBootNum(MacDesSize);

    if(SataDes != NULL)
    {
        FreePool(SataDes);
    }
    if(MacDes != NULL)
    {
        FreePool(MacDes);
    }
    if(DevicePathTxt != NULL)
    {
        FreePool(DevicePathTxt);
    }
    return EFI_SUCCESS;
}