| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> uboot的打印框架printf -> 正文阅读 |
|
[数据结构与算法]uboot的打印框架printf |
uboot打印框架前言本文主要探索uboot下的打印是怎么走的,是如何调用到串口驱动的。以及探索下在uboot下的打印框架。本文中的uboot 要点uboot启动大致流程uboot 启动从汇编文件开始到C语言环境执行init_sequence_f和init_sequence_r,
arch\arm\lib\crt0.S
common\board_f.c
common\board_r.c
arch\arm\cpu\armv7\start.S: bl _main
ENTRY(_main)
一堆的汇编bl指令跳转
board_init_f_alloc_reserve
...
board_init_f
initcall_run_list(init_sequence_f)
arch_cpu_init
...
timer_init
serial_init
console_init_f
relocate_code
...
board_init_r
initcall_run_list(init_sequence_r)
...
initr_serial
initr_flash
...
打印我们知道一个设备对外输出的是串口,所以最终的输出硬件介质是串口,必然和串口驱动有关, 剖析串口打印printf我们在uboot下用的都是printf,看其实现,利用va 解析可变参数并格式化通过puts输出字符串。
putsputs --》common\console.c
stdiodev代码路径\common\stdio.c
stdio 设备的插入添加既然printf是由stdio_devices的puts接口发送出去的那必然有stdio_devices初始化的地方
线索一
stdio设备的一些接口拿到上面的线索后不着急看console_setfile谁调用了,按照这种内核或者uboot开发者的风格,抽象出stdio设备层,通过stdio设备的接口函数去调用,面向对象思想,封装性比较强,内聚比较高, stdiodev初始化一般模块都有初始化在本文件中搜索init
初始化链表
stdio_init
stdio_init_tables(void)
stdio_add_devices(void)
INIT_LIST_HEAD(&(devs.list));
drv_system_init ();
serial_stdio_init ();
list操作static struct stdio_dev devs;
线索二
stdio_register仍然搜索注册的地方 根据编译文件分析
由线索一得知打印最终由stdio的puts输出所以这两个函数要注意下。
线索三
线索梳理通过线索一得知标准输入输出设备stdio在console_setfile中被设置,而console_setfile被console_init_r所调用. 继续接上线索一进行分析console_init_r函数如下
从中能看到一些线索二的影子。
根据 线索三serial的stdio设备在链表中比较靠前所以最终标准输出指向drv_system_init 注册的stdio设备 再次梳理整理已知的线索
分析名为"serial"stdio设备
get_current()
等效于
stdio_serial_puts()
serial_puts
get_current()->puts(s);
serial_current
serial_current->puts()
由上面信息可以得到终极线索
serial_devices\drivers\serial\serial.c
serial_pl01x驱动
确定调用关系
serial_initiali这个函数也是一堆的初始化,有其他各个平台的初始化,按照顺序注册serial设备 注意这个函数serial_assign,看代码也能看明白
那么这里产生第5个线索五
终极大法
图如下
arch\arm\lib\crt0.S
common\board_f.c
common\board_r.c
common\board_r.c
drivers\serial\serial.c
drivers\serial\serial.c
drivers\serial\serial.c
common\board_r.c
common\stdio.c
common\stdio.c
common\stdio.c
common\stdio.c
arch\arm\cpu\armv7\start.S: bl _main
ENTRY(_main)
一堆的汇编bl指令跳转
init_sequence_f
init_sequence_r
initr_serial
serial_initialize
pl01x_serial_initialize
注册pl01串口设备
serial_assign(default_serial_console()->name)
设置serial_current为pl01X设备
stdio_add_devices
drv_system_init ();
serial_stdio_init ();
stdio_register (&dev)
注册名字为serial的stdio设备
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 17:48:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |