kernel的console_init和printk

linux kernel在start_kernel里面调用console_init执行控制台的初始化。使用printk执行打印。

但是在console_init之前有一部分printk。需要在console_init之后才能打印出来,也就是说之前prinkt的数据都保存在了一个缓冲区内,等到console_init以后才打印出来。


console_init的执行流程在/drivers/tty的tty_io.c里面

void __init console_init(void)
{
	initcall_t *call;

	/* Setup the default TTY line discipline. */
	tty_ldisc_begin();

	/*
	 * set up the console device so that later boot sequences can
	 * inform about problems etc..
	 */
	call = __con_initcall_start;
	while (call < __con_initcall_end) {
		(*call)();
		call++;
	}
}

tty_ldisc_begin()暂时先不看。直接看后面注册函数的调用。

也就是从 __con_initcall_start到__con_initcall_end的函数都会被调用执行。

在linux/init.h里面有

#define console_initcall(fn) \
	static initcall_t __initcall_##fn \
	__used __section(.con_initcall.init) = fn

通过 console_initcall(fn)定义的fn函数都会被放到.con_initcall.init段里面。这个段的开始是__con_initcall_start,结束是__con_initcall_end

我的树莓派里面定义了一个函数在drivers\tty\serial\8250\8250_core.c里面

console_initcall(univ8250_console_init);

所以console_init就会调用univ8250_console_init。

static int __init univ8250_console_init(void)
{
	serial8250_isa_init_ports();
	register_console(&univ8250_console);
	return 0;
}
console_initcall(univ8250_console_init);
univ8250_console_init首先初始化了ports然后调用register_console注册了这个univ8250_console设备

在kernel/printk/printk.c中有register_console函数


register_console 将这个设备注册到console_drivers里面。后面printk->vprintk_emit->console_unlock->call_console_drivers->con->write(con, text, len);实现了输出

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值