linux printk()的实现

原文链接http://blog.chinaunix.net/uid-26791607-id-3346231.html

printk()的实现
start_kernel(void)
{lock_kernel();
 printk(linux_banner);
.....
console_init();
}

上面的代码显示在调用console_init之前,已经使用了printk函数。那么printk函数到底是如何在console上实现呢?可否更改printk函数,重定向输出?本文给出答案。

printk在src/kernel/Printk.c中实现:
 int printk(const char *fmt, ...)
在该函数内申请了一块静态内存static char printk_buf[1024];作为输出缓冲区。也就是说,不管console是否存在,printk都可以成功返回。
if (!down_trylock(&console_sem)) {
  /*
   * We own the drivers.  We can drop the spinlock and let
   * release_console_sem() print the text
   */
  spin_unlock_irqrestore(&logbuf_lock, flags);
  console_may_schedule = 0;
  release_console_sem();
printk函数,时时刻刻希望得到当前系统的console,因此只要系统调用了console init函数,printk就可以觉察到。在下次调用printk时,printk会把printk_buf中存储的数据输出到console中。这个过程在release_console_sem();实现:
for ( ; ; ) {
  spin_lock_irqsave(&logbuf_lock, flags);
  must_wake_klogd |= log_start - log_end;
  if (con_start == log_end)
   break;   /* Nothing to print */
  _con_start = con_start;
  _log_end = log_end;
  con_start = log_end;  /* Flush */
  spin_unlock_irqrestore(&logbuf_lock, flags);
  call_console_drivers(_con_start, _log_end);
 }
通过调用call_console_drivers,printk输出数据到console!
call_console_drivers再次调用函数:
_call_console_drivers(start_print, cur_index, msg_level);
再次调用更为底层的__call_console_drivers()实现。
正是在__call_console_drivers()中完成了对console驱动中write的调用!
for (con = console_drivers; con; con = con->next) {
  if ((con->flags & CON_ENABLED) && con->write)
   con->write(con, &LOG_BUF(start), end - start);
 }

因此,在系统没有调用console_init();之前,printk并没有真正把数据发送到console。更改printk,可以很方便的输出到任何需要的设备上。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值