His test-machine has no keyboard and no screen. No one needs that. All he needs are NICs (Network Interface Cards) ... Plenty of NICs and Ethernet cable to see if his kernel responds to pings and routes packets correctly. His kernel of course has powerful multithreading and a complete TCP/IP stack. Or maybe you want to start with something else.
Nick Stacky's challenge
Accessing your NIC.
- First of all, buy one. A RTL8139 preferably or a ne2000, as they're well documented with well-documented hobby-drivers available for them. The Bochs has ISA NE2K support while Qemu has it as a PCI device. Another nice card is the 3c90x.
- Get as much documentation about those chips as you can, figure how they work
- Write/port tools that will scan the PCI bus for such device(s).
First thing, you should learn to send/receive packet on your own system. I strongly recommend the Beej Programming Guide, and reading about encapsulation of protocol headers will be a must.
+--*--*--*--*--*--*--*--+--*--*--*--*--*--+--*--*--*--*--*--+--*--+----/ /--+--*--*--*--+ | preamble & startbit | destination add | source addr | Len | data | CRC | +-----------8-----------+--------6--------+--------6--------+--2--+----/ /--+-----4-----+
Note that for technical reasons, the "data" field must be at least of 46bytes (though "len" may be smaller) and may not be of over 1500 bytes. NIC usually doesn't check this, but failing to do so will lead to packet lost or misinterpreted by other components.
Most NIC cards use the concept of ring buffers that contain packets received (but not yet transferred to main memory) or packet to send. The NIC issues an IRQ when a packet is available in such buffer or when a packet has been successfully emitted (check out the programming guide of your card for details).
Quoting the RTL8139(a/b) pguide, you have to
- copy the packet to a physically continuous buffer in (main) memory
- write the descriptor (start address, size, and miscellaneous control values) on the card's registers
In response, the NIC will
- starts moving data in its xmit FIFO and will start emitting on the wire as soon as it has "enough" data (defined by the early threshold on 8139)
- indicates it has the whole packet in FIFO by modifying the descriptor (setting a status bit somewhere)
- indicates it has emitted the packet by setting another status bit
- trigger an interrupt if interrupts have been enabled for this operation.
Supporting IP, TCP, UDP
Going further than Nick Stacky
One difficulty for Nick is that with his all-wired OS, it can be quite difficult to change the machine setup. Here again, using one GRUB module that will contain the network configuration (IP address to use, address of the default gateway, routing table, etc.) may greatly help.
Nick Stacky's Bookshelf
He owns a copy of "Computer Networks: A Systems Approach" by Larry L. Peterson & Bruce S. Davie that he found by chance in a local bookstore. But he hates reading much else in the print side, since reading print is too slow. He'd rather download the book from his experimental network and gaze at its virtual beauty, then go back and do it again.
Nick Stacky's Opponents position
A kernel should be able to do more than just answering pings. You have plenty of code following RFC, but you can't even display a single character on screen ... Is TCP really interresting if your kernel cannot even have programs that exchange data through those connections ? And don't talk me about your kernel-level POP/SMTP server when i talk to you about user programs ...
- Pcmattman: Even in the first version I had a fully functional UDP/IP stack, and I always find writing the card drivers easier than other things
- insert your names here