Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389

Драйвер для ядра 3.x и старше

12.06.2018, 23:06. Показов 2861. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Есть где-нибудь руководство по написанию драйверов для Linux с ядром 3.x и 4.x?
Конкретно надо для ядра 3.16, связанный с константами для клавиатуры.
В файле include/uapi/linux/input.h нет их описаний, также не вполне понятно, как создавать свои ioctl().
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.06.2018, 23:06
Ответы с готовыми решениями:

Как установить драйвер ядра для VirtuaBox?
доброго времени суток ! хочу установить Virtual Box на Ubuntu 13.04 64bit (недавно сама обновилась =) ) но при запуске машины выдает...

Драйвер службы ядра
Пишу программку. Скинул ее потестить человеку на другую машину- и вылазит постоянное предупреждение:

Драйвер ядра устройства NULL
В стандартной утилите "Сведения о системе", пункт "Устройство с неполадками" присутствует пункт: "устройство - NULL, код устройства...

29
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
19.06.2018, 15:17
не смог в личное сообщение написать. (хотел пдф книги вложить.или хотябы название сказать)
потому, просто пишу тут.
такие книги есть.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
19.06.2018, 20:44  [ТС]
Хорошо, буду знать что они есть, а я уже думал, что их нет, т.к. на другом сайт мне далии ссылки
опять же на книгу по 2.6. Правда, в исходных текстах ядра в Documentation есть описания и даже
примеры, но хотелось бы в систематическом виде, типа книги.
0
48 / 46 / 18
Регистрация: 27.04.2016
Сообщений: 169
19.06.2018, 22:46
Есть Linux Device Drivers Development 2017-го года на английском. Думаю, в ней версия ядра посвежее 2.6. Но это не точно.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
19.06.2018, 23:10  [ТС]
Благодарю за название. Я и сам собирался искать по английским названиям, так что посмотрю.
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
22.06.2018, 23:46
Практикум: модули ядра Linux
Конспект с примерами и упражнения с задачами
Автор: Олег Цилюрик
Редакция 6.245
18.03.2015 г.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
23.06.2018, 11:34  [ТС]
sgaeal, очень благодарен за совет, скачал эту книгу в pdf, там сказано,
что примеры проверялись на ядрах до 3.17 включительно. Материал, как мне показалось,
изложен очен хорошо. Буду читать.
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
26.06.2018, 16:08
Совет как действовать.
Качаешь все ядра с кернелорга. Разархивируешь красиво по папочкам.
И далее с помощью grep определяешь какие были изменения, в той часте кода, которую изучаешь.
Т.е. прочёл книгу. Там допустим есть структура struct inode

делаешь команду
grep '^struct inode {' -r /path_kernel_sources
и видишь где эта структура находится, в каждой версии ядра. (структуры могут располагаться в разных файлах)


Если есть изменения в теле структур, то по такомуже способу, через греп, определяешь где изменение произошло.

Могу сказать что с 2,0,x и по сей день, кодинг особо не изменился для ядра.
Вот маленькая книжка https://www.ozon.ru/context/detail/id/17925734/ Как помню, там тоже ядра выше 3,x

Вот книга https://www.ozon.ru/context/detail/id/3589107/ Наверно самая ценная по этому вопросу , хоть и вышла в 2007 году. (АКТУАЛЬНА)
Ну и есть книга https://www.ozon.ru/context/detail/id/2441431/ По сетевой архитектуре. 2006 год. Также АКТУАЛЬНА и на сегодняшний день.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
26.06.2018, 20:47  [ТС]
sgaeal, благодарю за внимание. Книга "Ядро Linux" меня есть, названной книги Р. Лава нет,
есть другая с похожим названием, 2-е издание. Вообще на работе я раза 2 или 3 корректировал
текст драйвера для более старого ядра. Понятно, что нетрудно найти, где в ядре находится необходимый
файл или структура. Пока мне достаточно книги Цилюрика. Он там предлагает не пользоваться ioctl(),
а использовать интерфейс /proc или /sys, но для этого надо затратить заметно больше усилий,
чем для ioctl(), так что я собираюсь обойтись ioctl().
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
26.06.2018, 22:30
http://itsecforu.ru/wp-content... abotki.pdf

Добавлено через 8 минут
Если найдёте, чтонить интересное почитать по ядру на русс языке, то кидайте ссылки в эту тему.

