EFI LIST

来源:互联网 发布:佛山陶瓷出口数据 编辑:程序博客网 时间:2024/05/04 08:33

EFI LIST

List是一个非常常见的数据结构,学过C的童鞋肯定都会非常熟悉这个东东,上学的时候老师都会教我们按照如下的方式定义一个双向List。

typedef struct  _list_node {

struct _list_node * Flink;

struct _list_node * Blink;

uint32   data;

}list;

乍看这个list也没什么不好 中规中矩大家都是这么用的,可是我们来看一下EDK中的list的实现方式,就会发现还是有一丁点的差异。

typedef struct _EFI_LIST_ENTRY {

  struct _EFI_LIST_ENTRY  *Flink;

  struct _EFI_LIST_ENTRY  *Blink;

} EFI_LIST_ENTRY;

主要的差别在新的List结构中成员变量没有数据项 只有前驱和后继指针,这样一来这个链表就和特定的数据类型无关,也就是说可以用这个链表穿起任何类型的数据(包括自定义类型),EDK code中有类似定义的数据结构,其中Link作为该结构中的一个成员

typedef struct {

  UINTN                     Signature;

  EFI_LIST_ENTRY            Link;

  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  CHAR16                    *OptionName;

  UINTN                     OptionNumber;

  UINT16                    BootCurrent;

  UINT32                    Attribute;

  CHAR16                    *Description;

  VOID                      *LoadOptions;

  UINT32                    LoadOptionsSize;

} BDS_COMMON_OPTION;

这样的结构串成链表以后就会如下图所示,当我们需要从链表中取出完整的结构时也只需要CR一下(你懂的,小学数学加减法)

 

  Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);

List比较常见的操作有插入、删除、交换等基本操作,这些操作也都非常简单,基本上就是连连看,比如在当前节点头部插入一个节点通常需要做的就是 该节点的前驱指向 头结点的前驱,头结点的前驱的后继指向该节点,该节点的后继指向头结点,头结点的前驱指向该节点(比较晕)。EFI中的list不是凭空发明出来的,linux中的list也是使用同样的定义方式,虽说只是比常规的list少了一个数据项,但是实质却是观念上的改变,它将数据与链表解耦了,使得所有的数据类型都都可以放在链表之中。

原创粉丝点击