Offline |
Mentor/Kernel Developer |
 |
Joined: Fri Jun 30, 2006 9:01 am Posts: 1279
|
There is a document written by mike hibbet, let me find it for you.. EDIT: here it is: Writing Network Drivers Under MenuetWriting Network Drivers Under Menuet ====================================
Mike Hibbett,
4th September 2003
Background ==========
The protocol stack is handled in the kernel main loop, os_loop.
All stack code is handled in this loop by a single stack function called stack_handler. This function polls the network driver for received data and calls the IP & TCP processes.
This release of the stack uses a very simple buffer array for IP packets. The array is defined in stack.inc. IPBuffers is an array of NUM_IPBUFFERS entries, each one IPBUFFERSIZE big. Each entry looks like this:
; 0 1 2 3 ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ; ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; |Version| IHL |Type of Service| Total Length | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; | Identification |Flags| Fragment Offset | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; | Time to Live | Protocol | Header Checksum | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; | Source Address | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; | Destination Address | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ; | Data | ; +-+-+-.......... -+
i.e. it is a 'normal' IP packet.
Note: This implementation does not permit the options fields in the IP header to be populated.
The function ethernet_driver first calls eth_rx, which will poll the lower level newtwork driver for data. If a packet is available, it is retrieved and stored in an IP buffer. ethernet_driver then calls eth_tx, which will look through the IPBuffers to see if there is a buffer that is marked for transmission. If there is one, it is passed to the network driver, and immediately transmitted.
Ethernet drivers require a mapping between the IP addresses and the ethernet hardware address (MAC). This is managed by a protocol called ARP. ARP is only visible to the network driver; IP does not care about address resolution.
Driver Requirements ===================
Only PCI bus ethernet hardware is supported currently. This can be plug in cards or motherboard hosted PCI hardware ( as fitted to most laptops )
Driver requirements are very simple.
Menuets ethernet drivers are based on the etherboot projects driver code, which has been written in C. Get a copy of the source files.
I recommend that you examine the files ns8390.c and eepro100.c, which formed the basis of rtl8029.inc and i8255x.inc respectively.
A driver must provide four functions:
drivername_reset drivername_probe drivername_poll drivername_transmit
I recommend that you keep the names of these functions in a similar format to the other drivers, to make it easier for others to read your code.
_reset function =============== Input parameters : I/O address in io_addr PCI bus in pci_bus PCI dev # in pci_dev Output parameters : None
This function should return the card into it's default active state, ready to receive data. It is typically called at the end of hardware initialisation. The function is not currently called externally, but may be in the future.
_probe function ===============
Input parameters : I/O address in io_addr PCI bus in pci_bus PCI dev # in pci_dev Output parameters : MAC address writen to node_addr
This function is called once the hardware's I/O address space is known. The function will completely initialise the hardware, and extract the MAC address. It returns with the hardware activated, awaiting data for transmission or reception. If the _probe function completed successfully, the following two lines should be performed
; Indicate that we have successfully reset the card mov eax, [pci_data] mov [eth_status], eax
_poll function ==============
Input parameters : I/O address in io_addr Output parameters : Received data written to Ether_buffer Number of bytes received written to eth_rx_data_len
This function examines the hardware to see if a data packet has been received. If it has, the data is extracted and stored in the buffer Ether_buffer ( which is globally available, and defined in stack.inc ).
First, ensure that the following lines are executed at the beginning
mov ax, 0 ; assume no data mov [eth_rx_data_len], ax
eth_rx_data_len is used by the upper layer to determine if data was received.
_transmit function ==================
Input parameters : I/O address in io_addr Pointer to MAC address in edi Type of packet ( IP or ARP ) in bx Size of packet in ecx Pointer to packet in esi Output parameters : None ( packet assumed transmitted )
Passes a data packet to the hardware, and waits for it's transmission. The destination address is specified in the call, so this function does not need to worry about address resolution.
Integrating the Driver ======================
Firstly, write you code in a new include file, and give the file a name that identifies the driver, eg 3c509.inc
In ethernet.inc, find the lines:
include "RTL8029.INC" include "I8255X.INC"
which will be near the top. Add your include file hear.
Further down ethernet.inc, find these lines:
PCICards: dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
Add a new line, and fill in your drivers details. The first dword is the PCI bus device and vendor words. These can be found from the etherboot project, which give a list of the PCI values for various card types. You need to find this value before implementing the driver anyway!
That is it. Re-assemble the kernel, copy it to your boot disk and boot. Now when you enable the packet driver, your card will hopefully be detetected and used. You can verify this by running the status application
Hints =====
The etherboot source code relies on some timer functions that are not currently available in menuet. These timers are used for generating timeouts while waiting for the hardware to complete tasks. I have chosen to ignore these for now, and not implement them. So for this has not been a problem, and we will address them at a later stage. Generating short delays can be a problem, and where there is a real need for generating 2 - 10 us delays I have used much larger delays with no problem. We are working on providing an acuurate, small delay facility within menuet.
My approach has been to simply identify the I/O calls within the original source file, and code this in assembler. So far with the two drivers I have implemented this has not been an issue. Email me if you have any questions on your driver.
The etherboot project has been an enormous help, as it means that a detailed understanding of the hardware is not required. I have not needed to refer to the chip specifications on my two implementations.
Notes =====
The driver implementation is polled rather than interrupt based. This slows down transfers but makes driver development very easy. We will address this in the future when I can work out how to use interrupts with the hardware!
I should point out that the way in which network drivers are implemented will be changing soon in preparation for implementing TCP. However the principle will remain largely the same, so if you are considering writing a driver do it now rather than wait!
Any comments/ questions to mikehibbett [@] oceanfree.net translate to russian Написание сетевых драйверов под Menuet ====================================
Майк Хиббетт,
4 сентября 2003 г.
Задний план ==========
Стек протоколов обрабатывается в основном цикле ядра os_loop.
Весь код стека обрабатывается в этом цикле одной функцией стека, называемой stack_handler. Эта функция опрашивает сетевой драйвер на предмет полученных данных и вызывает процессы IP и TCP.
В этом выпуске стека используется очень простой буферный массив для IP-пакетов. В массив определен в stack.inc. IPBuffers - это массив записей NUM_IPBUFFERS, каждый IPBUFFERSIZE большой. Каждая запись выглядит так:
; 0 1 2 3 ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ; ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Версия | МГП | Тип услуги | Общая длина | ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Идентификация | Флаги | Смещение фрагмента | ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Время жить | Протокол | Контрольная сумма заголовка | ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Исходный адрес | ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Адрес назначения | ; + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + ; | Данные | ; + - + - + -.......... - +
т.е. это «нормальный» IP-пакет.
Примечание. Эта реализация не позволяет использовать поля параметров в заголовке IP. быть заселенным.
Функция ethernet_driver сначала вызывает eth_rx, который опрашивает нижний уровень. драйвер newtwork для данных. Если пакет доступен, он извлекается и сохраняется. в буфере IP. ethernet_driver затем вызывает eth_tx, который просматривает IPBuffers, чтобы увидеть, есть ли буфер, помеченный для передачи. Если там единица, она передается сетевому драйверу и сразу же передается.
Драйверы Ethernet требуют сопоставления IP-адресов и Ethernet. аппаратный адрес (MAC). Это управляется протоколом ARP. ARP только виден сетевому драйверу; IP не заботится о разрешении адресов.
Требования к водителю ===================
В настоящее время поддерживается только оборудование Ethernet с шиной PCI. Это можно вставить карты или материнская плата, размещенная на оборудовании PCI (как установлено на большинстве ноутбуков)
Требования к драйверам очень простые.
Драйверы Ethernet Menuets основаны на коде драйвера проектов etherboot, который был написан на C. Получите копию исходных файлов.
Я рекомендую вам изучить файлы ns8390.c и eepro100.c, которые сформировали основа rtl8029.inc и i8255x.inc соответственно.
Драйвер должен обеспечивать четыре функции:
Drivername_reset Drivername_probe Drivername_poll Drivername_transmit
Я рекомендую вам сохранить имена этих функций в формате, аналогичном формату другие драйверы, чтобы другим было легче читать ваш код.
_reset функция =============== Входные параметры: адрес ввода / вывода в io_addr Шина PCI в pci_bus Номер разработчика PCI в pci_dev Выходные параметры: Нет
Эта функция должна вернуть карту в активное состояние по умолчанию, готовое к получать данные. Обычно он вызывается в конце инициализации оборудования. В функция в настоящее время не вызывается извне, но может быть в будущем.
_probe функция ===============
Входные параметры: адрес ввода / вывода в io_addr Шина PCI в pci_bus Номер разработчика PCI в pci_dev Выходные параметры: MAC-адрес записывается в node_addr
Эта функция вызывается, когда становится известно адресное пространство ввода-вывода оборудования. Функция полностью инициализирует оборудование и извлечет MAC. адрес. Он возвращается с активированным оборудованием, ожидая передачи данных. или прием. Если функция _probe завершилась успешно, следующие две строчки должны быть выполнены
; Укажите, что мы успешно сбросили карту mov eax, [pci_data] mov [eth_status], eax
функция _poll ==============
Входные параметры: адрес ввода / вывода в io_addr Выходные параметры: полученные данные записываются в Ether_buffer Количество полученных байтов, записанных в eth_rx_data_len
Эта функция проверяет оборудование, чтобы увидеть, был ли получен пакет данных. Если да, данные извлекаются и сохраняются в буфере Ether_buffer (который доступен глобально и определен в stack.inc).
Сначала убедитесь, что следующие строки выполняются в начале
mov ax, 0; не предполагать никаких данных mov [eth_rx_data_len], топор
eth_rx_data_len используется верхним уровнем, чтобы определить, были ли получены данные.
_transmit функция ==================
Входные параметры: адрес ввода / вывода в io_addr Указатель на MAC-адрес в edi Тип пакета (IP или ARP) в bx Размер пакета в ecx Указатель на пакет в esi Выходные параметры: Нет (предполагается, что пакет передан)
Передает пакет данных оборудованию и ожидает его передачи. В адрес назначения указывается в вызове, поэтому эта функция не требует беспокоиться о разрешении адресов.
Интеграция драйвера ======================
Во-первых, напишите код в новом включаемом файле и дайте файлу имя, которое идентифицирует драйвер, например 3c509.inc
В ethernet.inc найдите строки:
включить "RTL8029.INC" включить "I8255X.INC"
который будет наверху. Добавьте ваш включаемый файл.
Далее по ethernet.inc найдите эти строки:
PCICards: dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
Добавьте новую строку и введите данные о драйверах. Первое двойное слово - PCI устройство шины и слова продавца. Их можно найти в проекте etherboot, которые дают список значений PCI для различных типов карт. Вам нужно в любом случае найдите это значение перед реализацией драйвера!
Вот и все. Соберите ядро заново, скопируйте его на загрузочный диск и загрузитесь. В настоящее время когда вы включите пакетный драйвер, ваша карта, надеюсь, будет обнаружена и использовал. Вы можете проверить это, запустив статусную заявку
Подсказки =====
Исходный код etherboot использует некоторые функции таймера, которые не в настоящее время доступно в menuet. Эти таймеры используются для генерации таймауты при ожидании завершения аппаратным обеспечением задач. Я выбрал пока игнорировать их и не реализовывать. Так что для этого не возникла проблема, и мы рассмотрим ее позже. Создание короткие задержки могут быть проблемой, и там, где есть реальная потребность в генерации Задержки от 2 до 10 мкс. Я без проблем использовал гораздо большие задержки. Мы работает над обеспечением точной, небольшой задержки в меню.
Мой подход заключался в том, чтобы просто идентифицировать вызовы ввода-вывода в исходном исходный файл и запрограммировать его на ассемблере. Пока что с двумя драйверами я реализовали это не было проблемой. Напишите мне, если у вас есть вопросы по вашему драйверу.
Проект etherboot оказал огромную помощь, поскольку он означает, что детального понимания аппаратного обеспечения не требуется. Я не нуждался чтобы сослаться на спецификации микросхем двух моих реализаций.
Ноты =====
Реализация драйвера опрашивается, а не на основе прерывания. Это замедляет понижает трансферы, но делает разработку драйверов очень простой. Мы рассмотрим это в будущем, когда я смогу разобраться, как использовать прерывания с оборудованием!
Следует отметить, что сетевые драйверы Реализованный будет скоро изменен в рамках подготовки к реализации TCP. Однако принцип останется в основном таким же, поэтому, если вы рассматриваете напишите драйвер, сделайте это сейчас, а не ждать!
_________________ "Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction." Albert Einstein
|
|