ΠΠ΅ΡΡΠΈΠΈ ΡΠ΄ΡΠ° Linux ΡΠ°Π·Π΄Π΅Π»Π΅Π½Ρ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΡΠΎΠΉΡΠΈΠ²ΡΠΌΠΈ Π²Π΅ΡΡΠΈΡΠΌΠΈ (n.<Π§Π΅ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ>.m) ΠΈ Π²Π΅ΡΡΠΈΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ (n.<ΠΠ΅ΡΠ΅ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ>.m). ΠΠ΅ΡΡΠΈΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ Π²ΠΊΠ»ΡΡΠ°ΡΡ Π²ΡΠ΅ Π½ΠΎΠ²ΡΠ΅ ΠΈΠ΄Π΅ΠΈ, Π²ΠΊΠ»ΡΡΠ°Ρ ΡΠ΅, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΡΡΠΈΡΠ°ΡΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ ΠΈΠ»ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Ρ Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ. Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄ΠΎΠ²Π΅ΡΡΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Π² ΡΠΎΠΌ ΠΏΠ»Π°Π½Π΅, ΡΡΠΎ ΠΎΠ½ ΠΎΡΡΠ°Π½Π΅ΡΡΡ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠ°ΠΌΡΠΌ Π² Π²Π΅ΡΡΠΈΡΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ. Π ΡΡΡΠΎΠΉΡΠΈΠ²ΡΡ Π²Π΅ΡΡΠΈΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΆΠΈΠ΄Π°ΡΡ, ΡΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΎΡΡΠ°Π½Π΅ΡΡΡ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠ°ΠΌΡΠΌ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ Π²Π΅ΡΡΠΈΠΈ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ (ΡΠΈΡΠ»ΠΎ m).
ΠΡΠ° Π²Π΅ΡΡΠΈΡ MPG Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ Π΄Π»Ρ Π²Π΅ΡΡΠΈΠΈ 2.0.x ΠΈ Π²Π΅ΡΡΠΈΠΈ ΡΠ΄ΡΠ° Linux. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌΠ΅ΡΡΡΡ ΡΠ°Π·Π»ΠΈΡΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΠΌΠΈ, ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΡΠ»ΠΎΠ²Π½Π°Ρ ΡΡΠ°Π½ΡΠ»ΡΡΠΈΡ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π²Π΅ΡΡΠΈΠΈ. Π‘ΠΏΠΎΡΠΎΠ± ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ ΡΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΊ ΡΠΎΠΌΡ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ°ΠΊΡΠΎΠΊΠΎΠΌΠ°Π½Π΄Ρ LINUX_VERSION_CODE. Π Π²Π΅ΡΡΠΈΠΈ a.b.c ΡΠ΄ΡΠ° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠΉ ΠΌΠ°ΠΊΡΠΎΠΊΠΎΠΌΠ°Π½Π΄Ρ Π±ΡΠ»ΠΎ Π±Ρ 216a+28b+c. Π§ΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ°ΠΊΡΠΎΠΊΠΎΠΌΠ°Π½Π΄Ρ KERNEL_VERSION. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎΡ ΠΌΠ°ΠΊΡΠΎΡ Π½Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ Π² 2.0.35, ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π΅Π³ΠΎ ΡΠ°ΠΌΠΈ Π² ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.
Π€Π°ΠΉΠ»ΠΎΠ²Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° /proc
Π Linux ΠΈΠΌΠ΅Π΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ Π΄Π»Ρ ΡΠ΄ΡΠ° ΠΈ ΡΠ΄Π΅ΡΠ½ΡΡ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ ΠΏΠΎΡΠ»Π°ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌ: ΡΠ°ΠΉΠ»ΠΎΠ²Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° /proc. ΠΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π½Π°Ρ Π΄Π»Ρ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ², ΠΎΠ½Π° ΡΠ΅ΠΏΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΌ ΠΊΡΡΠΎΡΠΊΠΎΠΌ ΡΠ΄ΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠΎ-Π»ΠΈΠ±ΠΎ ΡΠΎΠΎΠ±ΡΠΈΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, /proc/modules, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠΌΠ΅Π΅Ρ ΡΠΏΠΈΡΠΎΠΊ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ ΠΈ /proc/meminfo, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠΌΠ΅Π΅Ρ ΡΡΠ°ΡΠΈΡΡΠΈΠΊΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ.
ΠΠ΅ΡΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ /proc ΠΎΡΠ΅Π½Ρ ΠΏΠΎΡ ΠΎΠΆ Π½Π° ΡΠ°Π±ΠΎΡΡ Ρ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠ°ΠΌΠΈ ΡΡΡΡΠΎΠΉΡΡΠ²Π°: ΠΡ ΡΠΎΠ·Π΄Π°Π΅ΡΠ΅ ΡΡΡΡΠΊΡΡΡΡ ΡΠΎ Π²ΡΠ΅ΠΉ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ΅ΠΉ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΠΉ Π΄Π»Ρ /proc ΡΠ°ΠΉΠ»Π°, Π²ΠΊΠ»ΡΡΠ°Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π½Π° Π»ΡΠ±ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄ΡΠ°ΠΉΠ²Π΅ΡΠ° (Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΈΠΌΠ΅Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½, Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠΉ ΠΊΠΎΠ³Π΄Π° ΠΊΡΠΎ-ΡΠΎ ΠΏΡΡΠ°Π΅ΡΡΡ ΡΠΈΡΠ°ΡΡ ΠΈΠ· /proc ΡΠ°ΠΉΠ»Π°). ΠΠ°ΡΠ΅ΠΌ init_module ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅Ρ ΡΡΡΡΠΊΡΡΡΡ ΠΈ cleanup_module ΠΎΡΠΌΠ΅Π½ΡΠ΅Ρ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ.
ΠΡΠΈΡΠΈΠ½Π° ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ proc_register_dynamic[2] Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΌΡ Π½Π΅ Ρ ΠΎΡΠΈΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ inode Π½ΠΎΠΌΠ΅Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ ΡΠ°ΠΉΠ»Π° Π·Π°ΡΠ°Π½Π΅Π΅, Π½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅ΠΌ ΡΠ΄ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ Π΅Π³ΠΎ, ΡΡΠΎΠ±Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ ΡΡΠΎΠ»ΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ. Π Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°Ρ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½Π½ΡΡ Π½Π° Π΄ΠΈΡΠΊΠ΅, Π° Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ Π² ΠΏΠ°ΠΌΡΡΠΈ (ΠΊΠ°ΠΊ /proc) inode ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΌ Π½Π° ΡΠΎ ΠΌΠ΅ΡΡΠΎ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π° Π΄ΠΈΡΠΊΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ ΠΈΠ½Π΄Π΅ΠΊΡΠ½ΡΠΉ ΡΠ·Π΅Π» ΡΠ°ΠΉΠ»Π° (ΠΊΡΠ°ΡΠΊΠΎ, inode). Inode ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ°ΠΉΠ»Π°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°, Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Π΅ΠΌ Π½Π° ΡΠΎ ΠΌΠ΅ΡΡΠΎ, Π³Π΄Π΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π½Π°ΠΉΠ΄Π΅Π½Ρ Π΄Π°Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Π°.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π½ΠΈΠΊΠ°ΠΊΠΈΡ Π½Π°ΡΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π½Π΅ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΊΠΎΠ³Π΄Π° ΡΠ°ΠΉΠ» ΠΎΡΠΊΡΡΠ²Π°Π΅ΡΡΡ ΠΈΠ»ΠΈ Π·Π°ΠΊΡΡΠ²Π°Π΅ΡΡΡ, Π½Π΅ΠΊΡΠ΄Π° ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ MOD_INC_USE_COUNT ΠΈ MOD_DEC_USE_COUNT Π² ΡΡΠΎΠΌ ΠΌΠΎΠ΄ΡΠ»Π΅, ΠΈ Π΅ΡΠ»ΠΈ ΡΠ°ΠΉΠ» ΠΎΡΠΊΡΡΡ ΠΈ Π·Π°ΡΠ΅ΠΌ ΠΌΠΎΠ΄ΡΠ»Ρ ΡΠ΄Π°Π»Π΅Π½, Π½Π΅ ΠΈΠΌΠ΅Π΅ΡΡΡ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΡΠΏΠΎΡΠΎΠ±Π° ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ. Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ Π³Π»Π°Π²Π΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ Π±ΠΎΠ»Π΅Π΅ ΡΡΠΆΠ΅Π»ΡΠΉ Π² ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ, Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΏΡΡΡ ΠΈΠΌΠ΅ΡΡΠΈΠΉ Π΄Π΅Π»ΠΎ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΠΈΠ· /proc, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ Π½Π°ΠΌ Π·Π°ΡΠΈΡΠΈΡΡΡΡ ΠΎΡ ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
procfs.c/* procfs.c - create a "file" in /proc
* Copyright (C) 1998-1999 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 because we use the proc fs */
#include <linux/proc_fs.h>
/* In 2.2.3 /usr/include/linux/version.h includes a
* macro for this, but 2.0.35 doesn't - so I add it
* here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
/* Put data into the proc fs file.
Arguments
=========
1. The buffer where the data is to be inserted, if you decide to use it.
2. A pointer to a pointer to characters. This is useful if you don't want to use the buffer allocated by the kernel.
3. The current position in the file.
4. The size of the buffer in the first argument.
5. Zero (for future use?).
Usage and Return Value
======================
If you use your own buffer, like I do, put its location in the second argument and return the number of bytes used in the buffer.
A return value of zero means you have no further information at this time (end of file). A negative return value is an error condition.
For More Information
====================
The way I discovered what to do with this function wasn't by reading documentation, but by reading the code which used it. I just looked to see what uses the get_info field of proc_dir_entry struct (I used a combination of find and grep, if you're interested), and I saw that it is used in <kernel source directory>/fs/proc/array.c.
If something is unknown about the kernel, this is usually the way to go. In Linux we have the great advantage of having the kernel source code for free - use it.
*/
int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int zero) {
int len; /* The number of bytes actually used */
/* This is static so it will still be in memory when we leave this function */
static char my_buffer[80];
static int count = 1;
/* We give all of our information in one go, so if the
* user asks us if we have more information the
* answer should always be no.
*
* This is important because the standard read
* function from the library would continue to issue
* the read system call until the kernel replies
* that it has no more information, or until its * buffer is filled. */
if (offset > 0) return 0;
/* Fill the buffer and get its length */
len = sprintf(my_buffer, "For the %d%s time, go away!\n", count,
(count % 100 > 10 && count % 100 < 14) ? "th" :
(count % 10 == 1) ? "st" : (count % 10 == 2) ? "nd" :
(count % 10 == 3) ? "rd" : "th" );
count++;
/* Tell the function which called us where the buffer is */
*buffer_location = my_buffer;
/* Return the length */
return len;
}
struct proc_dir_entry Our_Proc_File = {
0, /* Inode number - ignore, it will be filled by proc_register[_dynamic] */
4, /* Length of the file name */
"test", /* The file name */
S_IFREG | S_IRUGO, /* File mode - this is a regular file which can be read by its owner, its group, and everybody else */
1, /* Number of links (directories where the file is referenced) */
0, 0, /* The uid and gid for the file - we give it * to root */
80, /* The size of the file reported by ls. */
NULL, /* functions which can be done on the inode (linking, removing, etc.) - we don't support any. */
procfile_read, /* The read function for this file, the function called when somebody tries to read something from it. */
NULL /* We could have here a function to fill the file's inode, to enable us to play with permissions, ownership, etc. */
};
/* Initialize the module - register the proc file */
int init_module() {
/* Success if proc_register[_dynamic] is a success, failure otherwise. */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
/* In version 2.2, proc_register assign a dynamic
* inode number automatically if it is zero in the
* structure, so there's no more need for
* proc_register_dynamic */
return proc_register(&proc_root, &Our_Proc_File);
#else
return proc_register_dynamic(&proc_root, &Our_Proc_File);
#endif
/* proc_root is the root directory for the proc fs (/proc). This is where we want our file to be located. */
}
/* Cleanup - unregister our file from /proc */
void cleanup_module() {
proc_unregister(&proc_root, Our_Proc_File.low_ino);
}
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ /proc Π΄Π»Ρ Π²Π²ΠΎΠ΄Π°
ΠΠΎΠΊΠ° ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π²Π° ΡΠΏΠΎΡΠΎΠ±Π° Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ²ΠΎΠ΄ ΠΈΠ· ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ: ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°ΡΡ Π΄ΡΠ°ΠΉΠ²Π΅Ρ ΡΡΡΡΠΎΠΉΡΡΠ²Π° ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ mknod ΡΠ°ΠΉΠ» ΡΡΡΡΠΎΠΉΡΡΠ²Π°, ΠΈΠ»ΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΡΡ /proc ΡΠ°ΠΉΠ». ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΌΠΎΠ΄ΡΠ»Ρ ΡΠΎΠΎΠ±ΡΠ°ΡΡ Π½Π°ΠΌ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ. ΠΠ΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½Π°Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π² ΡΠΎΠΌ, ΡΡΠΎ Π½Π΅ ΠΈΠΌΠ΅Π΅ΡΡΡ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΏΡΡΠΈ Π΄Π»Ρ Π½Π°Ρ, ΡΡΠΎΠ±Ρ Π²ΠΎΠ·ΡΠ°Π·ΠΈΡΡ. ΠΠ΅ΡΠ²ΡΠΉ ΠΏΡΡΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΡ ΠΏΠΎΡΠ»Π΅ΠΌ Π²Π²ΠΎΠ΄ ΠΌΠΎΠ΄ΡΠ»ΡΠΌ, Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΠΈΡΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² ΡΠ°ΠΉΠ» Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ /proc.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ°ΠΉΠ»ΠΎΠ²Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° /proc Π±ΡΠ»Π° Π½Π°ΠΏΠΈΡΠ°Π½Π° Π³Π»Π°Π²Π½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡΡ ΡΠ΄ΡΡ ΡΠΎΠΎΠ±ΡΠ°ΡΡ ΡΠΈΡΡΠ°ΡΠΈΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌ, Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΠΉ Π΄Π»Ρ Π²Π²ΠΎΠ΄Π°. Π‘ΡΡΡΠΊΡΡΡΠ° proc_dir_entry Π½Π΅ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΡΠ½ΠΊΡΠΈΡ Π²Π²ΠΎΠ΄Π°. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΏΠΈΡΠ°ΡΡ Π² /proc, ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ.
Π Linux ΠΈΠΌΠ΅Π΅ΡΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ Π΄Π»Ρ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΊΠ°ΠΆΠ΄Π°Ρ ΡΠ°ΠΉΠ»ΠΎΠ²Π°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΠΌΠ΅ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ inode ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ[3], ΠΈΠΌΠ΅Π΅ΡΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½Π°Ρ ΡΡΡΡΠΊΡΡΡΠ°, ΡΡΠΎΠ±Ρ Ρ ΡΠ°Π½ΠΈΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π½Π° Π²ΡΠ΅ Π½ΡΠΆΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, struct inode_operations, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° struct file_operations. Π /proc Π²ΡΡΠΊΠΈΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΡΠ°ΠΉΠ», Π½Π°ΠΌ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ struct inode_operations Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΡΡΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ. ΠΡΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ, struct inode_operations, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° struct file_operations, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ Π½Π° Π½Π°ΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ module_input ΠΈ module_output.
ΠΠ°ΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΡΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΡΠΎΠ»ΠΈ ΡΡΠ΅Π½ΠΈΡ ΠΈ Π·Π°ΠΏΠΈΡΠΈ, ΠΎΠ±ΡΠ°ΡΠ΅Π½Ρ Π² ΡΠ΄ΡΠ΅. Π€ΡΠ½ΠΊΡΠΈΠΈ ΡΡΠ΅Π½ΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π°, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ Π·Π°ΠΏΠΈΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ Π²Π²ΠΎΠ΄Π°. ΠΡΠΈΡΠΈΠ½Π° Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ Π·Π°ΠΏΠΈΡΡ ΠΎΡΠ½ΠΎΡΡΡΡΡ ΠΊ ΡΠΎΡΠΊΠ΅ Π·ΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ: Π΅ΡΠ»ΠΈ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠΈΡΠ°Π΅Ρ ΡΡΠΎ-ΡΠΎ ΠΈΠ· ΡΠ΄ΡΠ°, ΡΠ΄ΡΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²ΡΠ²Π΅ΡΡΠΈ ΡΡΠΎ, Π° Π΅ΡΠ»ΠΈ ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΠΈΡΠ΅Ρ ΡΡΠΎ-ΡΠΎ Π² ΡΠ΄ΡΠΎ, ΠΎΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΡΡΠΎ ΠΊΠ°ΠΊ Π²Π²ΠΎΠ΄.
ΠΡΡΠ³Π°Ρ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½Π°Ρ ΡΠΎΡΠΊΠ° Π·Π΄Π΅ΡΡ ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ module_permission. ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π²ΡΡΠΊΠΈΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΡΠ΅ΡΡ ΠΏΡΠΎΠ±ΡΠ΅Ρ Π΄Π΅Π»Π°ΡΡ ΡΡΠΎ-Π»ΠΈΠ±ΠΎ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΡΠΈΡΡΠ΅ΠΌΡ /proc, ΠΈ ΠΌΠΎΠΆΠ΅Ρ ΡΠ΅ΡΠΈΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΈΠ»ΠΈ Π½Π΅Ρ. Π‘Π΅ΠΉΡΠ°Ρ ΡΡΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΡΠ½ΠΎΠ²Π°Π½ΠΎ Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΈ uid ΡΠ΅ΠΊΡΡΠΈΠ΅Π³ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, Π½ΠΎ Π² ΠΏΡΠΈΠ½ΡΠΈΠΏΠ΅ ΡΠ°ΠΊΠΎΠ΅ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ΄Π°Π²Π°ΡΡΡΡ ΠΈΡΡ ΠΎΠ΄Ρ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎ Π΄ΡΡΠ³ΠΈΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΡ Π΄Π΅Π»Π°ΡΡ Ρ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠ°ΠΌΡΠΌ ΡΠ°ΠΉΠ»ΠΎΠΌ, Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π΄Π½Ρ ΠΈΠ»ΠΈ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ Π²Π²ΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ.