zoukankan      html  css  js  c++  java
  • u-boot log_init函数分析

    log_init,

    int log_init(void)
    {
        struct log_driver *drv = ll_entry_start(struct log_driver, log_driver);

        #define ll_entry_start(_type, _list)                   
        ({                                   
                 static char start[0] __aligned(4) __attribute__((unused, section(".u_boot_list_2_"#_list"_1")));           
                  (_type *)&start;                       
         })

         //等价于:

        //struct log_driver *drv = {static char start[0];(struct log_driver*)&start;},其中start[0]放置在.u_boot_list_2_log_driver_1段

        /*.u_boot_list在u-boot.lds定义

        .u_boot_list : {
                     KEEP(*(SORT(.u_boot_list*)));}

         并按照u_boot_list后面的字符进行排序*/


        const int count = ll_entry_count(struct log_driver, log_driver);

        #define ll_entry_count(_type, _list)                   
        ({                               
            _type *start = ll_entry_start(_type, _list);       
            _type *end = ll_entry_end(_type, _list);       
            unsigned int _ll_result = end - start;           
            _ll_result;                       
        })

        //等价于const int count=ll_entry_end(_type, _list)-ll_entry_start(_type, _list),即计算.u_boot_list_2_log_driver_3和.u_boot_list_2_log_driver_1之间有多少个struct log_driver结构体
        struct log_driver *end = drv + count;             //指向.u_boot_list_2_log_driver_3处
        INIT_LIST_HEAD((struct list_head *)&gd->log_head);

        static inline void INIT_LIST_HEAD(struct list_head *list)
        {
              list->next = list;
              list->prev = list;
         }

        //即将gd->log_head设置为循环链表的头
        while (drv < end) {
            struct log_device *ldev;

            ldev = calloc(1, sizeof(*ldev));              //给ldev分配空间
            if (!ldev) {
                debug("%s: Cannot allocate memory ", __func__);
                return -ENOMEM;
            }
            INIT_LIST_HEAD(&ldev->filter_head);     //将ldev->filter_head成员初始化为循环链表
            ldev->drv = drv;                                        //将ldev->drv成员指向当前的log_driver
            list_add_tail(&ldev->sibling_node,
                      (struct list_head *)&gd->log_head);    //把ldev->sibling_node成员加入到gd->log_head的循环链表中
            drv++;
        }

       //通过该循环,将.u_boot_list_2_log_driver_3和.u_boot_list_2_log_driver_1之间的所有struct log_driver结构体都加入到了gd->log_head的循环链表中
        gd->flags |= GD_FLG_LOG_READY;       

        //之前gd->flags=0,此时设置gd->flags为GD_FLG_LOG_READY,即gd->flags=0x08000
        if (!gd->default_log_level)
            gd->default_log_level = LOGL_INFO;        //设置gd->default_log_level为LOGL_INFO
        gd->log_fmt = LOGF_DEFAULT;                    //设置gd->log_fmt为LOGF_DEFAULT

        return 0;
    }

    log_init的主要功能是将.u_boot_list_2_log_driver_3和.u_boot_list_2_log_driver_1之间的所有struct log_driver结构体都加入到了gd->log_head的循环链表中,并初始化gd->default_log_level和gd->log_fmt
    ————————————————
    版权声明:本文为CSDN博主「yanggx0929」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/yanggx0929/article/details/88785318

  • 相关阅读:
    [ jquery 选择器 :hidden ] 此方法选取匹配所有不可见元素,或者type为hidden的元素
    剑指 Offer 03. 数组中重复的数字 哈希
    LeetCode 1736. 替换隐藏数字得到的最晚时间 贪心
    Leetcode 1552. 两球之间的磁力 二分
    Leetcode 88. 合并两个有序数组 双指针
    LeetCode 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
    LeetCode 1743. 相邻元素对还原数组 哈希
    LeetCode 1745. 回文串分割 IV dp
    剑指 Offer 47. 礼物的最大价值 dp
    剑指 Offer 33. 二叉搜索树的后序遍历序列 树的遍历
  • 原文地址:https://www.cnblogs.com/idyllcheung/p/11652014.html
Copyright © 2011-2022 走看看