?? printk.c
字號(hào):
/* passed* linux/kernel/printk.c** (C) 1991 Linus Torvalds*/#include <set_seg.h>
/** 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.*//** 當(dāng)處于內(nèi)核模式時(shí),我們不能使用printf,因?yàn)榧拇嫫鱢s 指向其它不感興趣的地方。* 自己編制一個(gè)printf 并在使用前保存fs,一切就解決了。*/#include <stdarg.h> // 標(biāo)準(zhǔn)參數(shù)頭文件。以宏的形式定義變量參數(shù)列表。主要說明了-個(gè)// 類型(va_list)和三個(gè)宏(va_start, va_arg 和va_end),用于// vsprintf、vprintf、vfprintf 函數(shù)。#include <stddef.h> // 標(biāo)準(zhǔn)定義頭文件。定義了NULL, offsetof(TYPE, MEMBER)。#include <linux/kernel.h> // 內(nèi)核頭文件。含有一些內(nèi)核常用函數(shù)的原形定義。static char buf[1024];// 下面該函數(shù)vsprintf()在linux/kernel/vsprintf.c 中92 行開始。extern int vsprintf (char *buf, const char *fmt, va_list args);// 內(nèi)核使用的顯示函數(shù)。int printk (const char *fmt, ...){ va_list args; // va_list 實(shí)際上是一個(gè)字符指針類型。 int i; va_start (args, fmt); // 參數(shù)處理開始函數(shù)。在(include/stdarg.h,13) i = vsprintf (buf, fmt, args); // 使用格式串fmt 將參數(shù)列表args 輸出到buf 中。// 返回值i 等于輸出字符串的長(zhǎng)度。 va_end (args); // 參數(shù)處理結(jié)束函數(shù)。
_asm{
push fs // 保存fs。
push ds
pop fs // 令fs = ds。
push i // 將字符串長(zhǎng)度壓入堆棧(這三個(gè)入棧是調(diào)用參數(shù))。
push offset buf // 將buf 的地址壓入堆棧。
push 0 // 將數(shù)值0 壓入堆棧。是通道號(hào)channel。
call tty_write // 調(diào)用tty_write 函數(shù)。(kernel/chr_drv/tty_io.c,290)。
add esp,8 // 跳過(丟棄)兩個(gè)入棧參數(shù)(buf,channel)。
pop i // 彈出字符串長(zhǎng)度值,作為返回值。
pop fs // 恢復(fù)原fs 寄存器。
} /* __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"); // 通知編譯器,寄存器ax,cx,dx 值可能已經(jīng)改變。*/ return i; // 返回字符串長(zhǎng)度。}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -