Comments 28
Ещё хуже то, что система заваливается в неопределённом неустойчивом состоянии, и существует конечная (не высокая) вероятность того, что система не восстановится и после перезагрузки.
Простите, а что имеется в виду???
Я не могу вам рассказать абсолютно конкретно, но несколько (2-3) раз попадал в такую ситуацию
Это всё равно что вы вырубаете питание рубильником. Если система что-то пишет в это время на диск, сохраняет какие-то состояния и конфигурации, то после такого вырубания (без сброса кэшей на диск и т.п.) то, что там будет — непредсказуемо.
Это всё равно что вы вырубаете питание рубильником. Если система что-то пишет в это время на диск, сохраняет какие-то состояния и конфигурации, то после такого вырубания (без сброса кэшей на диск и т.п.) то, что там будет — непредсказуемо.
А, фух… Обычный fsck лечит ;) я уж думал все, неизлечимо ;)
Ну, файловые системы вообще-то обещают переживать отключение питания (пусть и с небольшой потерей данных, но без потери консистентности).
Показанная техника расширяет спектр возможностей автора модуля ядра на порядки!
… одновременно сужая диапазон номеров версий ядра, на которых модуль сможет работать.
Это абсолютно неверно, что я постараюсь показать в следующих частях. Как раз к используемым версиям ядра и обновлениям описываемая техника не имееет никакой корреляции.
Даже интересно, как вы защититесь от изменений API, изменений прототипов и семантики функций?
Кончно же что-то типа:
Или вы знаете другой способ?
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
Или вы знаете другой способ?
Или вы знаете другой способ?
Знаю: заслать драйвер в ядро и добиться его включения.
Знаю:
Это не решение, а так… отговорка:
1. «засланные» модули все пестрят LINUX_VERSION_CODE — как поле брани телами погибших…
2. это хороший совет, когда вы пишете код… ночами и на коленке, в порядке хобби… удовлетворения либидо; если же это промышленный проект, выполняемый в рамках штатнго расписаия, то на это никто не даст разрешения, да и времени на это нет;
3. и тем более, если это какая-то частная, специальная разработка, и вовсе даже не драйвер (в традиционном смысле), а модуль… некоторых «специальных эффектов», который для команды ядра представлять интереса не может, потому что просто не стыкуется с их философией.
1. «засланные» модули все пестрят LINUX_VERSION_CODE — как поле брани телами погибших…
Ну неправда же. Если драйвер пишут с нуля или портируют с прицелом на мэйнлайн, то там всё вылизано. Если нет — мейнтейнер обязательно потыкает в очевидное носом. Так бывает когда разработчик сидит 10 лет на своих исходниках, а потом решает их опубликовать. Но тогда им дорога в staging.
2. это хороший совет, когда вы пишете код… ночами и на коленке, в порядке хобби… удовлетворения либидо; если же это промышленный проект, выполняемый в рамках штатнго расписаия, то на это никто не даст разрешения, да и времени на это нет;
Да нет, просто есть такие компании, которые делают свою работу хорошо, а есть такие, которые осознанно забивают, делают кое-как, либо вообще не считают поддержку драйвера своей работой.
Если «никто не даст разрешения» и «нет времени», то в результате вообще получится одно ядро на котором всё работает, и попытка его обновить, скорее всего, принесёт немало сюрпризов.
Ну неправда же.
Ну, здесь я увлёкся и неправ.
Имел в виду великое множество проектов, совершенно открытых и свободных, которые годами сопровождают свои изделия, и которыми пользуется весь мир:
— чипы Broadcom
— чипы Ralink для WiFi
— проект Zaptel/DAHDI, который является интерфейсом к десяткам моделей разнородного оборудования и единственным интерфейсом, используемым всеми софтверными PBX: Asterisk, FreeSWITCH, YATE; но это вообще не драйвер в общепринятом смысле — там ведётся активная обработка потока в режиме ядра, например, нижний уровень сигнализации SS7.
Это только малая часть, названная только для того, чтобы было понятно о чём речь. Все они прекрасно справляются с поддержкой своих проектов ещё с версии ядра даже 2.4, используя LINUX_VERSION_CODE.
Это не говоря уже про проприетарые или полу-проприетарные проекты, которые имеют точно такое же право быть:
— VirtualBox
— NVIDIA со своими драйверами и поддержкой CUDA.
Идея всеобщего глобализма и затея объеденить под крышкой дерева исходных кодов ядра все вообще в природе устройства, протоколы… и вообще любые затеи, меня лично, не греет. Не верю я в идеи всеобщего глобального счастья.
И закончим на этом, потому что публикация и обсуждение совершенно о другом.
заслать драйвер в ядро и добиться его включения.
Это как-раз и есть расплата за монолитность ядра в противовес микроядерному, о чём так увлечённо спорили Торвальдс с Таненбаумом. Но эта тема уведёт нас слишком далеко… от моих, по крайней мере, намерений.
Сам подход, конечно, верный, но если нужно использовать что-то, что не экспортировано ядром, то скорее всего где-то что-то неверно в архитектуре разрабатываемого модуля. Взять ваши примеры — ну зачем могут понадобиться файловые операции из ядра? Есть, ведь, вполне таки экспортированные интерфейсы того же /proc и т.д. Плюс — теряется совместимость между разными версиями ядра, она часто теряется и с обычными функциями, не говоря уже о неэкспортированных.
В общем, статья полезная, но я считаю, что подобных ситуаций нужно избегать.
В общем, статья полезная, но я считаю, что подобных ситуаций нужно избегать.
Вы спешите…
Если бы вы были чуть проницательнее, ил читали чуть размереннее и внимательнее, то заподозрили бы, что меня интересует, в подавляющем большинстве случаев, sys_call_table.
Спешите…
Зачем?
Ну, например, для чтения своих конфигурационных параметров из /etc/…, или записи некоторых специфических логов.
Объясните (смоделируйте, опишите ситуацию) почему прототипы неэкспортируемых функций, например, должны меняться чаще, чем экспортируемых… только конкретно, на примерах, без… «из сображений банальной эрудиции»…
Если бы вы были чуть проницательнее, ил читали чуть размереннее и внимательнее, то заподозрили бы, что меня интересует, в подавляющем большинстве случаев, sys_call_table.
Спешите…
ну зачем могут понадобиться файловые операции из ядра?
Зачем?
Ну, например, для чтения своих конфигурационных параметров из /etc/…, или записи некоторых специфических логов.
Плюс — теряется совместимость между разными версиями ядра,
Объясните (смоделируйте, опишите ситуацию) почему прототипы неэкспортируемых функций, например, должны меняться чаще, чем экспортируемых… только конкретно, на примерах, без… «из сображений банальной эрудиции»…
Объясните (смоделируйте, опишите ситуацию) почему прототипы неэкспортируемых функций, например, должны меняться чаще, чем экспортируемых… только конкретно, на примерах, без… «из сображений банальной эрудиции»…
Потому что прототипы меняются, чаще всего, когда кто-то делает рефакторинг (или переписывает всё). Тот, кто делает рефакторинг видит экспортированные функции и знает, что кроме модулей входящих в состав ядра, могут быть и внешние модули. И даже это его в большинстве случаев не остановит от того, чтобы поменять прототип или семантику. С неэкспортируемыми функциями вообще никто не парится.
Вот официальная политика ядра: www.kernel.org/doc/Documentation/stable_api_nonsense.txt
И на вопрос «что делать, чтобы модуль не ломался с каждой новой версией ядра» она даёт ответ: «Simple, get your kernel driver into the main kernel tree.… If your driver is in the tree, and a kernel interface changes, it will be fixed up by the person who did the kernel change in the first place. This ensures that your driver is always buildable, and works over time, with very little effort on your part.».
Потому что прототипы меняются, чаще всего, когда кто-то делает рефакторинг (или переписывает всё). Тот, кто делает рефакторинг видит экспортированные функции и знает, что кроме модулей входящих в состав ядра, могут быть и внешние модули.
Это всё сображения «с точки зрения банальной эрудиции»… может быть, а может и не быть…
Но опыт показывает, что API экспортируемых функций меняется произвольно, и часто, и даже чаще, чем многие не экспортируемые. А чтобы мои утверждения не выглядели так же голословно (может быть, а может и не быть) я приведу некоторые (на самом дел их гораздо больше), из самых последних:
— версия 3.9 — меняется API WiFi
— версия 3.12 — меняется полостью API драйверов блочных устройств;
— версия 3.15 — меняется весь API, отвечающий за работу poll, select;
— версия 3.17 — меняется API сетевого стека;
— версия 3.17 — снова меняется API WiFi
Это не изменения в реализации названных подсистем. Это изменения в экспортируемых API, которые делают модули, работающие до сих пор с этими подсистемами, не компилирующимися.
Конфиг файл модуля, который будет читаться непосредственно из модуля? В жизни такого не видел.
По поводу второго — ниже коммент, я с ним согласен.
По поводу второго — ниже коммент, я с ним согласен.
Конфиг файл модуля, который будет читаться непосредственно из модуля? В жизни такого не видел.
Не видел — это не обязательно означает, что такое невозможно.
Да, именно поэтому там знак вопроса :) Можете привести пример, когда штатного modprobe, /proc и т.д. недостаточно, и нужно прибегать к использованию конфига, который читается из модуля ядра?
Можете привести пример, когда штатного modprobe, /proc и т.д.
Ну, например, когда в ядре 3.10 все модули, использующие API procfs (описанный во всех книгах, LDD3 и т.д. и т.п.) единомоментно перестали компилироваться «на дух» ;-).
А вообще… Мне довольно часто приходилось кого-то чему-то обучать (хотя никогда штатным преподавателем не был). И за многие годы такой практики я выработал такое правило: в программировании (любом!) самое бессмысленное занятие — спрашивать «зачем», единственный осмысленный вопрос — «как». Это касается любых аспектов: языков программирования, трюков на этих языках… и всё-всё-всё: если какая-то фича тебе не нравится — не используй.
Как там говорилось?:
— Что-то меня беспокоит Гондурас!
— Беспокоит? А ты его не чеши…
Зачем вам syscall table? filp_open, vfs_read уже не в моде?
Я применял kallsyms_lookup_name только когда писал модуль установки HW WP на уровне ядра(на то время такого финта не существовало, да и сейчас скорее всего нет такой фишки). Другого применения не вижу.
Я применял kallsyms_lookup_name только когда писал модуль установки HW WP на уровне ядра(на то время такого финта не существовало, да и сейчас скорее всего нет такой фишки). Другого применения не вижу.
В дополнение к тексту… нужны, как кажется по комментариям, некоторые дополнения, которые не включались в текст из нежелания раздувать и так немалый объём для короткой заметки.
Необходимость кодирования для ядра Linux возникает у программистов 2-х категорий: а). коммитеров, добавляющих (пытающихся) свои коммиты в дерево кодов ядра и б). разработчики автономных проектов, в рамках которых возникают опросы создания модулей ядра (или драйверов, как их простейшей формы). Но коммитеры предпочитают статические изменения в ядре, которые вносятся патчем с последующей сборкой ядра. Меня же интересовали, главным образом, потребности практикующих разработчики, которым требуется динамически внести изменения в функционирование отдельных ветвей ядра (сетевые протоколы, например).
Я не хочу обсуждать здесь вопрос зачем. Сконцентрируемся на вопроса как. Некоторую ясность в вопрос зачем добавят, возможно и не сняв его полностью, последующие части бсуждения (не зря в заголовке написано: часть 1).
Очень много попутных вопросов-ответов, аргументов-возражений и т.д. обкатывались на протяжении последих лет 5-ти в темах, обсуждаемых а форуме Linux изнутри. Я не могу все их обсудить ни в комментариях ни в тексте, но их намётки можно найти в этом форуме. Кроме того, итогом почти 10-ти летней работы с модулями вылились в учебный курс, выполенный на заказ, и тренинги по которому были проведен с 5-ю различными группами (в разных городах-филиалах) разработчиков одной из крупнейших международных софтверных компаний. Полный текст (>400 страниц) и архив из доброй сотни модулей для самых разнообразных случаев можно свободно взять (всё под лицензий Creative Commons Attribution ShareAlike) в моём блоге: Практикум по Linux Kernel.
Вот такое пространное объяснение мне показалось необходимым к тому, чтобы в комментариях мы обсуждали только вещи, относящиеся к публикации. Просто потому что:
(с) Козьма Прутков.
Необходимость кодирования для ядра Linux возникает у программистов 2-х категорий: а). коммитеров, добавляющих (пытающихся) свои коммиты в дерево кодов ядра и б). разработчики автономных проектов, в рамках которых возникают опросы создания модулей ядра (или драйверов, как их простейшей формы). Но коммитеры предпочитают статические изменения в ядре, которые вносятся патчем с последующей сборкой ядра. Меня же интересовали, главным образом, потребности практикующих разработчики, которым требуется динамически внести изменения в функционирование отдельных ветвей ядра (сетевые протоколы, например).
Я не хочу обсуждать здесь вопрос зачем. Сконцентрируемся на вопроса как. Некоторую ясность в вопрос зачем добавят, возможно и не сняв его полностью, последующие части бсуждения (не зря в заголовке написано: часть 1).
Очень много попутных вопросов-ответов, аргументов-возражений и т.д. обкатывались на протяжении последих лет 5-ти в темах, обсуждаемых а форуме Linux изнутри. Я не могу все их обсудить ни в комментариях ни в тексте, но их намётки можно найти в этом форуме. Кроме того, итогом почти 10-ти летней работы с модулями вылились в учебный курс, выполенный на заказ, и тренинги по которому были проведен с 5-ю различными группами (в разных городах-филиалах) разработчиков одной из крупнейших международных софтверных компаний. Полный текст (>400 страниц) и архив из доброй сотни модулей для самых разнообразных случаев можно свободно взять (всё под лицензий Creative Commons Attribution ShareAlike) в моём блоге: Практикум по Linux Kernel.
Вот такое пространное объяснение мне показалось необходимым к тому, чтобы в комментариях мы обсуждали только вещи, относящиеся к публикации. Просто потому что:
Нельзя объять необъятное.
(с) Козьма Прутков.
Огромное спасибо. Теперь не надо копипастой заниматься
Sign up to leave a comment.
Делаем доступным все символы ядра Linux. Часть 1