?? printk.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 + -