https://habr.com/company/intel/blog/266701/
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
27.06.2018, 20:40  [ТС]
sgaeal, благодарю за ссылку, скачал.

Добавлено через 21 час 13 минут
sgaeal, Не будете ли уж так любезны подсказать, где можно взять архивы с примерами,
упоминаемые в книге Цилюрика? Я сейчас просматриваю его статьи по ссылке в конце книги,
пока дощёл только до 4-й, а их там 77. Там какие-то архивы есть.
И ещё: может ли модуль, не драйвер, содержать свои ioctl(), может ли он включать структуру file_operations??
Или он обязательно должен быть в форме драйвера символьного устройства?
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
27.06.2018, 20:49
Насчёт архивов кода, не подскажу. Я их даже не смотрел.

"И ещё: может ли модуль, не драйвер, содержать свои ioctl(), может ли он включать структуру file_operations??"
Может.
Вообще странный вопрос. У Вас мало опыта в кодинге?
Модуль , может ВСЁ!.
не важно как что называется... file_operations или skb или что там ещё есть. Когда вы программируете модуль, у вас есть доступ ко всему! хоть к коду на микросхемах (имею ввиду память на материнке..или сидироме...или что там ещё есть)

Т.Е. не важно, какая у вас стоит задача. Её можно реализовать.
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
27.06.2018, 21:01  [ТС]
sgaeal, благодарю за быстрый ответ.
В создании драйверов вообще нет опыта, только однажды для DOS написал обработчик прерывания от клавиатуры,
но не полноценный, а заменяющий какие-то два символа на другие, это было необходимо для ФИДО.
Я подозревал, что модуль может иметь свой ioctl(), но всё же сомневался.
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
27.06.2018, 21:09
https://habr.com/post/106702/
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
27.06.2018, 22:02  [ТС]
sgaeal, ещё раз благодарю за внимание, скачал, но, кажется, у меня эта страница уже была скачана,
явно что-то очень знакомое.
Что касается архивов, то они есть в ссылках на отдельные статьи Цилюрика, я их сейчас по порядку скачиваю
в pdf, и архивы тоже, дощёл до 31-й, один архив - cdev.tgz - оказался утрачен

Добавлено через 37 минут
Оказались утраченными 11 -архивов - cdev,signal,call_table,new_sys,add_sys,h idden,umaster,master,plugin,udev,user_io .

Добавлено через 6 минут
call_table есть, я ошибся.
0
48 / 46 / 18
Регистрация: 27.04.2016
Сообщений: 169
30.06.2018, 15:02
peter_irich, по этой ссылке не ходили?
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
30.06.2018, 23:34  [ТС]
si1n3rd, по этой нет, благодарю за неё, но вообще я начал делать, ориентируясь на
input-programming.txt из документации к ядру и драйвер клавиатуры atkbd.c.
У меня также есть скачанный пример пользовательской программы, посылающей символы системе,
правда, его пришлось немного поправить, чтобы он компилировался и работал. В частности, чтобы символ
сразу же вводился, после него надо посылать Return, а запускать надо от root'а. Вот он:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#define NKEY 7
 
