浅析linux printk的实现


printk函数是我们调试linux内核必备的打印接口,

printk定义在/kernel/路径下

声明在/linux/kernel.h中,如果在某个文件中使用printk时编译通不过,通常都是未包含这个头文件(当然还有语法错误,呵呵~)



/**
 * printk - print a kernel message
 * @fmt: format string
 *
 * This is printk().  It can be called from any context.  We want it to work.
 *
 * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
 * call the console drivers.  If we fail to get the semaphore we place the output
 * into the log buffer and return.  The current holder of the console_sem will
 * notice the new output in release_console_sem() and will send it to the
 * consoles before releasing the semaphore.
 *
 * One effect of this deferred printing is that code which calls printk() and
 * then changes console_loglevel may break. This is because console_loglevel
 * is inspected when the actual printing occurs.
 *
 * See also:
 * printf(3)
 *
 * See the vsnprintf() documentation for format string extensions over C99.
 */


asmlinkageint printk(const char *fmt, ...)
{
    va_list args;
    int r;

    va_start(args, fmt);
    r = vprintk(fmt, args);
    va_end(args);

    return r;
}

/*

1.asmlinkage: 是GCC的c语言扩展语法,函数定义前加宏asmlinkage ,表示这些函数通过堆栈而不是通过寄存器传递参数。

2.printk是支持可变参数的,我们都知道一般情况下形参存储在动态数据区的栈区,但是const修饰的会存储在静态数据区,

不管形参在什么地方存储,有一点是不变的就是形参的存储是连续的;

其实不只是printk,只要支持可变参数,它们都有一个共同点:就是第一参数必须给定,根据第一个参数的地址,

就可以找后续的参数,以及参数的个数,以为它们是有逗号分隔的(这个就是实现可变参数的原理)

*/



asmlinkage int vprintk(const char *fmt, va_list args)
{
    int printed_len = 0;
    int current_log_level = default_message_loglevel;
    unsigned long flags;
    int this_cpu;
    char *p;

    boot_delay_msec();
    printk_delay();

    preempt_disable();                                                                          //禁止抢占
    /* This stops the holder of console_sem just where we want him */
    raw_local_irq_save(flags);                                                            //保存本地为处理的中断,这点我不是特别确认,只是根据字面意思理解的
    this_cpu = smp_processor_id();//获得CPU id

    /*
     * Ouch, printk recursed into itself!
     */

    if (unlikely(printk_cpu == this_cpu)) {
        /*
         * If a crash is occurring during printk() on this CPU,
         * then try to get the crash message out but make sure
         * we can't deadlock. Otherwise just return to avoid the
         * recursion and return - but flag the recursion so that
         * it can be printed at the next appropriate moment:
         */

        if (!oops_in_progress) {
            recursion_bug = 1;
            goto out_restore_irqs;
        }
        zap_locks();</

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值