This is an old revision of the document!


NE2000 Emulation For Bhyve

The bhyve hypervisor uses a virtio net PCI device emulation. However, a number of guest operating systems do not have virtio device drivers and are not able to use this emulation. One of the best supported devices, especially in older operating systems, is the NE2000 device. An implementation of a device model for this NIC would allow a larger number of unmodified guest operating systems to run under bhyve. The proposal aims to emulate the National Semiconductor DS8390/WD83C690 Ethernet adapter which is going to be used for the NE1000, NE2000 and a variety of similar clones.

The emulation is going to work tightly for the /sys/dev/ed/if_ed.c device driver in FreeBSD operating system and will be seen as a PCI device being attached under /sys/dev/if_ed_pci.c driver.

There is a datasheet for the 8390 NIC [0] which will be used for a proper understanding of the chip registers and transmit, receive, and control operations. Also, the ED device drivers mentioned above represent a good source of documentation.

I have found an implementation that emulates the NE2000 NIC in the qemu emulator [1]. Obviously, this code can not be ported in the bhyve tree sources, but certainly will be a good source of inspiration regarding the register emulation and transmit, receive protocols. So, an analysis should be done before starting to design and develop the implementation in bhyve. Actually, the qemu implementation uses the RTL8029AS controller which is an NE2000 compatible Ethernet Controller for PCI interface [2]. This controller I intend to use for the PCI configuration.

The implementation contains three logical phases. The first one is the module initialization where the PCI configuration space is configured and the data structures are initialized. The second one consists in register interpretation by handling the read and write BAR callbacks and eventually the third phase where transmit and receive protocols are emulated using read / write calls on the TAP interface. It should be mentioned that for the data transmission the packet is transferred from the memory to the device FIFO respectively for the data reception from the FIFO to the received buffer using the DMA protocol. Both packet reception and packet transmission are well explained in the 8390 NIC specification [0].

  • the PCI NE2000 module
  • the automated tester which is going to validate the NE2000 module

Implement the module initialization so the ED driver in the guest operating system recognizes the NE2000 module as a PCI device.

Design the bridge between the guest and the host operating systems through the TAP interface and find how to get notifications in order to read from the TAP file descriptor. For example, in the “virtio_net” module a callback is registered for the EVF_READ event on the TAP file descriptor.

Analyze of the structure of the registers from the datasheet [0]; design and implement the read and write register operations according to the specification.

Deliver the module initialization and read and write register operations implemented in 25 May - 26 Jun period.

Analyze and understand the transmit and receive protocols through DMA looking on both datasheet specification and qemu implementation [1]; design and implement the packet transmission protocol through DMA according to the specification.

Design and implement the packet reception protocol through DMA according to the specification.

Code and design review with the mentor and fix possible issues; thinking for a testing schema and implement an automatic tester which will be used firstly on the “virtio_net” module; after the implementation is functional it will be used for NE2000 module testing.

Test the NE2000 module implementation, fix some possible bugs and prepare the deliverables and the final evaluation.

I've implemented the NE2000 emulation in the bhyve hypervisor under both PCI and LPC attachements. The full implementation is located in: /usr/src/usr.sbin/bhyve/ne2000.c, and emulates the ne2000 device for the ED driver in FreeBSD: /usr/src/sys/dev/ed/if_ed.c

In order to use the device in bhyve, you need to configure it in the parameters list as:

  • under lpc: -l ne2k0,/dev/tap0
  • under pci: -s 4:0,ne2k,/dev/tap0

Under the LPC bus, you can add at most two ne2000 devices which are ne2k0 and ne2k1. If you want to add two interfaces at the same time you will configure it like:

  • -l ne2k0,/dev/tap0 -l ne2k1,/dev/tap1,00:a0:98:4a:0e:de

In the guest operating system you will see the network interfaces as: ed0 at port 0x310-0x32f irq 10 on isa0 ed0: Ethernet address: 00:a0:98:4a:0e:ee ed1 at port 0x330-0x34f irq 11 on isa0 ed1: Ethernet address: 00:a0:98:4a:0e:de

ed0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:a0:98:4a:0e:ee nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet 10baseT/UTP <full-duplex> ed1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 00:a0:98:4a:0e:de nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet 10baseT/UTP <full-duplex>

Any ne2000 device attached under the PCI bus will be probed as the ed2, ed3 … network interface.

Note0: For the LPC attachements you need to add in the /boot/device.hints file from the guest operating system the following lines: hint.ed.0.at=“isa” hint.ed.0.port=“0x310” hint.ed.0.irq=“10” hint.ed.1.at=“isa” hint.ed.1.port=“0x330” hint.ed.1.irq=“11”

(List of steps you plan to use to test your work, as discussed with your mentor)

  • summerofcode2015/ne2000emulationforbhyve.1440360163.txt.gz
  • Last modified: 2015/08/23 20:02
  • by AlexTeaca