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\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函数分析的更多相关文章
- 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 精尽Spring Boot源码分析 - 配置加载
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- split(),preg_split()与explode()函数分析与介
split(),preg_split()与explode()函数分析与介 发布时间:2013-06-01 18:32:45 来源:尔玉毕业设计 评论:0 点击:965 split()函数可以实 ...
- string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- start_amboot()函数分析
一.整体流程 start_amboot()函数是执行完start.S汇编文件后第一个C语言函数,完成的功能自然还是初始化的工作 . 1.全局变量指针r8设定,以及全局变量区清零 2.执行一些类初始化函 ...
- uboot的jumptable_init函数分析
一.函数说明 函数功能:安装系统函数指针 函数位置:common/exports.c 二.函数分析 void jumptable_init (void) { int i; gd->jt = (v ...
- Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析
Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...
- 31.QPainter-rotate()函数分析-文字旋转不倾斜,图片旋转实现等待
在上章和上上上章: 28.QT-QPainter介绍 30.QT-渐变之QLinearGradient. QConicalGradient.QRadialGradient 学习了QPainter基础绘 ...
- Spring Boot 入门详细分析
推荐阅读: 我们为什么要学习 Spring Boot 我们搭建 Spring Boot 项目,可以使用 Spring 为我们提供的初始化网站,那个可能不太方便,今天呢,我们就来说说如何使用 IDEA ...
随机推荐
- IFB上挂载NETEM
转发虚拟网卡的ingress 建立虚拟网卡的ingress转发到ifb0(每一个Pod): tc qdisc add dev calixxxxxxxxxxx ingress tc filter add ...
- 创建策略(Creation Policy )和生命周期(Life Cycle)
前言 在前面的介绍中我们已经知道:导入和导出的匹配成功需要ContractType,ContractName,Metadata都匹配,这里我们还要介绍一个新的东西:创建策略(creation poli ...
- asp.net mvc 依赖注入Ninject
1.安装Ninject 2.使用Ninject 一 安装Ninject Nuget:Ninject 二 使用Ninject public interface IStudent { string Get ...
- 转·c语言函数指针的理解与使用
原文出处:https://www.cnblogs.com/haore147/p/3647262.html 1.函数指针的定义 顾名思义,函数指针就是函数的指针.它是一个指针,指向一个函数.看例子: 1 ...
- mongodb 数据库操作 -- 》常用命令
首先需要下载数据库,安装后,找到bin目录,点开bin目录,复制当前路径配置到环境变量中 和bin的同级下,需要建立一个data/db文件夹,该文件夹并不会自动生成,必须手动设置 启动数据库 看 ...
- Python新手练手项目
1.新手练手项目集中推荐 https://zhuanlan.zhihu.com/p/22164270 2.Python学习网站 https://www.shiyanlou.com 3.数据结构可视化学 ...
- 【中间件】Kafka 学习 01
KafKa 博客教程-1 博客教程-2 kafka简介 kafka起源 Kafka是由LinkedIn开发并开源的分布式消息系统,2012年捐赠给Apache基金会,采用Scala语言,运行在JVM中 ...
- 函数进阶装B操作
三元表达式 条件成立时的返回值 if 条件 else 条件不成立时的返回值 x = 10 y = 20 print(f"x if x > y else y: {x if x > ...
- [NodeJs系列]聊一聊BOM
最近在看Node源码的时候,偶然间,看到如下函数: /** * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * be ...
- 看电视剧<潜伏>有感
前几天看了老电视剧-潜伏,有一些感慨. 一,立场和真相都不重要,形式才是最重要的. 二.历史在不断的轮回中. 好汉历经千辛万苦杀掉了为害一方的恶霸,好汉的威望达到了顶峰,自然的成了村庄的守护者和掌控者 ...