Драйвер сетевой карты
Всем привет. Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;) Пока оттолкнуться можно от http://linuxgazette.net/156/jangir.html, http://linuxportal.ru/entry.php/2622_0_3_0_C/ и http://dmilvdv.narod.ru/Translate/index.html - Linux Device Drivers, Third Edition (LDD3) на русском языке С уважением, Alex
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Пока оттолкнуться можно от http://linuxgazette.net/156/jangir.html, http://linuxportal.ru/entry.php/2622_0_3_0_C/ и http://dmilvdv.narod.ru/Translate/index.html - Linux Device Drivers, Third Edition (LDD3) на русском языке
С уважением, Alex
Предлагаю начать с драйвера для сетевых карт AMD PCNet-PCI II и PCNet-PCI III. Разобраться в работе этой карточки просто и она эмулируется большинством эмуляторов/ВМ. Ведь учиться писать драйвер на реальной машине проблематично, довольно часто работа нестабильного драйвера приводит к kernel panic, из-за чего приходится перезапускать машину. В письме оставлю ссылки на необходимую документацию. В атаче находится рабочий прототип драйвера, написанный мной, но имеет ряд недостатков: - написан только для x86 и не предусматривает ни x86_64, ни модели памяти big-endian. - работает в 2-3 раза медленнее, чем оригинальный драйвер ядра. - написан коряво =) Но как будем писать драйвер? полностью с нуля или пытаться довести до ума приложенный в атаче? -- [Литература] -- pcnet.txt в атаче содержит мои наброски в то время, когда я писал этот драйвер. Много важных моментов я не успел там помянуть, но все же он будет полезен. pcnet.c - сам драйвер PCnet Family Software Design Considerations (основная документация): http://www.nalanda.nitc.ac.in/industry/AppNotes/AMD/19669.pdf PCNet-PCI II datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf Можно поискать документацию по продуктам AMD: http://www.nalanda.nitc.ac.in/industry/AppNotes/AMD/Index.html#m4 А также незаменимая книжка "Linux. Сетевая архитектура. Структура и реализация сетевых протоколов я ядре", которую в электронном виде найти невозможно.
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Пока оттолкнуться можно от http://linuxgazette.net/156/jangir.html, http://linuxportal.ru/entry.php/2622_0_3_0_C/ и http://dmilvdv.narod.ru/Translate/index.html - Linux Device Drivers, Third Edition (LDD3) на русском языке
С уважением, Alex
Предлагаю начать с драйвера для сетевых карт AMD PCNet-PCI II и PCNet-PCI III. Разобраться в работе этой карточки просто и она эмулируется большинством эмуляторов/ВМ. Ведь учиться писать драйвер на реальной машине проблематично, довольно часто работа нестабильного драйвера приводит к kernel panic, из-за чего приходится перезапускать машину.
В Sun, 12 Sep 2010 19:47:33 +0300 Dmitry Podgorny <pasis.ua@gmail.com> пишет:
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Пока оттолкнуться можно от http://linuxgazette.net/156/jangir.html, http://linuxportal.ru/entry.php/2622_0_3_0_C/ и http://dmilvdv.narod.ru/Translate/index.html - Linux Device Drivers, Third Edition (LDD3) на русском языке
С уважением, Alex
Предлагаю начать с драйвера для сетевых карт AMD PCNet-PCI II и PCNet-PCI III. Разобраться в работе этой карточки просто и она эмулируется большинством эмуляторов/ВМ. Ведь учиться писать драйвер на реальной машине проблематично, довольно часто работа нестабильного драйвера приводит к kernel panic, из-за чего приходится перезапускать машину.
Литература: pcnet.txt в атаче содержит мои наброски в то время, когда я писал этот драйвер. Много важных моментов я не успел там помянуть, но все же он будет полезен. PCnet Family Software Design Considerations (основная документация): http://www.nalanda.nitc.ac.in/industry/AppNotes/AMD/19669.pdf PCNet-PCI II datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf Можно поискать документацию по продуктам AMD: http://www.nalanda.nitc.ac.in/industry/AppNotes/AMD/Index.html#m4 Конкретные реализации драйвера можно посмотреть в ядре Linux и в Plan9 А также незаменимая книжка "Linux. Сетевая архитектура. Структура и реализация сетевых протоколов я ядре", которую в электронном виде найти невозможно.
В Sun, 12 Sep 2010 19:47:33 +0300 Dmitry Podgorny <pasis.ua@gmail.com> пишет:
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Пока оттолкнуться можно от http://linuxgazette.net/156/jangir.html, http://linuxportal.ru/entry.php/2622_0_3_0_C/ и http://dmilvdv.narod.ru/Translate/index.html - Linux Device Drivers, Third Edition (LDD3) на русском языке
С уважением, Alex
Предлагаю начать с драйвера для сетевых карт AMD PCNet-PCI II и PCNet-PCI III. Разобраться в работе этой карточки просто и она эмулируется большинством эмуляторов/ВМ. Ведь учиться писать драйвер на реальной машине проблематично, довольно часто работа нестабильного драйвера приводит к kernel panic, из-за чего приходится перезапускать машину.
В атаче находится рабочий прототип драйвера, написанный мной, но имеет ряд недостатков: - написан только для x86 и не предусматривает ни x86_64, ни модели памяти big-endian. - работает в 2-3 раза медленнее, чем оригинальный драйвер ядра. - написан коряво =) Я так понимаю, что лучше начать писать драйвер с нуля, с описанием всех шагов? И может использовать контроль версий, чтобы побольше пользователей смогли подключиться к процессу?
Am Sun 12 Sep 2010 07:08:49 PM CEST schrieb Dmitry Podgorny <pasis.ua@gmail.com>:
Я так понимаю, что лучше начать писать драйвер с нуля, с описанием всех шагов? И может использовать контроль версий, чтобы побольше пользователей смогли подключиться к процессу?
Да, я думаю, что начать лучше с описанием всех шагов, (предварительно подкрепившись терией) -- Alexander Naumov, KDE Developer
В Sun, 12 Sep 2010 19:47:33 +0300 Dmitry Podgorny <pasis.ua@gmail.com> пишет:
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Какие грабли сразу ждут во время написании драйвера: 1. В ядре часто меняются структуры. Я писал драйвер на 2.6.29, а проверял в qemu с ядром 2.6.27. При чем в этих двух ядрах уже были несоответствия. Приходилось через #ifdef для разных версий использовать разные поля структур. Все это можно посмотреть в исходнике (pcnet.c). Так что нужно быть готовому к тому, что литература может не соответствовать действительности и нужно будет разбираться в заголовочных файлах, что же там изменилось. 2. Долгое время у меня ушло на то, чтобы разобраться с чтением/записью регистров BCR. То ли в литературе смутно описан процесс, то ли я что-то путаю =). Как бы там ни было, функции чтения/записи уже есть в исходнике. 3. Нужно не забывать о порядке битов и использовать функции преобразования hton[sl]() и ntoh[sl](). 4. Были еще проблемы, но о них, когда вспомню.
я предлагаю использовать github для хостинга сорцов. нужен еще какой-нибудь способ распространения изменений (в основном для ревью) для гипотетического драйвера. On 9/13/10, Dmitry Podgorny <pasis.ua@gmail.com> wrote:
В Sun, 12 Sep 2010 19:47:33 +0300 Dmitry Podgorny <pasis.ua@gmail.com> пишет:
В Sun, 12 Sep 2010 16:45:17 +0200 Alex Naumov <posix.ru@googlemail.com> пишет:
Всем привет.
Есть идея написать простейший драйвер для сетевой карты. Если кого интересует, присоединяйтесь к обсуждению ;)
Какие грабли сразу ждут во время написании драйвера: 1. В ядре часто меняются структуры. Я писал драйвер на 2.6.29, а проверял в qemu с ядром 2.6.27. При чем в этих двух ядрах уже были несоответствия. Приходилось через #ifdef для разных версий использовать разные поля структур. Все это можно посмотреть в исходнике (pcnet.c). Так что нужно быть готовому к тому, что литература может не соответствовать действительности и нужно будет разбираться в заголовочных файлах, что же там изменилось. 2. Долгое время у меня ушло на то, чтобы разобраться с чтением/записью регистров BCR. То ли в литературе смутно описан процесс, то ли я что-то путаю =). Как бы там ни было, функции чтения/записи уже есть в исходнике. 3. Нужно не забывать о порядке битов и использовать функции преобразования hton[sl]() и ntoh[sl](). 4. Были еще проблемы, но о них, когда вспомню.
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
С github согласен, в течение нескольких дней начну заново писать, зарегистрирую там репозитарий и сообщу об этом в рассылке. Думаю, нужно будет на форуме создать тему, так как на рассылку подписано мало человек. А вот насчет распространения изменений на ум приходит пока что только rss самого github (если есть такая возможность); или оповещать о ключевых моментах через рассылку, а уже изменения смотреть в патчах или на самом github. Походу данный вопрос остается открытым. В Mon, 13 Sep 2010 19:58:12 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
я предлагаю использовать github для хостинга сорцов. нужен еще какой-нибудь способ распространения изменений (в основном для ревью) для гипотетического драйвера.
2010/9/13 Dmitry Podgorny <pasis.ua@gmail.com>
С github согласен, в течение нескольких дней начну заново писать, зарегистрирую там репозитарий и сообщу об этом в рассылке.
Да, хорошая идея.
Думаю, нужно будет на форуме создать тему, так как на рассылку подписано мало человек.
Форум в твоем распоряжении.
А вот насчет распространения изменений на ум приходит пока что только rss самого github (если есть такая возможность); или оповещать о ключевых моментах через рассылку, а уже изменения смотреть в патчах или на самом github. Походу данный вопрос остается открытым.
Думаю, что changelog и _подробное_ описание в рассылке самое то. Хотя если что будет не понятно, то спросить всегда можно ;)
В Mon, 13 Sep 2010 19:58:12 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
я предлагаю использовать github для хостинга сорцов. нужен еще какой-нибудь способ распространения изменений (в основном для ревью) для гипотетического драйвера.
Репозитарий зарегистрирован http://github.com/pasis/pcnet-driver/. Сразу приведу ссылку, чтобы слить: git://github.com/pasis/pcnet-driver.git Первым делом написал простейший модуль ядра, далее планирую написать регистрацию PCI драйвера, определение модели карточки, добычу MAC-адреса и т.д. Вобщем, от простых шагов к более комплексному виду. Еще у меня есть вопрос: В документации по написанию модулей нету #define MODULE вначале исходника. А если посмотреть в <linux/module.h> и <linux/init.h>, то можно прийти к выводу, что объявлять MODULE нужно перед включением заголовочных файлов. Так этот MODULE объявляется через параметры gcc или откуда вообще берется, раз в примерах его нет? P.S. Буду рад любой помощи и критике моих не прямолинейных конечностей.
@Забыл подписать kernel-russian :/ AFAIK теперь это не нужно. Все определяется/скрыто/инкапсулировано(как угодно) в module_(init|exit) и тегах __init __exit etc 2010/9/14 Dmitry Podgorny <pasis.ua@gmail.com>:
В Mon, 13 Sep 2010 19:58:12 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
я предлагаю использовать github для хостинга сорцов. нужен еще какой-нибудь способ распространения изменений (в основном для ревью) для гипотетического драйвера.
Репозитарий зарегистрирован http://github.com/pasis/pcnet-driver/. Сразу приведу ссылку, чтобы слить: git://github.com/pasis/pcnet-driver.git
Первым делом написал простейший модуль ядра, далее планирую написать регистрацию PCI драйвера, определение модели карточки, добычу MAC-адреса и т.д. Вобщем, от простых шагов к более комплексному виду.
Еще у меня есть вопрос: В документации по написанию модулей нету #define MODULE вначале исходника. А если посмотреть в <linux/module.h> и <linux/init.h>, то можно прийти к выводу, что объявлять MODULE нужно перед включением заголовочных файлов. Так этот MODULE объявляется через параметры gcc или откуда вообще берется, раз в примерах его нет?
P.S. Буду рад любой помощи и критике моих не прямолинейных конечностей.
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
Dmitry, хотел задать вопрос про HAVE_NET_DEVICE_OPS в недавнем коммите. Текущие драйверы не должны проверять это явно. PS: попрошу еще раз присылать патчи в mailing list для ревью остальными участниками. Thanks. 2010/9/14 Denis Kirjanov <kirjanov@gmail.com>:
@Забыл подписать kernel-russian :/ AFAIK теперь это не нужно. Все определяется/скрыто/инкапсулировано(как угодно) в module_(init|exit) и тегах __init __exit etc
2010/9/14 Dmitry Podgorny <pasis.ua@gmail.com>:
В Mon, 13 Sep 2010 19:58:12 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
я предлагаю использовать github для хостинга сорцов. нужен еще какой-нибудь способ распространения изменений (в основном для ревью) для гипотетического драйвера.
Репозитарий зарегистрирован http://github.com/pasis/pcnet-driver/. Сразу приведу ссылку, чтобы слить: git://github.com/pasis/pcnet-driver.git
Первым делом написал простейший модуль ядра, далее планирую написать регистрацию PCI драйвера, определение модели карточки, добычу MAC-адреса и т.д. Вобщем, от простых шагов к более комплексному виду.
Еще у меня есть вопрос: В документации по написанию модулей нету #define MODULE вначале исходника. А если посмотреть в <linux/module.h> и <linux/init.h>, то можно прийти к выводу, что объявлять MODULE нужно перед включением заголовочных файлов. Так этот MODULE объявляется через параметры gcc или откуда вообще берется, раз в примерах его нет?
P.S. Буду рад любой помощи и критике моих не прямолинейных конечностей.
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
-- Regards, Denis
В Sun, 19 Sep 2010 17:30:10 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Dmitry, хотел задать вопрос про HAVE_NET_DEVICE_OPS в недавнем коммите. Текущие драйверы не должны проверять это явно.
Т.е. для этого существует другой путь, вместо прямого присвоения полям структуры net_device? Потому что я планирую для тестирования использовать ядро 2.6.27, где net_device_ops еще нет.
PS: попрошу еще раз присылать патчи в mailing list для ревью остальными участниками.
Thanks.
Прошу прощения, еще не успел разобраться с git send-email. Следующий коммит уже будет здесь :).
Доброго времени! Я бегло просмотрел докуметацию, и хотел бы обсудить вопрос о DMA. О Initialization block, о формате DMA-дескрипторов etc Если у кого-нибудь есть целостная картина как это работает, то дамп мыслей можно сюда. PS: постараюсь разобраться с этим в ближайшее время. Thanks 2010/9/19 Dmitry Podgorny <pasis.ua@gmail.com>:
В Sun, 19 Sep 2010 17:30:10 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Dmitry, хотел задать вопрос про HAVE_NET_DEVICE_OPS в недавнем коммите. Текущие драйверы не должны проверять это явно.
Т.е. для этого существует другой путь, вместо прямого присвоения полям структуры net_device? Потому что я планирую для тестирования использовать ядро 2.6.27, где net_device_ops еще нет.
PS: попрошу еще раз присылать патчи в mailing list для ревью остальными участниками.
Thanks.
Прошу прощения, еще не успел разобраться с git send-email. Следующий коммит уже будет здесь :).
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
Init. block используется, чтобы сконфигурировать регистры. Те же самые данные, что находятся в init. block, можно вбить вручную в регистры (в [1 стр.3] есть список всех этих регистров). Форматы init. block отличаются для 16бит и 32бит режимов, чтобы определить режим в котором работает карточка, можно воспользоваться процедурой из [2 pcnet_check_mode()]. Физический адрес записывается в два 16-битные регистры в CSR1 и CSR2, и затем блок читается контроллером из памяти и устанавливает свои регистры в соответствующие значения. Думаю, чтение init. block происходит при сбросе, но нужно это еще вычитать. DMA-дескрипторы - это дескрипторы приема и передачи для колец? (т.е. то что описано в [1 стр.5-6]). И какие конкретно вопросы о DMA нужно обсудить? Мне, например, не совсем понятно, что делает функция pci_map_single(). [1] PCnet Family Software Design Considerations [2] pcnet.c из первых писем рассылки В Tue, 21 Sep 2010 23:12:17 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Доброго времени!
Я бегло просмотрел докуметацию, и хотел бы обсудить вопрос о DMA. О Initialization block, о формате DMA-дескрипторов etc Если у кого-нибудь есть целостная картина как это работает, то дамп мыслей можно сюда.
PS: постараюсь разобраться с этим в ближайшее время.
Thanks
2010/9/22 Dmitry Podgorny <pasis.ua@gmail.com>:
Init. block используется, чтобы сконфигурировать регистры. Те же самые данные, что находятся в init. block, можно вбить вручную в регистры (в [1 стр.3] есть список всех этих регистров).
Форматы init. block отличаются для 16бит и 32бит режимов, чтобы определить режим в котором работает карточка, можно воспользоваться процедурой из [2 pcnet_check_mode()]. Физический адрес записывается в два 16-битные регистры в CSR1 и CSR2, и затем блок читается контроллером из памяти и устанавливает свои регистры в соответствующие значения. Думаю, чтение init. block происходит при сбросе, но нужно это еще вычитать.
DMA-дескрипторы - это дескрипторы приема и передачи для колец? (т.е. то что описано в [1 стр.5-6]). И какие конкретно вопросы о DMA нужно обсудить? Мне, например, не совсем понятно, что делает функция pci_map_single(). Да, они самые. pc_map_single служит для асинхронного DMA. После вызова этой ф-ии DMA-буфер принадлежит полность устройству ввода-вывода. CPU не должен использовать эту память, пока буфер принадлежит устройству. Для записи данных в устройство буфер должен содержать какие-нибудь данные, после этого вызывается pci_map_. При чтении мы должны получить от устройства прерывание что оно закончило с буфером. После этого можно вызывать pci_unmap_
[1] PCnet Family Software Design Considerations [2] pcnet.c из первых писем рассылки
В Tue, 21 Sep 2010 23:12:17 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Доброго времени!
Я бегло просмотрел докуметацию, и хотел бы обсудить вопрос о DMA. О Initialization block, о формате DMA-дескрипторов etc Если у кого-нибудь есть целостная картина как это работает, то дамп мыслей можно сюда.
PS: постараюсь разобраться с этим в ближайшее время.
Thanks
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
Предлагаю еще обсудить интерфейс доступа к регистрам. До этого я использовал исключительно PIO. Но как я понял из коммита http://github.com/pasis/pcnet-driver/commit/60d4f2b05f0ef5bd3470ab9d71f6cf53... планируется использовать MMIO/PIO. Будем ли реализовывать динамическое переключение между MMIO/PIO или только во время компиляции? А также как реализовывать возможность работы контроллера в 16бит и 32бит режиме? В Tue, 21 Sep 2010 23:12:17 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Доброго времени!
Я бегло просмотрел докуметацию, и хотел бы обсудить вопрос о DMA. О Initialization block, о формате DMA-дескрипторов etc Если у кого-нибудь есть целостная картина как это работает, то дамп мыслей можно сюда.
PS: постараюсь разобраться с этим в ближайшее время.
Thanks
/* 2 * Implement the default iomap interfaces 3 * 4 * (C) Copyright 2004 Linus Torvalds 5 */ 6 #include <linux/pci.h> 7 #include <linux/io.h> 8 9 #include <linux/module.h> 10 11 /* 12 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO 13 * access or a MMIO access, these functions don't care. The info is 14 * encoded in the hardware mapping set up by the mapping functions 15 * (or the cookie itself, depending on implementation and hw). 16 * 17 * The generic routines don't assume any hardware mappings, and just 18 * encode the PIO/MMIO as part of the cookie. They coldly assume that 19 * the MMIO IO mappings are not in the low address range. 20 * 21 * Architectures for which this is not true can't use this generic 22 * implementation and should do their own copy. 2010/9/22 Dmitry Podgorny <pasis.ua@gmail.com>:
Предлагаю еще обсудить интерфейс доступа к регистрам. До этого я использовал исключительно PIO. Но как я понял из коммита http://github.com/pasis/pcnet-driver/commit/60d4f2b05f0ef5bd3470ab9d71f6cf53... планируется использовать MMIO/PIO. Будем ли реализовывать динамическое переключение между MMIO/PIO или только во время компиляции? А также как реализовывать возможность работы контроллера в 16бит и 32бит режиме?
В Tue, 21 Sep 2010 23:12:17 +0400 Denis Kirjanov <kirjanov@gmail.com> пишет:
Доброго времени!
Я бегло просмотрел докуметацию, и хотел бы обсудить вопрос о DMA. О Initialization block, о формате DMA-дескрипторов etc Если у кого-нибудь есть целостная картина как это работает, то дамп мыслей можно сюда.
PS: постараюсь разобраться с этим в ближайшее время.
Thanks
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
-- Regards, Denis
participants (4)
-
Alex Naumov -
Alexander Naumov -
Denis Kirjanov -
Dmitry Podgorny