Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Программирование под Unix/Linux > Тема вопросов и ответов по ядру |
Автор: konshyn 26.1.2015, 12:36 |
Надеюсь, модераторы не против:) Суть: отдельная тема, чтобы не создавать каждый раз новую, где я, а может и другие, будут задавать общие вопросы по ядру linux (НЕ решение какой-то определенной проблемы) Итак, первый вопрос: раньше (предполагаю версию ядра меньше 2.16.0) в файле cat /proc/kallsyms вместе с эксмортируемыми именами выводился в первом столбике абсолютный адрес в пространстве ядра этих имен (точка входа). На моем ядре (3.16.0) все адреса заменены на нули. Мне кажется, что это связано с тем, что ядро перестало экспориторовать функцию sys_call_table(), хотя она в файле /proc/kallsyms все еще есть, но когда загружаю модель, где использую эту функцию, то вылетает ошибка имя неопределено. Правильно ли я понимаю, что отсутствие адресов в файлу связано именно с отсутствием экспорта функции sys_call_table? И как в новых версиях ядра можно перехватывать системные вызовы? |
Автор: tzirechnoy 26.1.2015, 20:50 | ||||||
Вы уверены, что в /proc/kallsyms?
Нет, вообще никак не связано. sys_call_table запретили где-то в 2.5, а чтение адресов ядра неруту -- в 2.6.38 (см. kptr_restrict)
Копайте в сторону lsm. Это совсем другой метод, но для большынства практических задач это дажэ удобнее. |
Автор: konshyn 29.1.2015, 19:13 | ||
это код регистрации устройства и создания имени в каталоге /dev. Так вот, после того, как создалось имя, например, example (/dev/example), то он имеет права доступа 600, и получается, что я не могу ничего записать в этой файл, хотя считывать, например через cat могу (приходится использовать sudo, вроде бы логично, но записать через sudo все равно не могу) . Операции read() и write() поддерживаются. Приходится менять права доступа так, чтобы было разрешение записи "для всех остальных". (например 002). Кто может это объяснить? И как сделать так, чтобы файл в /dev создавался с нужными правами? |
Автор: konshyn 29.1.2015, 20:56 |
Есть что-нибудь похожее на strerror() в ядре? |
Автор: tzirechnoy 30.1.2015, 01:32 | ||||||
Если ты пишэшь sudo cat a >b; то a открывает cat, запущенный от рута, а b -- твой шэлл, поскольку это перенаправление в shell.
Файл в /dev создаёт udev, он жэ и права ему назначает. Есть, правда, свойство uevent DEVMODE, которое позволяет драйверу указать mode (по умолчанию), но это, по большому счёту, не принято (по сути им только /dev/zero, /dev/random, /dev/tty пользуются). А так -- пишы GROUP и MODE в правилах udev. Кстати, у него сейчас работает нигде не описанная эвристика (нахера они её написали, если незадокументировали?) -- что если не ставишь ни GROUP ни MODE, то MODE по умолчанию 0600, а если указал GROUP без MODE -- то MODE ужэ станет 0660. Но лучшэ не выпендриваться, и задавать что надо самому.
Нет, нету. Обычно, если ты хочешь просто strerror() -- то оно и пользовательским кодом или strace замечательно напечатается, просто верни ошыбку. А если ты пишэшь это в логи ядра -- то тебе нужно что-то заметно более информативное, чем strerror(). Ну, в крайнем случае, если возврат ошыбки не вариант, а у тебя что-то есть -- напишы %d, администратор не идиот, разберётся. |
Автор: tzirechnoy 30.1.2015, 12:29 | ||||
Я обычно делаю sudo sh -c 'cat "$0" >"$1"' a b или как-то так. Впрочем, вариантов, разумеется, масса -- какой-нибудь, например, pv или tee через sudo, который сам открывает выходной файл, или просто sudo sh и дальшэ делать всё, что хочешь.
udev -- это не ядро. (всё собираюсь мигрировать на hotplug2, поскольку udev всё большэ bloated и насыщен такими внезапными приколами). |
Автор: konshyn 30.1.2015, 12:42 | ||||
tee вполне подходит, спасибо
я пока во всем этом, мягко говоря, не разбираюсь, поэтому дельных комментариев сказать не могу:) |
Автор: konshyn 30.1.2015, 13:03 |
В /proc я создаю через proc_create() создаю несколько файлов. В эту самую функцию требуется struct file_operations, я определяю только функцию чтения. Для каждого файла у меня своя структура и соответственно своя функция чтения. Хочется при создании трех файлов отправлять всем одинаковую структуру ( а не создавать три разные) с одной функцией чтения, а для этого нужно как-то в функции чтения различать, какой файл открыт, желательно что-то наподобии дескрипторов (например, в /dev я могу различать все по major и minor). В функцию чтения передается struct file. Какие там поля могут мне помочь в этом, или как вообще делают создание нескольких файлов в одном модуле? |
Автор: tzirechnoy 30.1.2015, 13:23 |
inode Но конкретно с /proc не знаю -- получится ли у тебя его соотнести с чем-то. Добавлено через 9 минут и 17 секунд Впрочем, посмотрел -- вроде офицыальный путь -- proc_create_data (последний параметр -- свой указатель), затем PDE_DATA(inode) на пришэдшэе в .open в file_ops. |
Автор: konshyn 30.1.2015, 15:11 | ||||
не могу найти это. например, в структуре file есть поле private_data - туда можно запихнуть указатель на данные. но я так и не понял, как через inode я могу отличить файлы в /proc, хотя с устройствами в /dev все легко и понятно Добавлено @ 15:23 Все, нашел. Можно узнать имя файла в .open из структуры file->f_dentry
|
Автор: tzirechnoy 30.1.2015, 16:06 | ||
(стырену у нормальных людей) |
Автор: konshyn 30.1.2015, 16:11 |
а в чем разница этого кода и того, что я сделал (через указатель на данные?) А проблема была вообще в том, чтобы различить файлы при открытии. В коде я этого не увидел, или просто слепой) |
Автор: tzirechnoy 30.1.2015, 16:47 | ||
Указатель на данные -- это нормально, а вот в том, что d_iname там всегда будет тожэ самое, а не изнасилованное каким-нибудь unionfs или ещё как просранное -- я бы не очень надеялся. Вот в номере inode можно быть более-менее уверенным (в смысле -- что он будет такой жэ, как вернулся в proc_create). В том, что если этот proc_create_data скомпилируется, то будет делать именно то, что нужно -- тожэ. А d_iname не выглядит стабильной вещью. |
Автор: konshyn 30.1.2015, 17:55 | ||
Жаль, что я не понимаю, что такое unionfs и как он может покалечить имя файла |
Автор: konshyn 1.2.2015, 21:05 | ||
Разбираюсь с системным таймером. Есть такое определение
Но когда я его вывожу, то выводится значение 250 ну и переменная jiffies увеличивается на 250. Перерыл весь каталог "../include/linux/*" grep'ом - ничего похожего на HZ = 250 не нашел, только определение в 1000. Как так выходит? И откуда берется тогда эта переменная? |
Автор: konshyn 2.2.2015, 00:14 | ||
Не могу понять, как сделать cross компиляцию. У меня есть Makefile
как сделать так, чтобы при опции CROSS_COMPILE (make CROSS_COMPILE=/path_to_cimpiler) у меня компилировалось под версию компилятора? |
Автор: tzirechnoy 2.2.2015, 05:59 |
Чаще всего HZ берётся из CONFIG_HZ. Как Вы не нашли пяток взаимоисключающих определений -- не понимаю. rgrep 'define.*HZ' выводит достаточно интересного. Но, по факту, во времена HPET само наличие HZ -- очень системнозависимая штука. Добавлено через 5 минут и 20 секунд 1) Кроме CROSS_COMPILE -- надо задавать ещё и ARCH 2) CROSS_COMPILE -- это не совсем /path/to/compiler. Это префикс. То есть под путём обычно понимается полный путь, включая имя бинарника CROSS_COMPILE -- это не полный путь к gcc, это путь к gcc без слова gcc. Ну и, там должэн лежать не только компилер... Ну, как минимум, gcc и binutils. А, вот, нашёл в Makefile: as, ld, gcc, ar, nm, strip, objcopy, objdump. Кстати, ничего сложного нет в том, чтобы открыть Makefile и посмотреть. |
Автор: tzirechnoy 2.2.2015, 06:15 |
А, ещё забыл совсем: если вопрос в передаче CROSS_COMPILE и ARCH в make -- то у make есть команда export. |
Автор: konshyn 2.2.2015, 17:49 | ||||||||
Не там искал немного. Вы правы, есть #define CONFIG_HZ 250, но так и не нашел, где происходит переопределение самой HZ, только код
С таймерами более-менее понятно. Особенно что будет, если выгрузить модуль и запущенный таймер с его обработчиком не остановить :(
Да, пока разбирался, понял Но я компилирую модуль не вручную, а через систему kbuild.
только какой Makefile? |
Автор: tzirechnoy 2.2.2015, 23:03 | ||||
Введите rgrep 'define *HZ' в исходниках ядра -- одна из строчек будет ответом. Но да, оно ещё и системно-зависимое.
Ядра линукса. PS И нет, я не знаю, как передать архитектуру через kbuild. |
Автор: konshyn 3.2.2015, 11:16 |
Я не уверен, но все работает, если я просто в Makefile пишу так $(MAKE) Что значит системно-зависимое? Насколько я почитал а Роберта Лава, то HZ определен везде, только на разных архитектурах по-разному, в зависимости от возможностей. И где-то есть дополнительные методы для лучшей точности таймера, счетчик тиков, например. И если посмотреть на определения функций различных таймеров, то все они требуют аргументы именно тиков - значение в будущем, при котором должен сработать таймер. Т.е. в принципе неважно, как работает таймер, т.к. высокоуровневые функции все делают за нас. |
Автор: tzirechnoy 17.2.2015, 12:08 | ||
С тех пор времена изменились, и появилась опцыя CONFIG_NO_HZ. |
Автор: konshyn 3.6.2015, 17:29 | ||
Пытаюсь поймать usb-клавиатуру от Logitech. (Id продукта {0xc31d}) вот код
И этот драйвер почему-то не выводит ID_VENDOR и ID_PRODUCT. Значит он не может поймать устройство. Хотя в логах основной драйвер пишет, что клавиатура подключена и id vender и id product совпадают с теми, что я написал. Напрашивается вопрос: че делать? ![]() |
Автор: konshyn 3.6.2015, 19:27 |
Как определить, какой драйвер управляет клавиатурой? |
Автор: Olej 22.12.2016, 15:42 | ||
http://mylinuxprog.blogspot.com/2015/02/linux-kernel_25.html |