Linux之prink原理
我的分析是基于Linux4.15.1
1.看看kernel是如何调用到console初始化函数的:
分两条线:
a.start_kernel --> console_init --> call = __con_initcall_start
去调用放在__con_initcall_start和__con_initcall_end之间的所有函数,看看这个区间的有哪些函数.
__con_initcall_start = .;
*(.con_initcall.init)
__con_initcall_end = .;
b.start_kernel --> rest_init --> kernel_init --> kernel_init_freeable --> do_basic_setup --> do_initcalls .
do_initcalls()将按顺序从由__initcall_start开始,到__initcall_end结束的section中以函数指针的形式取出这些编译到内核的驱动模块中初始化函数起始地址,来依次完成相应的初始化.
2.看看跟单板芯片相关的函数是如何放到__initcall这个section的。
在drivers/tty/serial/samsung.c里面有如下定义:console_initcall(s3c24xx_serial_console_init);,去include/linux/init.h里面查看console_initcall的定义:
#define console_initcall(fn) \
static initcall_t __initcall_##fn \
__used __section(.con_initcall.init) = fn
因此在执行console_init的时候,s3c24xx_serial_console_init也会被调用,进而执行register_console(&s3c24xx_serial_console);,结构体s3c24xx_serial_console的定义如下,
static struct console s3c24xx_serial_console = {
.name = S3C24XX_SERIAL_NAME,
.device = uart_console_device,
.flags = CON_PRINTBUFFER,
.index = -,
.write = s3c24xx_serial_console_write,
.setup = s3c24xx_serial_console_setup,
.data = &s3c24xx_uart_drv,
};
相当于将此结构体注册进内核,注意这里的名称:#define S3C24XX_SERIAL_NAME "ttySAC",是不是很眼熟,没错,这个就是我们在bootargs里面设置的console的名称。
这里也有一个write函数,就是通过这个函数将打印信息送到串口上的。
在register_console的时候,还会调用每个console的setup函数,对应于s3c2440的话,就是s3c24xx_serial_console_setup函数了。
if (!has_preferred) {
if (newcon->index < )
newcon->index = ;
if (newcon->setup == NULL ||
newcon->setup(newcon, NULL) == 0) {
newcon->flags |= CON_ENABLED;
if (newcon->device) {
newcon->flags |= CON_CONSDEV;
has_preferred = true;
}
}
}
console就这样注册进内核了,如果细看注册过程,其实是将此console的信息记录到static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];这个数组里面了,也由此可知内核最多允许8个console。
3.再看看我们传进去的console是如何跟上面注册的相关联起来的。
上面的代码是内核自动会运行的,所以可以看出,内核在初始化的时候注册了一个名为ttySAC*的console,里面还有write的函数直接操作串口,一般这个console就是ttySAC0了,这就是为什么我们在uboot里面传参数的时候console=ttySAC0的原因,就是为了跟内核里面注册的console名称匹配,每一款芯片可能这个名字都不一样,要自己看源码。
接下来就看我们传进去的console=ttySAC0是如何跟内核自动注册的console关联起来的。
在内核里面搜索"console="看看哪里解析了我们传进来的参数:
可以搜到在kernel/printk/printk.c里面有如下定义:
__setup("console=", console_setup);
当uboot通过"console="传入参数时,内核里面是用__setup宏申明的方法来处理的,前提是要名称匹配,也就是说,内核是通过调用console_setup来处理uboot传入的“console=”这个命令行的,也就是在console_cmdline[MAX_CMDLINECONSOLES]这个数组里面查看是否有相同的名称的console:
for (i = , c = console_cmdline;
i < MAX_CMDLINECONSOLES && c->name[];
i++, c++) {
if (strcmp(c->name, name) == && c->index == idx) {
if (!brl_options)
preferred_console = i;
return ;
}
}
如果找到名称匹配的,则将其记录在preferred_console这个变量里,关于console_setup这个函数的分析,网上很多,我这里就不细讲了。
这样用户指定的console就用起来了。
梳理一遍:
用户指定console --> 在内核注册的console里面有这个设备 --> 于是通过名字建立了关系。
Linux之prink原理的更多相关文章
- [转载]Linux Bond的原理及其不足
本文转自http://www.yunweipai.com/archives/1969.html 支持原创.尊重原创,分享知识! 在企业及电信Linux服务器环境上,网络配置都会使用Bonding技术做 ...
- Linux Bond的原理及其不足
http://www.tektea.com/archives/1969.html. 在企业及电信Linux服务器环境上,网络配置都会使用Bonding技术做网口硬件层面的冗余,防止单个网口应用的单点故 ...
- linux下的X server:linux图形界面原理
linux下的X server:linux图形界面原理 Moblin Core是在Gnome Mobile的平台上建立.我以前玩Linux,提交的都和图像没有关系,连Xwindows都不用启动,开 ...
- Linux Kbuild工作原理分析(以DVSDK生成PowerVR显卡内核模块为例)
一.引文 前篇博文<Makefile之Linux内核模块的Makefile写法分析>,介绍了Linux编译生成内核驱动模块的Makefile的写法,但最近在DVSDK下使用Linux2.6 ...
- [转帖]linux下的X server:linux图形界面原理
linux下的X server:linux图形界面原理 https://www.cnblogs.com/liangxiaofeng/p/5034912.html linux下的X server:lin ...
- Linux 文件删除原理_009
***了解Linux文件删除原理先了解一下文件inode索引节点,每个文件在Linux系统里都有唯一的索引节点(身份证号) inode.如果文件存在硬链接,那这个文件和这个文件的硬链接的inode是相 ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
- 转 Linux内存管理原理
Linux内存管理原理 在用户态,内核态逻辑地址专指下文说的线性偏移前的地址Linux内核虚拟3.伙伴算法和slab分配器 16个页面RAM因为最大连续内存大小为16个页面 页面最多16个页面,所以1 ...
- ARM Linux系统调用的原理
转载自:http://blog.csdn.net/hongjiujing/article/details/6831192 ARM Linux系统调用的原理 操作系统为在用户态运行的进程与硬件设备进行交 ...
随机推荐
- 网络请求get和post的区别
网络请求get和post的区别 其实本文更应该放在HTTP相关的分类,但是目前我并没有开设这一个分类专栏,so临时储存在HTML分类吧 Get和post是HTTP请求的两种基本方式 get是从服务器上 ...
- mybatis源码解析之Configuration加载(二)
概述 上一篇我们讲了configuation.xml中几个标签的解析,例如<properties>,<typeAlises>,<settings>等,今天我们来介绍 ...
- leetcode python 041首个缺失正数
##限定时间复杂度O(n)num=[0,5,3,1,2,-2,4,8,5,6]num=set(num)d=1for i in range(1,len(num)+1): if d in num: ...
- Linux集群架构(一)
第二十八课 Linux集群架构(一) 目录 一. 集群介绍 二. keepalived介绍 三. 用keepalived配置高可用集群 四. 负载均衡集群介绍 五. LVS介绍 六. LVS调度算法 ...
- Python 习题一
1.使用while循环输入 1 2 3 4 5 6 8 9 10 # Author:Tony.lou i = 1 while i < 11: if i == 7: pass else: prin ...
- 使用Xshell配置外网访问端口
- 第四次Scrum编码冲刺
第四次Scrum编码冲刺!!!! 一.总体任务: 本次冲刺是完成对图书馆管理系统的最后三个功能的实现------管理员对用户授权.用户注销和用户查询 二.个人任务及完成情况: 本人本次的任务是实 ...
- 大数据处理N!(21<N<2000)
输入: 每行输入1个正整数n,(0<n<1000 000) 输出: 对于每个n,输出n!的(十进制)位数 digit, 和最高位数firstNum.(n!约等于 firstNum * 10 ...
- win7安装python3.6.1及scrapy
---恢复内容开始--- 第一篇博客,记录自己自学python的过程及问题. 首先下载python3.6.1及所需资料 百度云:https://pan.baidu.com/s/1geOEp6z 密码: ...
- 树莓派安装tensorflow1.11
树莓派3B+ 环境:2018-11-13-raspbian-stretch 初始状态 首先将本地更新一下和安装 sudo apt-get update sudo apt-get upgrade 然后更 ...