⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printk.c

📁 带中文注释的Linux+0.11+源代码
💻 C
字号:
/** 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.*//** 当处于内核模式时,我们不能使用printf,因为寄存器fs 指向其它不感兴趣的地方。* 自己编制一个printf 并在使用前保存fs,一切就解决了。*/#include <stdarg.h>		// 标准参数头文件。以宏的形式定义变量参数列表。主要说明了-个// 类型(va_list)和三个宏(va_start, va_arg 和va_end),用于// vsprintf、vprintf、vfprintf 函数。#include <stddef.h>		// 标准定义头文件。定义了NULL, offsetof(TYPE, MEMBER)。#include <linux/kernel.h>	// 内核头文件。含有一些内核常用函数的原形定义。static char buf[1024];// 下面该函数vsprintf()在linux/kernel/vsprintf.c 中92 行开始。extern int vsprintf (char *buf, const char *fmt, va_list args);// 内核使用的显示函数。intprintk (const char *fmt, ...){  va_list args;			// va_list 实际上是一个字符指针类型。  int i;  va_start (args, fmt);		// 参数处理开始函数。在(include/stdarg.h,13)  i = vsprintf (buf, fmt, args);	// 使用格式串fmt 将参数列表args 输出到buf 中。// 返回值i 等于输出字符串的长度。  va_end (args);		// 参数处理结束函数。  __asm__ ("push %%fs\n\t"	// 保存fs。	   "push %%ds\n\t" "pop %%fs\n\t"	// 令fs = ds。	   "pushl %0\n\t"	// 将字符串长度压入堆栈(这三个入栈是调用参数)。	   "pushl $_buf\n\t"	// 将buf 的地址压入堆栈。	   "pushl $0\n\t"	// 将数值0 压入堆栈。是通道号channel。	   "call _tty_write\n\t"	// 调用tty_write 函数。(kernel/chr_drv/tty_io.c,290)。	   "addl $8,%%esp\n\t"	// 跳过(丢弃)两个入栈参数(buf,channel)。	   "popl %0\n\t"	// 弹出字符串长度值,作为返回值。	   "pop %%fs"		// 恢复原fs 寄存器。::"r" (i):"ax", "cx", "dx");	// 通知编译器,寄存器ax,cx,dx 值可能已经改变。  return i;			// 返回字符串长度。}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -