Linux - статьи


              

по которой для копирования данных


Причина, по которой для копирования данных используются функции put_user и get_user, состоит в том, что процессы в Linux (по крайней мере в архитектуре Intel) исполняются в изолированных адресных пространствах, не пересекающихся с адресным пространством ядра. Это означает, что указатель, не содержит уникальный адрес физической памяти -- он хранит логический адрес в адресном пространстве процесса.

Единственное адресное пространство, доступное процессу -- это его собственное адресное пространство. Практически любой модуль ядра, должен иметь возможность обмена информацией с пользовательскими процессами. Однако, когда модуль ядра получает указатель на некий буфер, то адрес этого буфера находится в адресном пространстве процесса. Макрокоманды put_user и get_user позволяют обращаться к памяти процесса по указанному им адресу.

Пример 5-3. procfs.c

/* * procfs.c - Пример создания файла в /proc, * который доступен как на чтение, так и на запись. */ /* Необходимо для любого модуля */ #include <linux/module.h> /* Все-таки мы работаем с ядром! */ #include <linux/kernel.h> /* Необходимо для работы с файловой системой /proc */ #include <linux/proc_fs.h> /* определения функций get_user и put_user */ #include <asm/uaccess.h>

/* * Место хранения последнего принятого сообщения, * которое будет выводиться в файл, чтобы показать, что * модуль действительно может получать ввод от пользователя */ #define MESSAGE_LENGTH 80 static char Message[MESSAGE_LENGTH]; static struct proc_dir_entry *Our_Proc_File;

#define PROC_ENTRY_FILENAME "rw_test"

static ssize_t module_output(struct file *filp, /* см. include/linux/fs.h */ char *buffer, /* буфер с данными */ size_t length, /* размер буфера */ loff_t * offset) { static int finished = 0; int i; char message[MESSAGE_LENGTH + 30];

/* * Для индикации признака конца файла возвращается 0. * Если этого не сделать, процесс будет продолжать * пытаться читать из файла, * угодив в бесконечный цикл. */ if (finished) { finished = 0; return 0; }


Содержание  Назад  Вперед