百度空间 | 百度首页 
 
查看文章
 
printk()的实现
2007-04-09 23:29

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,可以很方便的输出到任何需要的设备上。


类别:Linux | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu