пїЅ пїЅпїЅпїЅпїЅпїЅпїЅ (пїЅпїЅпїЅпїЅпїЅ1), пїЅ пїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅ X пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ. пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ tty. пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ, пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ.

пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ: пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ tty. пїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ tty, пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ, пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ tty. пїЅпїЅ пїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ.

printk.c

/* printk.c - send textual output to the tty you're

* running on, regardless of whether it's passed

* through X11, telnet, etc.

*/

/* Copyright (C) 1998 by Ori Pomerantz */

/* The necessary header files */

/* Standard in kernel modules */

#include /* We're doing kernel work */

#include /* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include

#endif

/* Necessary here */

#include /* For current */

#include /* For the tty declarations */

/* Print the string to the appropriate tty, the one

* the current task uses */

void print_string(char *str) {

пїЅstruct tty_struct *my_tty;

пїЅ/* The tty for the current task */

пїЅmy_tty = current->tty;

пїЅ/* If my_tty is NULL, it means that the current task

пїЅ* has no tty you can print to (this is possible, for

пїЅ* example, if it's a daemon). In this case, there's

пїЅ* nothing we can do. */

пїЅif (my_tty != NULL) {

пїЅпїЅ/* my_tty->driver is a struct which holds the tty's

пїЅпїЅ* functions, one of which (write) is used to

пїЅпїЅ* write strings to the tty. It can be used to take

пїЅпїЅ* a string either from the user's memory segment

пїЅпїЅ* or the kernel's memory segment.

пїЅпїЅ*

пїЅпїЅ* The function's first parameter is the tty to

пїЅпїЅ* write to, because the same function would

пїЅпїЅ* normally be used for all tty's of a certain type.

пїЅпїЅ* The second parameter controls whether the

пїЅпїЅ* function receives a string from kernel memory

пїЅпїЅ* (false, 0) or from user memory (true, non zero).

пїЅпїЅ* The third parameter is a pointer to a string,

пїЅпїЅ* and the fourth parameter is the length of

пїЅпїЅ* the string. */

пїЅпїЅ(*(my_tty->driver).write)(

пїЅпїЅ my_tty, /* The tty itself */

пїЅ пїЅ0, /* We don't take the string from user space */

пїЅ пїЅstr, /* String */

пїЅ пїЅstrlen(str)); /* Length */

пїЅ /* ttys were originally hardware devices, which

пїЅ * (usually) adhered strictly to the ASCII standard.

пїЅпїЅ* According to ASCII, to move to a new line you

пїЅпїЅ* need two characters, a carriage return and a

пїЅпїЅ* line feed. In Unix, on the other hand, the

пїЅпїЅ* ASCII line feed is used for both purposes - so

пїЅпїЅ* we can't just use \n, because it wouldn't have

пїЅпїЅ* a carriage return and the next line will

пїЅпїЅ* start at the column right after the line feed.

пїЅпїЅ*

пїЅпїЅ* BTW, this is the reason why the text file

пїЅпїЅ* is different between Unix and Windows.

пїЅпїЅ* In CP/M and its derivatives, such as MS-DOS and

пїЅпїЅ* Windows, the ASCII standard was strictly

пїЅпїЅ* adhered to, and therefore a new line requires

пїЅпїЅ* both a line feed and a carriage return. */

пїЅпїЅ(*(my_tty->driver).write)(my_tty, 0, "\015\012", 2);

пїЅ}

}

/* Module initialization and cleanup ****************** */

/* Initialize the module - register the proc file */

int init_module() {

пїЅprint_string("Module Inserted");

пїЅreturn 0;

}

/* Cleanup - unregister our file from /proc */

пїЅvoid cleanup_module() {

пїЅprint_string("Module Removed");

}