全局变量:
gCIfrRecordInfoDB
- 在函数CVfrCompiler::OptionInitialization解析过程中,如果用户输入参数"-l", 则打开RecordInfo的开关。调用 gCIfrRecordInfoDB.TurnOn () 实现
- 类CIfrRecordInfoDB的一个实例,用于记录创建的所有opcode的链表,内部通过变量SIfrRecord指针来维护所有opcode信息,具体记录opcode信息包括mLineNo,mIfrBinBuf,mBinBufLen, mOffset,均保存在SIfrRecord结构中。SIfrRecord通过变量mRecordCount,mIfrRecordListHead,mIfrRecordListHead维护。该类的主要成员函数包括:
- IfrRecordRegister
- 创建新的SIfrRecord来记录新创建的opcode信息。
- IfrRecordRegister
gCVfrVarDataTypeDB
- 在函数EfiVfrParser::vfrProgram中,初始化创建基本数据类型时,第一次使用。
gCFormPkg
- 在类CIfrObj的构造函数中被调用,主要用户维护Form binary数据的组织。
- 类CFormPkg的一个实例,该类用于记录当前创建的所有opcode的binary data,保存在内部以SBufferNode类指针指向的内存空间中。主要的成员函数包括:
- IfrBinBufferGet (Len)
- 从SBufferNode内存空间中分配Len长度数据,用于存放opcode对应的binary data。如果SBufferNode空间不够,动态申请新的SBufferNode成员来保存新的opcode。CFormPkg内部通过mBufferNodeQueueHead, mBufferNodeQueueTail, mCurrBufferNode三个变量来维护SBufferNode数据。
- IfrBinBufferGet (Len)
mCVfrDataStorage
- 作为类的一个成员变量,主要负责维护系统中所有的storage。在varstore相关opcode中创建新的storage。在question的声明中使用这些storage。
gCVfrBufferConfig
- 在buffer varstore的声明函数中第一次使用,主要用于记录各个buffer store中各个member的default 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;
- 在每个buffer varstore的声明函数(CVfrDataStorage::DeclareBufferVarStore)中会调用CVfrBufferConfig::Register函数来注册该varstore 到CVfrBufferConfig类中。
- 在每个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()
- VfrParserStart ()
- 这是一个全局函数,主要作用是创建parse主类,即EfiVfrParser类。
- 调用类的接口函数来初始化该类的一些环境设定。
- 最后调用类的vfrProgram函数来进行Vfr文件的解析。
EfiVfrParser::vfrProgram
- 在解析 vfrPragmaPackDefinition 和vfrDataStructDefinition阶段,主要是通过全局变量gCVfrVarDataTypeDB来实现基本数据类型(通过预设的全局变量gInternalTypesTable实现)和用户新创建数据结构类型的构建。
- 在解析vfrFormSetDefinition阶段:
- 针对每一个opcode,创建该opcode对应的类实例:
- 这些opcode对应的类,都是继承于类CIfrObj和 CIfrOpHeader。
- 在创建每个opcode对应的类实例时,会调用类的构建函数,进而调用类CIfrObj和CIfrOpHeader的构造函数。
- 在类CIfrObj的构造函数中:
- 调用gCFormPkg.GetPkgLength函数来获取form中该opcode生成binary的相对位置。
- 调用函数gCFormPkg.IfrBinBufferGet获取该opcode在form的binary buffer的起始位置
- 调用函数gCIfrRecordInfoDB.IfrRecordRegister获取该opcode在整个IFR数据库中的相对位置。
- 如果类的构造函数中DelayEmit变量为TRUE,则在构造函数中只是申请临时buffer来保存,最终的buffer会在类的析构函数中从Form的binary data中申请。
- 在类CIfrObj的析构函数中:
- 如果类的构造函数中DelayEmit变量为TRUE,则在构造函数中只是申请临时buffer来保存,最终的buffer会在类的析构函数中从Form的binary data中申请。
- 调用函数gCIfrRecordInfoDB.IfrRecordInfoUpdate,将该opcode对应的信息记录到IFR数据库中。
- 在类CIfrOpHeader的构造函数中:
- 通过预先设定好的全局数据结构gOpcodeSizesScopeTable获取该opcode的信息,包括opcode代码,opcode长度和opcode的scope。
- 该类没有析构函数。
- 之后调用该opcode的构造函数:
- 主要工作是初始化该类自己的相关成员变量。
- 总结:每个opcode的binary的生成,分为三个部分实现:
- CIfrObj实现:
- Binary data 空间的指向
- 在整个Form data中的相对位置
- 该opcode对应的length。
- CIfrOpHeader实现:
- 该opcode的tag
- 该opcode的length
- 该opcode的scope
- opcode的类实现:
- 该opcode特有的数据结构数据的保存。
- CIfrObj实现:
- 针对每一个opcode,创建该opcode对应的类实例:
- 在各种varstore创建的过程中:
- 首先该varstore对应的opcode需要创建,另外,每个varstore还需要创建对应的storage:
- 对于Buffer varstore:
- 通过VFR info获取该opcode对应的各种信息。
- 调用函数mCVfrDataStorage.DeclareBufferVarStore创建buffer type的varstore。
- 对于Buffer varstore:
- 首先该varstore对应的opcode需要创建,另外,每个varstore还需要创建对应的storage:
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.