我的BIOS之行(10)-传值修改setup中的值

Posted AlexKing阁下

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的BIOS之行(10)-传值修改setup中的值相关的知识,希望对你有一定的参考价值。

前言

今天我的module算是大功告成,基本上已经能够将该有的功能都写完整了,如果你是跟这我做了一边,那么恭喜你,基本上你已经在uefi上基本算是入门了,可以自己写个module什么的来练练手什么的。

效果如下图

功能实现介绍

上一文,我们讲到了还需要实现通过pcie读取相关device的device id并将值回填给setup的item。
首先你得知道一点,我们是通过protocol的interface做了功能,其中一个就是要通过pci去读device id,读完以后要咋么传递呢?

实例分析

起初我的想法是比较简单的,直接用gui的hii接口就是了,但在这里,你却会发现一个坑人的情况,就是你根本无从获取到hiihandle。 然后我查阅了大量的代码发现没这个handle成不了事,于是导入这个hiihanle,但是最好这个结构能不能直接被用在我的dxe阶段。看起来好像无解了,其实我忘记了setup的界面可是在dxe阶段的最后,那么再传个值就是了。

建立setup变化项

像bios version之类的后面带值的就是可以进行改变的值。

在uni中重新写名称

#string STR_HOMEWORK_TEXT    #language eng      "Devices ID"
#string STR_HOMEWORK_TEXT_VALUE   #language eng      "N/A"
#string STR_HOMEWORK_FORM       #language eng      "PCI Device"
#string STR_HOMEWORK_FORM_HELP    #language eng      "it is my homework"
#string STR_HOMEWORK_VALUE0        #language eng      "device 0"
#string STR_HOMEWORK_VALUE1      #language eng      "device 1"
#string STR_HOMEWORK_VALUE2     #language eng      "device 2"

注意:STR_HOMEWORK_TEXT_VALUE就是我们要改变的值

在sd文件中建立选项

这个在前面业说过,但这里还用到了text,有机会后面会详细地介绍sd uni的语法。

SEPARATOR
        text
        help = STRING_TOKEN(STR_EMPTY),
        text = STRING_TOKEN(STR_HOMEWORK_TEXT),
        text = STRING_TOKEN(STR_HOMEWORK_TEXT_VALUE);

这样我们要修改的已经确定了。

让hiihandle飞起来

从大量的源码中,发现要改变setup的值有好几种,一种是在init的时候修改(最常用),一种是sdl中直接回调函数进行修改(很繁琐),另一种是自己获取hiihandle进行实现(最复杂)

在这里我就只用了第一种方案,

在sdl中进行elnk

ELINK
    Name = "InitHomeWorkStrings,"
    Parent = "SetupStringInit"
    InvokeOrder = AfterParent
End

ELINK
    Name  = "$(HomeWork_DIR)/HomeWork.c"
    Parent  = "SetupCallbackFiles"
    InvokeOrder = AfterParent
End

建立SetupStringInit函数

在homework.c中

InitHomeWorkStrings (
  EFI_HII_HANDLE HiiHandle,
  UINT16         Class
  )

其实做到这里我就开始郁闷了,咋么传值啊?试了直接用全局变量,没用,查阅有没有其他办法,看到GetVariable嗯嗯终于找到了(其实还有一种是把值放在memory里面,然后我去读值就可以了)

setvariable传值建立

在homeworkdxe.c中

UINT16 Value;
    Value = PciRead16(PCI_LIB_ADDRESS(busnum,devicenum,funcnum,0x02));
    pRS->SetVariable(
            L"Homeworkdeviceid",
            &gHomeWorkDeviceGuid,
            HOMEWOORK_VARIABLE_ATTRIBUTES,
            sizeof(Value),
            &Value
          );
    return EFI_SUCCESS;

PCiread16这个我就不说了,不懂,请回看前面,setvariable这个也请翻阅uefi spec,都是有说到的

获取值并改变setup item值

 UINT16              Value;
       UINTN               ValueSize;
       EFI_STATUS              Status;
       Status = pRS->GetVariable(L"Homeworkdeviceid",
           &gHomeWorkDeviceGuid,
           NULL,
           &ValueSize,
           &Value);
   //    OEM_TRACE("InitHomeWorkStrings=%x\\n",Value);
       if (!EFI_ERROR(Status)) 
           InitString(HiiHandle, STRING_TOKEN(STR_HOMEWORK_TEXT_VALUE), L"%x",Value);  
       

InitString(HiiHandle, STRING_TOKEN(STR_HOMEWORK_TEXT_VALUE), L"%x",Value);直接将setup的值写入

以上是关于我的BIOS之行(10)-传值修改setup中的值的主要内容,如果未能解决你的问题,请参考以下文章

我的BIOS之行-hob的使用

我的BIOS之行-protocol的使用与创建

我的BIOS之行-事件的使用

我的BIOS界面很特别,进入第二项后,没有BIOS SETUP

Vue3的setup基础

GRUB2 -> Buildroot:grub-bios-setup 中的分段错误