【Linux102】10-kernel/printk.c


公粽号「专注Linux」,专注Linux内核开发

Linux102系列会详细讲解Linux0.11版本中的102个文件,本文讲解linux0.11的第10个文件kernel/printk.c的文件源码。

1.printk的主要作用

一句话:就是内核态的printf。

其中,printk会使用到的函数:

vsprintf移步:☺【Linux102】11-kernel/vsprintf.c
stdarg.h头文件移步:☺【Linux102】12-include/stdarg.h

3.源码注释版本

/*
 *  linux/kernel/printk.c
 *
 *  (C) 1991  Linus Torvalds
 */

/*
 * When in kernel-mode, we cannot use printf, as fs is liable to
 * point to 'interesting' things. Make a printf with fs-saving, and
 * all is well.
 */
#include <stdarg.h>
#include <stddef.h>

#include <linux/kernel.h>

static char buf[1024];

/**
 * @brief 格式化字符串函数,并且返回格式化后的字符串长度
 *
 * @param buf 输出缓冲区
 * @param fmt 格式化字符串
 * @param args 可变参数列表
 * @return int 输出字符串的长度
 */

extern int vsprintf(char *buf, const char *fmt, va_list args);

/**
 * @brief 打印内核消息函数
 *
 * @param fmt 格式化字符串
 * @return int 输出字符串的长度
 * 注意:printk负责格式化,tty_write负责硬件相关的实际写入,职责分离使代码更易维护。
 */
int printk(const char *fmt, ...)
{
    va_list args; /*可变参数列表指针*/
    int i;
    /*初始化可变参数列表指针*/
    va_start(args, fmt);
    /*格式化字符串长度*/
    i = vsprintf(buf, fmt, args);
    /*结束可变参数列表指针*/
    va_end(args);
    /*使用 GCC 内联汇编直接操作硬件和调用内核函数tty_write输出内容*/
    __asm__("push %%fs\n\t"      /*保存fs寄存器*/
            "push %%ds\n\t"      /*保存ds寄存器*/
            "pop %%fs\n\t"       /*恢复fs寄存器*/
            "pushl %0\n\t"       /*压入字符串长度i作为参数*/
            "pushl $buf\n\t"     /*压入缓冲区地址作为参数*/
            "pushl $0\n\t"       /*压入文件描述符0(通常代表控制台)*/
            "call tty_write\n\t" /*调用tty_write函数*/
            "addl $8,%%esp\n\t"  /*清理栈上的两个参数,返回值依旧保留的*/
            "popl %0\n\t"        /*恢复i的值*/
            "pop %%fs\n\t"       /*恢复fs寄存器*/
            : /*没有实际的输出寄存器*/
            : "r"(i) /*输入:将i放入寄存器.注意这里没有输出*/
            : "ax", "cx", "dx");/*告知编译器这些寄存器(ax cs dx)会被修改*/
    return i;
}

4.源码源版本

/*
 *  linux/kernel/printk.c
 *
 *  (C) 1991  Linus Torvalds
 */

/*
 * When in kernel-mode, we cannot use printf, as fs is liable to
 * point to 'interesting' things. Make a printf with fs-saving, and
 * all is well.
 */
#include <stdarg.h>
#include <stddef.h>

#include <linux/kernel.h>

static char buf[1024];

extern int vsprintf(char *buf, const char *fmt, va_list args);

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

    va_start(args, fmt);
    i = vsprintf(buf, fmt, args);
    va_end(args);
    __asm__("push %%fs\n\t"
            "push %%ds\n\t"
            "pop %%fs\n\t"
            "pushl %0\n\t"
            "pushl $buf\n\t"
            "pushl $0\n\t"
            "call tty_write\n\t"
            "addl $8,%%esp\n\t"
            "popl %0\n\t"
            "pop %%fs" ::"r"(i) : "ax", "cx", "dx");
    return i;
}  

5.源码图像版本

kernel/printk.c源码


kernel/printk.c源码注释版本



汇编语言

😉【汇编语言】1—基础硬件知识

😉【汇编语言】2—寄存器基础知识

😉【汇编语言】3-寄存器与内存的交互

😉【汇编语言】4-第一个完整的汇编程序

😉【汇编语言】5-[BX]和loop指令

😉【汇编语言】6-包含多个段的程序

😉【汇编语言】7-灵活的5大寻址方式

😉【汇编语言】8-1-数据的位置

😉【汇编语言】8-2-数据的长度

😉【汇编语言】8-数据处理的两个基本问题(位置与长度)

😉【DOSBox】1-debug

😉【DOSBox】2-debug可执行文件

😉【DOSBox】3-完整开发流程


C语言

😉【C语言】C Token(C89 C99 C11)

😉【C语言】指针基础

😉【C语言】数组基础

😉【C语言】结构体对齐

😉【C语言】华为C语言进阶测试

😉【C语言】触发刷新到磁盘的方式总结

😉【C语言】C语言文件操作的mode详解

😉【C语言】C语言文件知识全讲解

😉【C语言】从extern到头文件包含的最优实践

😉【C语言】C语言的关键字与重载机制

😉【C语言】长字符串的2种处理方式

😉【C语言】C语言嵌入汇编程序

😉【C陷阱与缺陷】-1-词法陷阱

😉【C陷阱与缺陷】-2-语法陷阱

😉【C陷阱与缺陷】-3-语义陷阱


Linux101系列

专注讲解Linux中的常用命令,共计发布100+文章。

😉【Linux101-1】ls

😉【Linux101-1】ls -l命令输出结果全解析

😉【Linux101-2】cd

😉【Linux101-3】cat

😉【Linux101-4】tac

😉【Linux101-5】head

😉【Linux101-6】tail

😉【Linux101-7】pwd

😉【Linux101-8】touch

😉【Linux101-9】cal

😉【Linux101-10】bc

😉【Linux101-11】df

😉【Linux101-12】uname

😉【Linux101-13】mkdir

😉【Linux101-14】gzip

😉【Linux101-15】tar

😉【Linux101-16】lsof

😉【Linux101-17】du

😉【Linux101-18】stat


Linux102系列

本系列将精讲Linux0.11内核中的每一个文件,共计会发布100+文章。

😉【Linux102】1-Makefile

😉【Linux102】2-Makefile.header

😉【Linux102】3-system.map

😉【Linux102】4-bootsect.s

😉【Linux102】5-setup.s

😉【Linux102】6-head.s

😉【Linux102-D】/boot

😉【Linux102】7-main.c

😉【Linux102】8-kernel/asm.s

😉【Linux102】11-kernel/vsprintf.c

😉【Linux102】12-include/stdarg.h


Linux内核精讲系列

和Linux内核102系列不同,本系列将会从全局描绘Linux内核的各个模块,而非逐行源码分析,适合想对Linux系统有宏观了解的家人阅读。

😉【Linux】学习Linux前必备的知识点

😉【Linux】Linux内核对进程的内存抽象

😉【Linux】Linux概述1-linux对物理内存的使用

😉【Linux】软件从写下到运行的全部流程

😉【Linux】CPU的三寻址:实模式、保护模式、长模式

😉【Linux】实模式与保护模式的寻址, 这次讲明白了!

😉【Linux】linux0.11的源码目录架构

😉【Linux】Makefile机制及基础详解

😉【Linux】编译并运行Linux0.11

😉【Linux】“进进内网文”—Linux的内核结构全貌

😉【Linux】linux的中断机制

😉【Linux】linux进程描述



关于小希

😉嘿嘿嘿,我是小希,专注Linux内核领域,同时讲解C语言汇编等知识。

我的微信:C_Linux_Cloud,期待与您学习交流!

加微信请备注哦


小希的座右铭:别看简单,简单也是难。别看难,难也是简单。我的文章都是讲述简单的知识,如果你喜欢这种风格:

不妨关注、评论、转发,让更多朋友看到哦~~~🙈

下一期想看什么?在评论区留言吧!我们下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值