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

  • 相关阅读:
    网页设计~老生常谈~浏览器兼容2个主要问题的解决
    谈谈网页功能测试
    从PMP学习中浅谈公司行政工作
    肉肉谈对需求设计的想法到底是功能驱动界面?还是界面驱动功能?
    jndi和rmi学习
    mysql赋值变量:=的使用
    用Cookies和HashTable制作购物车
    nginx实现简单的反向代理
    .net Form认证扩展保存 Object 类型
    基于Docker搭建私有镜像仓库
  • 原文地址:https://www.cnblogs.com/idyllcheung/p/11652014.html
Copyright © 2011-2022 走看看