This is an old revision of the document!
===== Week 1 ===== ==== Day 1 ==== Git commit: [[http://git.etherboot.org/?p=people/andreif/gpxe.git;a=commit;h=0e64b6cd060808571a97d2ed26361952ac9c513d|0e64b6cd060808571a97d2ed26361952ac9c513d]] Today's goal was to have the new pcnet32 driver skeleton in place. I took the exact structure that the r8169.[ch] implementation has, and modified it accordingly. Made the first commit/push after that. Until now I've been testing gpxe by creating an ''.iso'' image and using that from VMware. After finding [[appnotes:gpxeonvmware|this page]], I've decided to give the ROM "burning" a try. At first it didn't work because the new ethernetX interface I've created in the ''.vmx'' file was automatically set in bridged mode. I didn't immediately realize that gpxe would not be able to get to my local DHCP/TFTP servers this way. After fiddling with the ''.vmx'' file, I eventually set the NAT option in VMware and it worked. This test was done using the old pcnet32 driver. Compiled using:<code> $ make NO_WERROR=1 bin/pcnet32.rom </code> since my driver's routines are empty and I had to ignore the ''unused parameter'' warnings temporarily. VMware now greets me with a ''No more network devices'' message since my ''.probe'' routine does nothing. ==== Day 2 ==== Git commit: [[http://git.etherboot.org/?p=people/andreif/gpxe.git;a=commit;h=7bb4f10c31b18f3ed78537c83dbd9d4db10033bb|7bb4f10c31b18f3ed78537c83dbd9d4db10033bb]] Today wasn't so productive in terms of coding but I started to delve into the details of the pcnet32 NIC I'm working on. Since I wanted to do a commit/push every day but I didn't want to taint my branch with unfinished implementations I created a separate branch where I'll push every day no matter what. This way, people can tell me if I am heading down the wrong path right away. First, let's get all the acronyms out of the way: * RAP - //Register Address Pointer// * RDP - //Register Data Port// * BDP - //Bus configuration register Data Port// * BCR - //Bus Configuration Register// * CSR - //Control and Status Register// Naturally, what we want to do in an initial stage is to gain access to those Control and Status Registers so we can bring the NIC in a well-known state. Suppose we want to read the chip version present in CSR88 and CSR89. To do that we have to write 88 in RAP so it "points" to CSR88 (or BCR88, since RAP is shared by BCRs and CSRs). After we've done that we read from RDP to obtain the CSR88's value. Repeat for CSR89. Here it is in pseudo-code form: <code C> outw(88, ioaddr + 0x12); // 0x12 is RAP's offset from base inw(ioaddr + 0x10); // 0x10 is RDP's offset from base outw(89, ioaddr + 0x12); inw(ioaddr + 0x10); </code> Something similar has to be done in case we want to access the BCRs. It's all fine and dandy until you realize that pcnet has two modes for accessing those registers: * WIO - //Word I/O// * DWIO - //Double Word I/O// In WIO outw/inw have to be used and in DWIO outl/inl. The datasheet says that doing otherwise may cause "unexpected reprogramming of the [...] control registers". This means we have to define two sets of routines for accesing the registers, one for each mode. Bleh. Also got a look at gpxe's structures and how they relate to each other: * ''struct pci_device'' - Contains information found in the PCI configuration space of a device. * ''struct net_device'' - Represents a generic network device. Create one such structure in the ''.probe'' routine and link the ''priv'' field to any private data your driver might store (''alloc_etherdev''). Link your driver's defined ops to this struct (''netdev_init'') Finally, linke the pci_device to the net_device by setting pci_device's ''priv'' field to point to the net_device (''pci_set_drvdata''). Also you might want to make sure both structure point to the same physical device (the ''dev'' field).