edk2 中链表操作

        不论是哪个操作系统都会涉及链表的操作, Linux、 Qemu 、 VirtualBox 以及RTthread、 Ucos等 RTOS都有链表。链表的操作主要有: 初始化链表头、头部插入、尾部插入、遍历结点、任意节点交互等。 在阅读 edk2代码时,内核并不提供链表的遍历接口, 要想遍历则需要使用 for循环进行链表操作。

        edk2中链表操作和l inux内核的没有什么太大差异

        代码路径: // uefi\edk2\MdePkg\Library\BaseLib\LinkedList.c

1- 链表初始化

           

LIST_ENTRY *
EFIAPI
InitializeListHead (
  IN OUT  LIST_ENTRY  *ListHead
  )

{
  ASSERT (ListHead != NULL);

  ListHead->ForwardLink = ListHead;
  ListHead->BackLink    = ListHead;
  return ListHead;
}

        上述代码构建一个双向循环链表头

2- 尾部插入

LIST_ENTRY *
EFIAPI
InsertTailList (
  IN OUT  LIST_ENTRY  *ListHead,
  IN OUT  LIST_ENTRY  *Entry
  )
{
  //
  // ASSERT List not too long and Entry is not one of the nodes of List
  //
  ASSERT_VERIFY_NODE_IN_VALID_LIST (ListHead, Entry, FALSE);

  Entry->ForwardLink           = ListHead;
  Entry->BackLink              = ListHead->BackLink;
  Entry->BackLink->ForwardLink = Entry;
  ListHead->BackLink           = Entry;
  return ListHead;
}

如下图所示:

 

3- 头部插入

LIST_ENTRY *
EFIAPI
InsertHeadList (
  IN OUT  LIST_ENTRY  *ListHead,
  IN OUT  LIST_ENTRY  *Entry
  )
{
  //
  // ASSERT List not too long and Entry is not one of the nodes of List
  //
  ASSERT_VERIFY_NODE_IN_VALID_LIST (ListHead, Entry, FALSE);

  Entry->ForwardLink           = ListHead->ForwardLink;
  Entry->BackLink              = ListHead;
  Entry->ForwardLink->BackLink = Entry;
  ListHead->ForwardLink        = Entry;
  return ListHead;
}

如下图所示:

       

 

4- 其它链表操作

GetPreviousNode (LIST_ENTRY  *List, LIST_ENTRY  *Node)
GetNextNode     (LIST_ENTRY  *List, LIST_ENTRY  *Node)
InsertTailList (LIST_ENTRY  *ListHead, LIST_ENTRY  *Entry)
InsertHeadList (LIST_ENTRY  *ListHead, LIST_ENTRY  *Entry)

// 以下时 linux内核链表参数
void list_add(struct list_head *new, struct list_head *head)
void list_add_tail(struct list_head *new, struct list_head *head)

        Linux 内核链表操作代码是相当犀利,覆盖了各个场景,加锁的,hash及红黑树之类的。熟悉linux 内核中链表操作,再看其他代码,相对简单很多

5- 总结

        链表是构建复杂系统的基石,学习时要注意

  •  结合代码画图
  • edk2中链表操作和 linux内核参数是相反的
  • edk2中不提供遍历接口,需要手动 for 循环
  • edk2中使用 CR宏和 container_of一样的效果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tcutee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值