首页 > 其他 > 详细

u-boot log_init函数分析

时间:2019-10-11 10:26:44      阅读:200      评论:0      收藏:0      [点我收藏+]

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\n", __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

u-boot log_init函数分析

原文:https://www.cnblogs.com/idyllcheung/p/11652014.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!