EDK2 VfrCompiler 代码流程分析

全局变量:

gCIfrRecordInfoDB

  1. 在函数CVfrCompiler::OptionInitialization解析过程中,如果用户输入参数"-l" 则打开RecordInfo的开关。调用 gCIfrRecordInfoDB.TurnOn () 实现
  1. CIfrRecordInfoDB的一个实例,用于记录创建的所有opcode的链表,内部通过变量SIfrRecord指针来维护所有opcode信息,具体记录opcode信息包括mLineNomIfrBinBufmBinBufLen mOffset,均保存在SIfrRecord结构中。SIfrRecord通过变量mRecordCountmIfrRecordListHeadmIfrRecordListHead维护。该类的主要成员函数包括:
    1. IfrRecordRegister
      1. 创建新的SIfrRecord来记录新创建的opcode信息。

 

gCVfrVarDataTypeDB

  1. 在函数EfiVfrParser::vfrProgram中,初始化创建基本数据类型时,第一次使用。

 

gCFormPkg

  1. 在类CIfrObj的构造函数中被调用,主要用户维护Form binary数据的组织。
  1. CFormPkg的一个实例,该类用于记录当前创建的所有opcodebinary data,保存在内部以SBufferNode类指针指向的内存空间中。主要的成员函数包括:
    1. IfrBinBufferGet (Len)
      1. 从SBufferNode内存空间中分配Len长度数据,用于存放opcode对应的binary data。如果SBufferNode空间不够,动态申请新的SBufferNode成员来保存新的opcodeCFormPkg内部通过mBufferNodeQueueHead, mBufferNodeQueueTail,  mCurrBufferNode三个变量来维护SBufferNode数据。

 

mCVfrDataStorage

  1. 作为类的一个成员变量,主要负责维护系统中所有的storage。在varstore相关opcode中创建新的storage。在question的声明中使用这些storage

 

gCVfrBufferConfig

  1. buffer varstore的声明函数中第一次使用,主要用于记录各个buffer store中各个memberdefault value。该类的成员变量是SConfigItem SConfigItem中包含的成员变量如下:

  CHAR8         *mName;         // varstore name

  EFI_GUID      *mGuid;         // varstore guid, varstore name + guid deside one varstore

  CHAR8         *mId;           // default ID

  SConfigInfo   *mInfoStrList;  // list of Offset/Value in the varstore

  SConfigItem   *mNext;

  1. 在每个buffer varstore的声明函数(CVfrDataStorage::DeclareBufferVarStore)中会调用CVfrBufferConfig::Register函数来注册该varstore CVfrBufferConfig类中。
  1. 在每个opcode中如果有default value 的声明,则对应的opcode会调用函数CVfrDefaultStore::BufferVarStoreAltConfigAdd 最终调用gCVfrBufferConfig.Write来添加该default value到对应的varstore中。

 

CVfrCompiler::CVfrCompiler ()

1.调用函数OptionInitialization对输入参数进行解析,并对整个环境进行初始化

2.初始化成功后,设定当前执行状态为STATUS_INITIALIZED

 

CVfrCompiler::PreProcess()

1.拼装预处理命令行参数,调用system函数进行预处理

2.预处理成功后,设定当前执行状态为STATUS_PREPROCESSED

 

 

CVfrCompiler::Compile()

  1. VfrParserStart ()
    1. 这是一个全局函数,主要作用是创建parse主类,即EfiVfrParser类。
    1. 调用类的接口函数来初始化该类的一些环境设定。
    1. 最后调用类的vfrProgram函数来进行Vfr文件的解析。

                                  

EfiVfrParser::vfrProgram

  1. 在解析 vfrPragmaPackDefinition vfrDataStructDefinition阶段,主要是通过全局变量gCVfrVarDataTypeDB来实现基本数据类型(通过预设的全局变量gInternalTypesTable实现)和用户新创建数据结构类型的构建。
  1. 在解析vfrFormSetDefinition阶段:
    1. 针对每一个opcode,创建该opcode对应的类实例:
      1. 这些opcode对应的类,都是继承于类CIfrObj CIfrOpHeader
      1. 在创建每个opcode对应的类实例时,会调用类的构建函数,进而调用类CIfrObjCIfrOpHeader的构造函数。
      1. 在类CIfrObj的构造函数中:
        1. 调用gCFormPkg.GetPkgLength函数来获取form中该opcode生成binary的相对位置。
        1. 调用函数gCFormPkg.IfrBinBufferGet获取该opcodeformbinary buffer的起始位置
        1. 调用函数gCIfrRecordInfoDB.IfrRecordRegister获取该opcode在整个IFR数据库中的相对位置。
        1. 如果类的构造函数中DelayEmit变量为TRUE,则在构造函数中只是申请临时buffer来保存,最终的buffer会在类的析构函数中从Formbinary data中申请。
      1. 在类CIfrObj的析构函数中:
        1. 如果类的构造函数中DelayEmit变量为TRUE,则在构造函数中只是申请临时buffer来保存,最终的buffer会在类的析构函数中从Formbinary data中申请。
        1. 调用函数gCIfrRecordInfoDB.IfrRecordInfoUpdate,将该opcode对应的信息记录到IFR数据库中。
      1. 在类CIfrOpHeader的构造函数中:
        1. 通过预先设定好的全局数据结构gOpcodeSizesScopeTable获取该opcode的信息,包括opcode代码,opcode长度和opcodescope
        1. 该类没有析构函数。
      1. 之后调用该opcode的构造函数:
        1. 主要工作是初始化该类自己的相关成员变量。
      1. 总结:每个opcodebinary的生成,分为三个部分实现:
        1. CIfrObj实现:
          1. Binary data 空间的指向
          1. 在整个Form data中的相对位置
          1. opcode对应的length
        1. CIfrOpHeader实现:
          1. opcodetag
          1. opcodelength
          1. opcodescope
        1. opcode的类实现:
          1. opcode特有的数据结构数据的保存。
  1. 在各种varstore创建的过程中:
    1. 首先该varstore对应的opcode需要创建,另外,每个varstore还需要创建对应的storage
      1. 对于Buffer varstore:
        1. 通过VFR info获取该opcode对应的各种信息。
        1. 调用函数mCVfrDataStorage.DeclareBufferVarStore创建buffer typevarstore

 

CVfrCompiler::AdjustBin()

    1.Call UpdateInfoForDynamicOpcode function to adjust data maintained by gCIfrRecordInfoDB.

    2.Generate binary data from gCFormPkg and gCIfrRecordInfoDB, compare the data and make sure generate the same binary data.

    

CVfrCompiler::GenBinary ()

    1.Generate binary data from gCFormPkg.


 CVfrCompiler::GenRecordListFile ()

    1.If the -l command parameter is input, in this function, vfrcompiler will create a *.lst file to save the data for each opcode, it is used for debug.


你可能感兴趣的:(EDK2 VfrCompiler 代码流程分析)