|
||||
|
Замена для printkВ начале (глава1), я сказал, что X и программирование модулей ядра не совместимы. Это истинно при разработке модуля, но в фактическом использовании, Вы должны быть способны послать сообщениям любому tty[10]. Это важно для идентификации ошибок после того, как модуль выпущен, потому что он будет использоваться через любой из терминалов. Путем этого достичь: используя текущий указатель на задачу, выполняемую в настоящее время, получить ее структуру 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 <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */ /* Deal with CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif /* Necessary here */ #include <linux/sched.h> /* For current */ #include <linux/tty.h> /* 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"); } Примечания:1 Причина, по которой я предпочитаю не компилировать как root в том, что так наиболее безопасно. Я работаю в службе компьютерной безопасности, так что я параноидален. 10 Teletype, первоначально комбинация принтера с клавиатурой, используемая, для связи с Unix системой, и сегодня абстракция для текстового потока, используемого для программы Unix, независимо от того, является ли это физическим терминалом, xterm на дисплее X, сетевое подключение, используемое telnet и т.д. |
|
||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх | ||||
|