Хранение массива структуры в пространстве ядра, Linux - PullRequest
0 голосов
/ 24 ноября 2010

Полагаю, я немного обдумал эту проблему ... У меня есть текстовый файл, расположенный на моей файловой системе, который я анализирую при загрузке и сохраняю результаты в виде массива структур. Мне нужно скопировать этот массив из пространства пользователя в пространство ядра (copy_from_user), и эти данные должны быть доступны ядру в любое время. Данные в пространстве ядра должны быть доступны из файла Sockets.c. Есть ли специальное место для хранения массива в пространстве ядра, или я могу просто добавить ссылку на массив в Sockets.c? Мой C немного ржавый ...

Спасибо за любой совет.

Ответы [ 3 ]

6 голосов
/ 24 ноября 2010

Я считаю, что в вашей задаче есть две основные части:

  • Передача данных из пространства пользователя в пространство ядра

  • Хранение данных в пространстве ядра

Для первого вопроса я бы предложил использовать сокет Netlink, а не более традиционный интерфейс системного вызова (чтение / запись / ioctl). Сокеты Netlink позволяют передавать данные конфигурации в ядро ​​с помощью интерфейса, подобного сокету, что значительно проще и безопаснее в использовании.

Ваша программа должна выполнить весь синтаксический анализ и проверку ввода, а затем передать данные ядру, предпочтительно в более структурированной форме (например, запись за записью), чем массивный большой двоичный объект данных.

Если вы не заинтересованы в высокой пропускной способности (мегабайт данных в секунду), интерфейс netlink в порядке. Следующие ссылки предоставляют объяснение, а также пример:

http://en.wikipedia.org/wiki/Netlink

http://www.linuxjournal.com/article/7356

http://linux -net.osdl.org / index.php / Generic_Netlink_HOWTO

http://www.kernel.org/doc/Documentation/connector/

Что касается хранения массива, если вы планируете хранить более 128 КБ данных, вам придется использовать vmalloc () для выделения пространства, в противном случае предпочтительнее использовать kmalloc (). Вам следует прочитать соответствующую главу книги «Драйверы устройств Linux»:

http://lwn.net/images/pdf/LDD3/ch08.pdf

Обратите внимание, что буферы, выделенные с помощью vmalloc (), не подходят для устройств DMA с / на устройства, поскольку страницы памяти не являются смежными. Вы также можете рассмотреть более сложную структуру данных, такую ​​как список, если вы не знаете, сколько записей у вас будет заранее.

Что касается глобального доступа к хранилищу, вы можете сделать это, как с любой программой на C:

В заголовочный файл, включенный во все .c файлы, которые вам нужны для доступа к данным, поместите что-то вроде:

extern struct my_struct *unique_name_that_will_not_conflict_with_other_symbols;

Ключевое слово extern указывает, что оно объявляет переменную, которая реализована в другом исходном файле. Это сделает этот указатель доступным для всех файлов C, которые включают этот заголовок. Затем в C-файле, предпочтительно, с остальным кодом - если он существует:

struct my_struct *unique_name_that_will_not_conflict_with_other_symbols = NULL;

Реальная реализация переменной, объявленной в заголовочном файле.

PS: Если вы собираетесь работать с ядром Linux, вам действительно нужно освежить свой C. В противном случае у вас будут некоторые очень разочаровывающие моменты, и вы в конечном итоге будете сожалеть и болеть.

PS2: Вы также сэкономите много времени, если хотя бы пролистаете всю книгу «Драйверы устройств Linux». Несмотря на название и относительный возраст, он содержит много актуальной и важной информации при написании любого кода для ядра Linux.

1 голос
/ 24 ноября 2010

Ваш вопрос достаточно простой и неопределенный, поэтому я рекомендую вам выполнить некоторые из упражнений в этой книге . Вся глава 8 посвящена выделению памяти ядра.

1 голос
/ 24 ноября 2010

Вы можете просто определить указатель extern где-нибудь в ядре (скажем, в файле sockets.c, где вы собираетесь его использовать). Инициализируйте его как NULL и включите объявление для него в некоторый соответствующий заголовочный файл.

В той части кода, которая выполняет copy_from_user(), выделите пространство для массива с помощью kmalloc() и сохраните адрес в указателе. Скопируйте данные в него. Вы также захотите, чтобы мьютекс был заблокирован вокруг доступа к массиву.

Память, выделенная kmalloc(), будет сохраняться, пока не будет освобождена с помощью kfree().

...