int main(void){
    int fd;
    struct uinput_user_dev uidev;
    struct input_event ev;
  int i,n,key_a[NKEY];
  key_a[0] = KEY_0;
  key_a[1] = KEY_1;
  key_a[2] = KEY_2;
  key_a[3] = KEY_3;
  key_a[4] = KEY_4;
  key_a[5] = KEY_5;
  key_a[6] = KEY_ENTER;
 
    fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if (fd < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ open /dev/uinput : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
    if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ ioctl UI_SET_EVBIT EV_KEY : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
 
  for(i = 0; i < NKEY; i++){
 
    if (ioctl(fd, UI_SET_KEYBIT, key_a[i]) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ ioctl UI_SET_KEYBIT KEY_0 : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
  }
 
    memset(&uidev, 0, sizeof(uidev));
    strcpy(uidev.name, "tmp-input");
    uidev.id.bustype = BUS_I8042;
    uidev.id.vendor  = 0x1;
    uidev.id.product = 0x1;
    uidev.id.version = 1;
    if((n=write(fd, &uidev, sizeof(uidev))) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ write uidev : %d : %s", e, strerror(e));
        exit(EXIT_FAILURE);
    }
 
    if(ioctl(fd, UI_DEV_CREATE) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ ioctl UI_DEV_CREATE : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
 
  for(i = 0; i < NKEY - 1; i++){
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = key_a[i];
    ev.value = 1;
    if ((n=write(fd, &ev, sizeof(struct input_event))) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ write EV_KEY KEY_ESC 1 : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
    usleep(5000);
 
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = key_a[i];
    ev.value = 0;
    if (write(fd, &ev, sizeof(struct input_event)) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ write EV_KEY KEY_ESC 0 : %d : %s",
                e, strerror(e));
    }
    usleep(5000);
 
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = key_a[NKEY - 1];
    ev.value = 1;
    if ((n=write(fd, &ev, sizeof(struct input_event))) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ write EV_KEY KEY_ESC 1 : %d : %s",
                e, strerror(e));
        exit(EXIT_FAILURE);
    }
    usleep(5000);
 
    memset(&ev, 0, sizeof(struct input_event));
    ev.type = EV_KEY;
    ev.code = key_a[NKEY - 1];
    ev.value = 0;
    if (write(fd, &ev, sizeof(struct input_event)) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ write EV_KEY KEY_ESC 0 : %d : %s",
                e, strerror(e));
    }
    usleep(200000);
 
  }
 
    if (ioctl(fd, UI_DEV_DESTROY) < 0) {
        const int e = errno;
        fprintf(stdout, "fail @ ioctl UI_DEV_DESTROY : %d : %s",
                e, strerror(e));
    }
 
    close(fd);
    fprintf(stdout, "\nexit: %d\n",i);
 
    return EXIT_SUCCESS;
}
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
03.07.2018, 21:39  [ТС]
С помощью sgael и драйвера atkbd.c из ядра я как-то написал модуль, он загружается,
для него создаётся устройство в /dev, он принимает из проверочной программы ioctl() и правильно
их расшифровывает, но input_event() не выполняется. М.б., кто-нибудь подскажет, что я упустил?
В atkbd.c структура input_dev и сам драйвер в подавляющем большинстве посвящён реальной клавиатуре,
т.е. в этой структуре надо заполнять не все поля. структура input_dev находится в linux/input.h.
Вот модуль:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "dev.h"
#include "ioctl.h"
 
#define MYEVENT_MAJOR 201
#define MYEVENT_MODNAME "my_event"
 
// Работа с символьным устройством в старом стиле...
static int dev_open( struct inode *n, struct file *f ) {
   // ... при этом MINOR номер устройства должна обслуживать функция open:
   // unsigned int minor = iminor( n );
   return 0;
}
 
static int dev_release( struct inode *n, struct file *f ) {
   return 0;
}
 
static struct input_dev *i_dev;
static char dname[16];
 
static long dev_ioctl( struct file *f,
                      unsigned int cmd, unsigned long arg ) {
int ni, nr, nc, nv;
  nr = 0;
   if( ( _IOC_TYPE( cmd ) != IOC_MAGIC ) ) return -ENOTTY;
   switch( cmd ) {
    case MYEVENT_CMD_KEY:
      ni = copy_from_user( (void *)&data.n, (void *)arg, _IOC_SIZE( cmd ) );
      if(ni != 0){
        nr =  -EFAULT;
        printk(KERN_ERR "my_event from %d\n", ni);
      }
//  printk(KERN_INFO "my_event from %d\n", data.n);
      nc = data.n;
      nv = (nc > 0) ? 1 : 0;
      if(nv == 0)
        nc = -nc;
      input_event(i_dev, EV_KEY, nc, nv);
//    input_event(i_dev, EV_KEY, KEY_ENTER, 1);
      input_sync(i_dev);
      break;
    default: 
     nr =  -ENOTTY;
  }
  return nr;
}
 
static const struct file_operations event_fops = {
   .owner = THIS_MODULE,
   .open = dev_open,
   .release = dev_release,
   .unlocked_ioctl = dev_ioctl
};
 
int init_module(void){
int error;
 
  i_dev = input_allocate_device();
  if (!i_dev) {
    printk(KERN_ERR "my_event.c: Not enough memory\n");
    error = -ENOMEM;
    goto err_err;
  }
 
//  memset(i_dev, 0, sizeof(struct input_dev));
  i_dev->evbit[0] = BIT_MASK(EV_KEY);
  i_dev->keybit[BIT_WORD(KEY_ESC)] = BIT_MASK(KEY_ESC);
  i_dev->keybit[BIT_WORD(KEY_1)] = BIT_MASK(KEY_1);
  i_dev->keybit[BIT_WORD(KEY_2)] = BIT_MASK(KEY_2);
  i_dev->keybit[BIT_WORD(KEY_3)] = BIT_MASK(KEY_3);
  i_dev->keybit[BIT_WORD(KEY_4)] = BIT_MASK(KEY_4);
  i_dev->keybit[BIT_WORD(KEY_5)] = BIT_MASK(KEY_5);
  i_dev->keybit[BIT_WORD(KEY_6)] = BIT_MASK(KEY_6);
  i_dev->keybit[BIT_WORD(KEY_7)] = BIT_MASK(KEY_7);
  i_dev->keybit[BIT_WORD(KEY_8)] = BIT_MASK(KEY_8);
  i_dev->keybit[BIT_WORD(KEY_9)] = BIT_MASK(KEY_9);
  i_dev->keybit[BIT_WORD(KEY_0)] = BIT_MASK(KEY_0);
  i_dev->keybit[BIT_WORD(KEY_MINUS)] = BIT_MASK(KEY_MINUS);
  i_dev->keybit[BIT_WORD(KEY_EQUAL)] = BIT_MASK(KEY_EQUAL);
  i_dev->keybit[BIT_WORD(KEY_BACKSPACE)] = BIT_MASK(KEY_BACKSPACE);
  i_dev->keybit[BIT_WORD(KEY_TAB)] = BIT_MASK(KEY_TAB);
  i_dev->keybit[BIT_WORD(KEY_Q)] = BIT_MASK(KEY_Q);
  i_dev->keybit[BIT_WORD(KEY_W)] = BIT_MASK(KEY_W);
  i_dev->keybit[BIT_WORD(KEY_E)] = BIT_MASK(KEY_E);
  i_dev->keybit[BIT_WORD(KEY_R)] = BIT_MASK(KEY_R);
  i_dev->keybit[BIT_WORD(KEY_T)] = BIT_MASK(KEY_T);
  i_dev->keybit[BIT_WORD(KEY_Y)] = BIT_MASK(KEY_Y);
  i_dev->keybit[BIT_WORD(KEY_U)] = BIT_MASK(KEY_U);
  i_dev->keybit[BIT_WORD(KEY_I)] = BIT_MASK(KEY_I);
  i_dev->keybit[BIT_WORD(KEY_O)] = BIT_MASK(KEY_O);
  i_dev->keybit[BIT_WORD(KEY_P)] = BIT_MASK(KEY_P);
  i_dev->keybit[BIT_WORD(KEY_LEFTBRACE)] = BIT_MASK(KEY_LEFTBRACE);
  i_dev->keybit[BIT_WORD(KEY_RIGHTBRACE)] = BIT_MASK(KEY_RIGHTBRACE);
  i_dev->keybit[BIT_WORD(KEY_ENTER)] = BIT_MASK(KEY_ENTER);
  i_dev->keybit[BIT_WORD(KEY_LEFTCTRL)] = BIT_MASK(KEY_LEFTCTRL);
  i_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);
  i_dev->keybit[BIT_WORD(KEY_S)] = BIT_MASK(KEY_S);
  i_dev->keybit[BIT_WORD(KEY_D)] = BIT_MASK(KEY_D);
  i_dev->keybit[BIT_WORD(KEY_F)] = BIT_MASK(KEY_F);
  i_dev->keybit[BIT_WORD(KEY_G)] = BIT_MASK(KEY_G);
  i_dev->keybit[BIT_WORD(KEY_H)] = BIT_MASK(KEY_H);
  i_dev->keybit[BIT_WORD(KEY_J)] = BIT_MASK(KEY_J);
  i_dev->keybit[BIT_WORD(KEY_K)] = BIT_MASK(KEY_K);
  i_dev->keybit[BIT_WORD(KEY_L)] = BIT_MASK(KEY_L);
  i_dev->keybit[BIT_WORD(KEY_SEMICOLON)] = BIT_MASK(KEY_SEMICOLON);
  i_dev->keybit[BIT_WORD(KEY_APOSTROPHE)] = BIT_MASK(KEY_APOSTROPHE);
  i_dev->keybit[BIT_WORD(KEY_GRAVE)] = BIT_MASK(KEY_GRAVE);
  i_dev->keybit[BIT_WORD(KEY_LEFTSHIFT)] = BIT_MASK(KEY_LEFTSHIFT);
  i_dev->keybit[BIT_WORD(KEY_BACKSLASH)] = BIT_MASK(KEY_BACKSLASH);
  i_dev->keybit[BIT_WORD(KEY_Z)] = BIT_MASK(KEY_Z);
  i_dev->keybit[BIT_WORD(KEY_X)] = BIT_MASK(KEY_X);
  i_dev->keybit[BIT_WORD(KEY_C)] = BIT_MASK(KEY_C);
  i_dev->keybit[BIT_WORD(KEY_V)] = BIT_MASK(KEY_V);
  i_dev->keybit[BIT_WORD(KEY_B)] = BIT_MASK(KEY_B);
  i_dev->keybit[BIT_WORD(KEY_N)] = BIT_MASK(KEY_N);
  i_dev->keybit[BIT_WORD(KEY_M)] = BIT_MASK(KEY_M);
  i_dev->keybit[BIT_WORD(KEY_COMMA)] = BIT_MASK(KEY_COMMA);
  i_dev->keybit[BIT_WORD(KEY_DOT)] = BIT_MASK(KEY_DOT);
  i_dev->keybit[BIT_WORD(KEY_SLASH)] = BIT_MASK(KEY_SLASH);
  i_dev->keybit[BIT_WORD(KEY_RIGHTSHIFT)] = BIT_MASK(KEY_RIGHTSHIFT);
  i_dev->keybit[BIT_WORD(KEY_LEFTALT)] = BIT_MASK(KEY_LEFTALT);
  i_dev->keybit[BIT_WORD(KEY_SPACE)] = BIT_MASK(KEY_SPACE);
  i_dev->keybit[BIT_WORD(KEY_CAPSLOCK)] = BIT_MASK(KEY_CAPSLOCK);
  i_dev->keybit[BIT_WORD(KEY_F1)] = BIT_MASK(KEY_F1);
  i_dev->keybit[BIT_WORD(KEY_F2)] = BIT_MASK(KEY_F2);
  i_dev->keybit[BIT_WORD(KEY_F3)] = BIT_MASK(KEY_F3);
  i_dev->keybit[BIT_WORD(KEY_F4)] = BIT_MASK(KEY_F4);
  i_dev->keybit[BIT_WORD(KEY_F5)] = BIT_MASK(KEY_F5);
  i_dev->keybit[BIT_WORD(KEY_F6)] = BIT_MASK(KEY_F6);
  i_dev->keybit[BIT_WORD(KEY_F7)] = BIT_MASK(KEY_F7);
  i_dev->keybit[BIT_WORD(KEY_F8)] = BIT_MASK(KEY_F8);
  i_dev->keybit[BIT_WORD(KEY_F9)] = BIT_MASK(KEY_F9);
  i_dev->keybit[BIT_WORD(KEY_F10)] = BIT_MASK(KEY_F10);
  i_dev->keybit[BIT_WORD(KEY_F11)] = BIT_MASK(KEY_F11);
  i_dev->keybit[BIT_WORD(KEY_F12)] = BIT_MASK(KEY_F12);
  i_dev->keybit[BIT_WORD(KEY_UP)] = BIT_MASK(KEY_UP);
  i_dev->keybit[BIT_WORD(KEY_PAGEUP)] = BIT_MASK(KEY_PAGEUP);
  i_dev->keybit[BIT_WORD(KEY_LEFT)] = BIT_MASK(KEY_LEFT);
  i_dev->keybit[BIT_WORD(KEY_RIGHT)] = BIT_MASK(KEY_RIGHT);
  i_dev->keybit[BIT_WORD(KEY_DOWN)] = BIT_MASK(KEY_DOWN);
  i_dev->keybit[BIT_WORD(KEY_PAGEDOWN)] = BIT_MASK(KEY_PAGEDOWN);
 
  strcpy(dname, "my_event");
  i_dev->name = dname;
  i_dev->id.bustype = BUS_I8042;
  i_dev->id.vendor = 1;
  i_dev->id.product = 1;
  i_dev->id.version = 1;
 
  error = input_register_device(i_dev);
  if (error) {
    printk(KERN_ERR "my_event.c: Failed to register device. %d\n", error);
    input_free_device(i_dev);
    goto err_err;
  }
 
   error = register_chrdev( MYEVENT_MAJOR, MYEVENT_MODNAME, &event_fops );
    if( error < 0 ) {
      printk( KERN_ERR "my_event_dev: can't register char device. %d\n", error );
      input_free_device(i_dev);
      goto err_err;
    } else
      printk( KERN_INFO "my_event_dev loaded.\n" );
 
    return 0;
 
err_err:
    return error;
}
 
void cleanup_module( void ) {
  input_unregister_device(i_dev);
  input_free_device(i_dev);
  unregister_chrdev( MYEVENT_MAJOR, MYEVENT_MODNAME );
  printk( KERN_INFO "my_event_dev removed.\n" );
}
Вот заголовочные файлы:
dev.h:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include "user_buf.h"
#include <linux/errno.h>
#include <linux/input.h>
#include <linux/fcntl.h>
#include <uapi/linux/ioctl.h>
 
MODULE_LICENSE( "GPL" );
MODULE_AUTHOR( "Peter Irich <author@prov.ru>" );
MODULE_VERSION( "1.0" );
 
static struct USER_DATA data;
static char name[32];
 
int init_module( void );
 
void cleanup_module( void );
ioctl.h:
C
1
2
3
4
#define IOC_MAGIC    'o'
#define MYEVENT_CMD_KEY _IOR( IOC_MAGIC, 31, int )
 
#define DEVPATH "/dev/my_event"
user_buf.h:
C
1
2
3
4
typedef struct USER_DATA {
   char buf[ 160 ];
  int n;
} USER_DATA;
Добавлено через 59 минут
Возможно, у меня input_event() уходит в никуда или выходит ниоткуда, т.к. я не указал источник или приёмник.
Я пытался это сделать, но пока не получилось.
0
2 / 2 / 0
Регистрация: 19.06.2018
Сообщений: 41
03.07.2018, 21:52
Как обычно, ничего не читал. ничего не проверял. Особо не думал..и тд. Не знаю как это всё работает.
Но скажу своё мнение.


1) Поставь на каждой строчкен printk с выводом текущей строки. Так ты точно узнаешь , докуда код не доходит.
2) Наверняка проблема тут copy_from_user .(заметьте..я только отгадываю.) Наверняка, там в этой функции, какая-то проверка, о которой никто не знает, и изза неё, возвращается ошибка, и код дальше не идёт.
3) .....яб заменил copy_from_user на memcpy
0
 Аватар для peter_irich
367 / 223 / 53
Регистрация: 18.10.2017
Сообщений: 2,389
04.07.2018, 00:09  [ТС]
sgaeal, благодарю за быстрый ответ, но copy_from_user() работает правильно,
там были проверочные printk(), но я их удалил перед помещением сюда. Что посылаю в ioctl()
из проверочной программы, то и выводится.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.07.2018, 00:09
Помогаю со студенческими работами здесь

Модуль ядра и драйвер устройства
Здравствуйте, чем отличается модуль ядра от драйвера устройства? Само понятие. Если я правильно понимаю то модуль ядра это более обширное...

Возможно ли приостановить/заморозить драйвер на уровне ядра
Есть драйвер windows который мне нужно заморозить на 1 минуту. Он работает на уровне нулевого кольца (ring0) В PC Hunter он загружается...

Выборка из БД мужчин от 60 и старше, женщин от 55 и старше на Foxpro 2.6
Помогите осуществить Выборку из БД мужчин от 60 и старше, женщин от 55 и старше Часть кода, где DATW - дата выписки, DATP-дата...

Выборка SQL Foxpro муж от 60 лет старше и жен от 55 лет и старше
Помогите сделать запрос sql муж от 60 лет старше и жен от 55 лет и старше одним запросом Добавлено через 5 минут SELECT * FROM...

Скачал драйвер для ATI и при загрузке пишет не найден драйвер
Скачал драйвер для ATI и при загрузке пишет ненайден драйвер поиска,что делать7


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru