How to learn network Ethernet device driver programming? - linux

I am looking what piece of hardware should i buy (NIC Or FPGA Or ASIC etc) which i could connect to my system, and write device driver to implement and learn Ethernet device driver typical functions like - packet trapping/ receiving and sending packet/ reprogramming the hardware etc ? How can i learn all this stuff at home ?

I think that if your "system" is a computer, it should have a NIC (or you can buy one). Anyway, you need a computer to write a driver... so download the kernel sources and look at the driver source for the NIC you are using.

Related

How does the Linux Operating System understand the underlying hardware?

I want to learn how Linux OS understands the underlying hardware.Can anyone suggest me where to start for getting this understanding,As of now i just know the '/dev' sub-directory plays a vital role in that.
It has the device special files which are like a portal to the device driver which then takes it to the physical device.
I read somewhere that Udev daemon listens to the netlink socket to collect this information and Udev device manager detects addition and removal of devices as they occur.
But with these i am just not satisfied with the thought of how Linux reads the hardware.
Please let me know where to start to understand this, i am so thankful to anyone trying to help.
I think at first you need to find out how the memory mapping works. What is the address space and how it relates to physical memory. Then you could read about how the hardware is mapped in address space and how to access it. It is a big amount of docs to read.
Some of those information are in Linux Documentation Project.
Additionally some knowledge about electronic would be helpful.
In general - Linux for communication with devices needs some "channel" of communication. This channel may be for example ISA, PCI, USB, etc bus. For example PCI devices are memory mapped devices and Linux kernel communicates with them via memory accesses. So first Linux needs to see given device in some memory area and then it is able to configure this device and do some communication with it.
In case of USB devices it is a little bit complicated because USB devices are not memory mapped. You need to configure USB host first to be able to communicate with USB devices. Every communication with USB device is achieved via USB host.
There are also devices which are not connected via ISA, PCI or USB. They are connected directly to the processor and visible under some memory address. This solution is usually implemented in embedded devices. For example ARM processors use this approach.
Regarding udev - it is user-space application which listens for events from Linux kernel and helps other applications with recognizing device addition and configuration.

How to Locate and Directly Connect to an Ethernet Card on Unix / Mac

From my understanding, the ethernet drivers are where the rubber hits the road in terms of sending data over the network. It is where the CPU transfers bits to hardware which somehow goes over the network.
The question is how you do this at the lowest level possible, i.e. without using a unix command like netcat or something equivalent in C.
From what it sounds like, the ethernet "network card" is a piece of hardware with highly varied implementations. So each version of a MacBook might have a different network card, not to mention each PC version. So it sounds like there could be thousands of different network card implementations. Which is why the operating system like Linux has the "driver" abstraction. The driver is created by the hardware manufacturer so that it fits the ~specification~ Linux has for I'm guessing a "socket", but not sure. Please correct me if I'm wrong.
So what I'm wondering is, how I find out on my Mac how to directly connect to an ethernet driver (at the lowest-level possible), so I can then figure out how to send 1 bit into the network (not going to ask about where to send in the network, because that is probably a further complicated question).

How to transfer data with high speed through USB?

I'm trying to find a way to send/receive data through USB port of an ARM processor on a zynq board (ZC706) running petalinux.
I searched on the net and I'm totally confused where to begin. I found solutions but those did not consider USB to be connected to ARM processor, high-speed data transfer or petalinux.
I know how to write simple linux kernel codes and I know how to work with zynq board.
To be specific, I want to know how to write a piece of code, better to say a library of functions, in petalinux to read and write to usb port connected to ARM as high-speed as possible.
Seems like you are trying to do some quite sophisticated thing.
First I would like to say that USB is not some kind of port which you can read data "byte after byte" like in case of serial or parallel ports.
I would recommend you to start with reading about USB 2.0 and EHCI documentation (it take some time). Additionally you need to know what kind of USB is your board - is it host or device USB type? In case of usb device type - probably you need to write your own driver for this board and connect it to some USB host (PC for example). Then you need to create some communication protocol over USB. Luckily on the PC side you would use the libusb library for this. I mean you need to write program which uses libusb library for communication with your board.
Quite a lot of work to do.

How does the USB storage driver works in Linux?

I am trying to find out a high-level overview of how the USB storage driver works in Linux. I'm looking for a simple article or even a picture/flowchart describing how it works.
Basically, I'm looking to get these questions answered:
When you plug the device into your computer, what happens? Is there a daemon that picks up on it, or does the event trigger an interrupt somewhere? Does the core USB driver read information about the device before passing control over to the USB storage driver? How does it decide what type of device it is? How does the device get mounted, and what allows it to communicate with the computer's filesystem? When I copy a file, what does the data flow look like in the kernel?
I hope the question isn't too vague - I tried Google to no avail, so I'm wondering if anyone knows any articles or diagrams that can explain this, or perhaps if they can explain it themselves without too much effort. Thanks.
No, it is a very good question.
The block writing is going in linux with the block device layer. The filesystems are working with this block dev layer.
If this layer wants to write something out, says it to the driver of the usb master device. This driver is talking with the usb controller chip of the motherboard.
This chip is very simple: the usb is practically a serial port, with a lot of extensions, mainly targeting the autoconfiguration and the power management. But basically, you can write out bytes, and read in bytes.
Your questions:
When you plug the device into your computer, what happens? Is there a daemon that picks up on it, or does the event trigger an interrupt somewhere?
The device (usb slave) says the master (in the motherboard): "I am here". The usb controller chip gets the message and says it to the kernel (normally) with an interrupt. The kernel reinitializes and rescans the usb bus, and says the udev: "here is a new 1234:5678 usb device on the usb tree 1.3.5"
"How does it decide what type of device it is?"
Usb devices have a vendor and model id, and they can say this on ask. Google for "usb ids".
"How does the device get mounted, and what allows it to communicate with the computer's filesystem?"
The kernel only loads the driver and says the udev (which is in userspace): "Here is a new block device on device number 22:16". From this, udev tries to mount this with some userspace daemon, it is already distribution-dependant.

Linux writing raw bytes on USB

I've got usb cable plugged to my computer, which D+ and D- pins are connected to multimeter. I want to send some raw bytes to get some voltage.. is it possible at all?
I'm 99% sure that usb port I've plugged cable in is something like /dev/bus/usb/002
I know that there was possibility to do the same with LPT or RS232 ports.
RS232 and LPT are not bus ! USB devices need to be addressed in order to become reachable.
Maybe unloading and reloading usb driver that drive your usb host... or trying to make a reset on usb hub host...
For doing this kind of operation on usb port, you have to break usb kernel driver and whipe all addressing operation to address directly the chipset...
At all, due to USB concept, I'm not sure you may successfully hold some power state on outlet.
For playing with that kind of physical IO, two solution:
Install a low-cost RS-232 <-> USB adapter
or better
Buy an Arduino micro-controller for prototyping and development.
I'm nearly 100% sure that you can't send anything down your USB lead unless you actually have a device at the other end. If you still want to play with this, get a cheap memory stick, break the casing off it [not too roughly], and measure whilst doing a large file-transfer to the memory stick, or some such.
But I'm not sure your multimeter will show much, as they tend to be a bit slow, compared to USB rates.
USB uses pull-up / pull-down resistors on the data lines to detect whether or not a port is connected (1.5k pull-up to 3.3v on the device side, 15k pull-down on the host side IIRC). The exact connection depends on the device speed.
So if you connect an appropriate resistor, the host should attempt to start signalling. Because of the data-rate, you might not be able to see that on a multimeter; an oscilloscope would be more appropriate.
If you want to by-pass the normal USB protocol and just blindly send data, I think you'll need to get your hands dirty and write code to bypass the usual device drivers and access the USB hardware directly. Even then I'm not sure what's possible - the USB hardware is a lot smarter than good ol' LPT and RS232 ports, which might get in the way of doing this sort of low level stuff.

Resources