pretty code

2017年10月26日 星期四

UEFI Shell

最近需要 pass Shell Env to my shell script
原本以為是很難的事
幸好 UEFI 在 C Lib 中就提供了 setenv 函數

不過事情不是憨人想的那樣
呼叫此 function 會失敗
從 errno 中看到失敗值是 45 表示 unsupport

沒關係除了 setenv,我們還有二個方式
1. UefiShellLib 的 ShellSetEnvironmentVariable(後來才發現 setenv 也是 call 它)
2. 使用 SHELL PROTOCOL

很不幸的 2 個方式都會 gg,回傳的值是 3  (EFI_UNSUPPORTED)
此時直覺是 INF 設定有問題,調整老半天還是搞不定

後來換了 UEFI Shell 後,事情總算解決了
不過此時又跑出一個新的 question

EdkShellBinPkg 還有 ShellBinPkg 裡面都有 Shell Binary
為什麼一個可以成功,一個卻不行
過了一個禮拜終於在 官網 github 找到答案

簡單來說 EdkShellBinPkg 是 v1.0 的 Shell Spec
ShellBinPkg 是 v2.0 的 Shell Spec
我們從下圖的註解便可以得知
需要 UEFI Shell 2.0 的環境才能支援


/**
  set the value of an environment variable

This function changes the current value of the specified environment variable. If the
environment variable exists and the Value is an empty string, then the environment
variable is deleted. If the environment variable exists and the Value is not an empty
string, then the value of the environment variable is changed. If the environment
variable does not exist and the Value is an empty string, there is no action. If the
environment variable does not exist and the Value is a non-empty string, then the
environment variable is created and assigned the specified value.

  This is not supported pre-UEFI Shell 2.0.

  @param EnvKey                 The key name of the environment variable.
  @param EnvVal                 The Value of the environment variable
  @param Volatile               Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE).

  @retval EFI_SUCCESS           the operation was completed sucessfully
  @retval EFI_UNSUPPORTED       This operation is not allowed in pre UEFI 2.0 Shell environments
**/
EFI_STATUS
EFIAPI
ShellSetEnvironmentVariable (
  IN CONST CHAR16               *EnvKey,
  IN CONST CHAR16               *EnvVal,
  IN BOOLEAN                    Volatile
  )
{
  //
  // Check for UEFI Shell 2.0 protocols
  //
  if (gEfiShellProtocol != NULL) {
    return (gEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile));
  }

底下分別是 EdkShellBinPkg 和 ShellBinPkg 的 Shell version information







沒有留言: