Аватар для peter_irich
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394

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

12.06.2018, 23:06. Показов 2877. Ответов 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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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
368 / 224 / 53
Регистрация: 18.10.2017
Сообщений: 2,394
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 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru