Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: udp-сокеты в kernel module :)  (Прочитано 20698 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Sava
Участник

by
Offline Offline

« : 16-12-2008 08:54 » 

здравствуйте, необходимо найти информацию, желательно подробную, про udp-сокеты в ядре, как они реализуются, нашла только
h**p://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-3.html, но там мало пояснений, и никак не разберусь, как отправлять сообщения от модуля ядра через udp-сокеты... долго копалась в исходниках, все красиво, но непонятно.
может, кто еще ссылочек подбросит... Улыбаюсь
« Последнее редактирование: 16-12-2008 10:24 от Вад » Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #1 : 16-12-2008 09:09 » 

почему именно udp сокеты?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sava
Участник

by
Offline Offline

« Ответ #2 : 16-12-2008 09:18 » 

 Отлично
хочу udp-сокеты и все тут Скромно так...
ладно, если есть толковые ссылки по другим, то, оставьте, пожалуйста... Улыбаюсь
а то дым из ушей уже идет от поиска в google
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 16-12-2008 14:55 » 

Ну тут можно только одно посоветовать, смотри исходники ядра Linux. Расположение относительно директории куда распакованы исходники: ./net/ipv4/udp.c

Если нет исходников и желания их качать, то я прикрепил именно udp.c из ядра 2.4.37, в ядре 2.6.х udp.c аналогичны.

* udp.c (28.28 Кб - загружено 1116 раз.)
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #4 : 16-12-2008 14:59 » 

Sava, все зависит от того что конкретно ты хочешь, какие сообщения, куда, кому?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sava
Участник

by
Offline Offline

« Ответ #5 : 16-12-2008 15:07 » new

Serg79, спасибо, почитаю. Улыбаюсь

McZim:
1. сообщения типа "Привет!"
2. и 3. пользовательской программе, которая ждет сообщения и ловит udp-пакеты
 
P.S. а зачем такие уточнения нужны?
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #6 : 16-12-2008 15:14 » 

Sava,

1. Чтобы создать простой канал на Си, мы прибегаем к использованию системного вызова pipe(). Для него требуется единственный аргумент, который является массивом из двух целых (integer), и, в случае успеха, массив будет содержать два новых файловых дескриптора, которые будут использованы для канала. После создания канала процесс обычно порождает новый процесс, а процесс-потомок наследует открытые файловые дескрипторы

Код:
SYSTEM CALL: pipe();
PROTOTYPE: int pipe( int fd[2] );
RETURNS: 0 в случае успеха
-1 в случае ошибки:
errno = EMFILE (нет свободных дескрипторов)
EMFILE (системная файловая таблица переполнена)
EFAULT (массив fd некорректен)

NOTES: fd[0] устанавливается для чтения, fd[1] - для записи.

Первое целое в массиве (элемент 0) установлено и открыто для чтения, в то время как второе целое (элемент 1) установлено и открыто для записи.

Далее мы рассмотрим пример, когда создается родительский процесс и процесс-потомок. Родительский проуесс мы откроем на чтение, а процесс-потомок мы откроем на запись.

И так создадим канал:

Код:
int fd[2];
pipe(fd);

//мы создали родительский процесс, заметим что (fd), тоже самое что и (&fd[0])

двлее нам нужно создать потомка этого процесса:

Код:
if ((childpid = fork()) == -1)
{
perror("fork");
exit(0);
}

Если родитель хочет получить данные от потомка, то он должен закрыть fd1, а потомок должен закрыть fd0.

Код:
if (childpid == 0)
{
close(fd[0]); //выполняем для потомка
}
else
{
close(fd[1]); //выполняем для родителя
}

рассмотрим весь код нашей программы:

Код:
/*
fd[0] -- read
fd[1] -- write

i'm create parent and child process, parent process read (fd[0]), child process write (fd[1])
*/

#include ...

int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[20];

pipe(fd);

if ((childpid = fork()) == -1) //create child process
{
perror("fork");
exit(0);
}

if (childpid == 0)
{
close(fd[0]);

write(fd[1], string, strlen(string));
exit(0);
}

else
{
close(fd[1]);

nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}

return(0);
}

И так, мы осуществили взамодействие между двумя процессами, родителем и потомком, с помощью системного вызова pipe(), более детально о системный вызовах и unix каналах читайте в гугле Ага

2. Я считаю нет смысла общаться с процессом который на этом же компе, методом udp, даже если она их уже ждет.
3. Уточнения нужно потому что для разного рода задач, нужно использовать разные юникс каналы.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sava
Участник

by
Offline Offline

« Ответ #7 : 16-12-2008 15:18 » 

McZim, спасибо. Улыбаюсь
только мне нужен модуль ядра  Улыбаюсь
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #8 : 16-12-2008 15:20 » 

Модуль ядра так модуль ядра, нет ничего проще

Я не буду углубляться в то, чтобы описывать что такое модуль и как он попадает в ядро, а сразу приступлю к делу.

И так для нашего будущего модуля понадобятся два файла, Makefile и файл с исходным кодом. Допустим файл с исходным кодом мы обзавем hellomod.c, а его содержимое будет:

Код:
#include 
#include
#include

MODULE_LICENSE("GPL");

static int __init hello_in(void)
{
printk("KERN_ALERT Hello, World! From the KERNEL space...\n");
return 0;
}

static void __exit hello_out(void)
{
printk("KERN_ALERT Goodbye, World! Leaving KERNEL space...\n");
}

module_init(hello_in);
module_exit(hello_out);

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

этих уровней у нас 8:

Код:
0 - KERN_EMERG //system is unusable
1 - KERN_ALERT //action must be taken immediately
2 - KERN_CRIT //critical conditions
3 - KERN_ERR //error conditions
4 - KERN_WARNING //warning conditions
5 - KERN_NOTICE //normal
6 - KERN_INFO //informational
7 - KERN_DEBUG //debug

Дальше нам нужно описать Makefile для нашего файла с исходным кодом, выглядеть он будет так:

Код:
obj-m += hellomod.o

вот и все, все что нам осталось это скомпилировать наш исходный код в модуль ядра, следующей коммандой:
Код:
make -C /usr/src/linux-`uname -r` SUBDIRS=$PWD modules

После чего мы должны увидеть нечто вроде:

Код:
make: Entering directory `/usr/src/linux-2.6.23.9'
CC [M] /home/mczim/programming/test/hellomod.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/mczim/programming/test/hellomod.mod.o
LD [M] /home/mczim/programming/test/hellomod.ko
make: Leaving directory `/usr/src/linux-2.6.23.9'

В директории /usr/src/linux-2.6.23.9 --лежат исходники ядра, на котором производилась данная сборка.

теперь мы готовы подгрузить наш модуль в ядро:

Код:
sudo insmod hellomod.ko

и смотрим в лог:
Код:
Jan 22 23:10:39 mczim-desktop kernel: [365908.733723] KERN_ALERT Hello, World! From the KERNEL space...

теперь выгрузим наш модуль из ядра:

Код:
sudo rmmod hellomod.ko

продолжаем смотреть в лог:
Код:
Jan 22 23:12:42 mczim-desktop kernel: [366031.925420] KERN_ALERT Goodbye, World! Leaving KERNEL space...

Итак, мы сами написали свой собственный (хоть и не значительный) модуль для ядра Linux, подгрузили его убедились что он работает, а затем выгрузили его. Хочу напомнить что работа производилась с версией ядра 2.6.23.9, в версиях ядер 2.2.x.x и 2.4.x.x написание модулей, а так же их инсталяция в ядро происходит немного по другому.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 16-12-2008 18:29 » 

Sava, посмотри здесь: https://club.shelek.ru/viewfiles.php?id=9
Linux Device Drivers
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sava
Участник

by
Offline Offline

« Ответ #10 : 16-12-2008 19:20 » 

 :)McZim, спасибо, конечно, только такие я уже умею делать, и читала месяц назад у тебя в блоге.
мне нужен модуль ядра, который отправляет сообщение через udp-сокет и подробно про то, как этот сокет в ядре создается...
думаю в ldd поищу еще...
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 16-12-2008 20:10 » 

Sava, примеры сложно будет найти. Проще самому посмотреть в коде ядра, что делают syscall socket, bind, sendto и close - они просто находят нужные структуры ядра и вызывают функции через указатели в этих структурах.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sava
Участник

by
Offline Offline

« Ответ #12 : 17-12-2008 08:38 » 

может кто-нибудь встречался с такой ошибкой

localhost kernel: BUG: unable to handle kernel paging request at virtual address 726c6c61

она получается после того, как я пытаюсь запихнуть информацию в буфер для посылки в пользовательскую программу, и послать через udp
Записан
Sava
Участник

by
Offline Offline

« Ответ #13 : 17-12-2008 09:56 » 

а,  разобралась, там просто буфер не обнулялся, и до такой степени засорился, что ядро начало ругаться Улыбаюсь
Записан
Sava
Участник

by
Offline Offline

« Ответ #14 : 17-12-2008 13:36 » 

Всем спасибо!!!!!!!!!!!!!!!!!!!!!!! Улыбаюсь) Улыбаюсь Внимание! Говорит и показывает... Отлично
у меня получилось, только теперь надо отправить полученное значение назад в модуль!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines