/*
* 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)
// vsprintfvprintfvfprintf 
#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);

// ںʹõʾ
int
printk (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;			// ַȡ
}
