The presentation given in lecture is now accessible from the web:
NetWatch lecture slides
Friday, September 26, 2008
Many changes
Many changes were made tonight, with quite a few exciting new bits of functionality. But, before I go into detail on any of those, let me start off with this:
We have, indeed, successfully bothered the 3c905 network card to cause it to go away and get off our bus. It wasn't the cleanest solution, but it did work. It turns out that if you set the BARs on a card to garbage, Linux will set them to non-garbage on card probe, and since we can't trap on 0xCF8/0xCFC accesses, those were *two* of the methods that we planned to use to bother this card gone. But, Linux will surely listen to you if you ask often enough; so, we asked the card every 64msec to stop responding to requests. This creates a race; it had better be the case that Linux does PCI enumeration more than 64msec before it loads the 3c905 driver, or else we will be hosed.
I'm not sure if there is a clean way to do this; suggestions would be appreciated. This works, at least, for the time being.
There were many more things that happened tonight, though. In particular:
The code is now much cleaner, and more extensible. Look forward to lwIP coming this weekend, or at least a small network driver.
[ 3.193058] e100: eth0: e100_probe: addr 0xfbfff000, irq 10, MAC addr 00:02:b3:36:7d:72
[ 3.193229] 3c59x 0000:02:0c.0: enabling device (0000 -> 0003)
[ 3.193300] PCI: Found IRQ 11 for device 0000:02:0c.0
[ 3.193386] 3c59x: Donald Becker and others.
[ 3.193451] 0000:02:0c.0: 3Com PCI 3c905C Tornado at e0814000.
[ 3.314350] *** EEPROM MAC address is invalid.
[ 3.314411] 3c59x: vortex_probe1 fails. Returns -22
[ 3.314479] 3c59x: probe of 0000:02:0c.0 failed with error -22
We have, indeed, successfully bothered the 3c905 network card to cause it to go away and get off our bus. It wasn't the cleanest solution, but it did work. It turns out that if you set the BARs on a card to garbage, Linux will set them to non-garbage on card probe, and since we can't trap on 0xCF8/0xCFC accesses, those were *two* of the methods that we planned to use to bother this card gone. But, Linux will surely listen to you if you ask often enough; so, we asked the card every 64msec to stop responding to requests. This creates a race; it had better be the case that Linux does PCI enumeration more than 64msec before it loads the 3c905 driver, or else we will be hosed.
I'm not sure if there is a clean way to do this; suggestions would be appreciated. This works, at least, for the time being.
There were many more things that happened tonight, though. In particular:
- SMI handlers now have enable routines -- instead of poking the hardware directly, you can smi_register_handler(...); smi_enable_event(...);. Much cleaner code, much more portable.
- Structured packet support was added. If you put some magic values in the registers, then poke the GBL_RLS (BIOS request) bit on the southbridge like an ACPI handler would do, then you can make requests of NetWatch. You can even give it a logical address, and it'll do lookups just as if it were the kernel! Blame Jacob for that... ;)
- We can now scan and probe devices on the PCI bus, with a relatively abstract method.
- Output routines were unified -- now instead of deciding whether to call puts or dolog, you can call the function pointers output and its formatted friend, outputf and you'll get the Right Thing no matter whether you are in the loader or the aseg code itself.
The code is now much cleaner, and more extensible. Look forward to lwIP coming this weekend, or at least a small network driver.
Sunday, September 21, 2008
quick thought
Also, we need to unify logging. Having dolog() from some contexts, and sprintf()/puts() from others is not so cool. Also, we need to figure out a way to split the build environments out, and put object files in the right places for the right build environments -- right now, there are three build environments (Linux, grubload, and in-SMM, with grubload being very similar to in-SMM, but for the bigger console). A full unified build system that would allow you to 'make' from the root would be cool too.
Much-needed dirty work
Okay, some much needed dirty work has been done. I moved a bunch of logic out to smi.c, and put together a lot of defines in reg-82801b.h as created from Intel's documentation. There are a few subregisters that need to be trawled, and I need to work out a system to register interest in a type of event, and have a callback for it.
Of note also is that we now have 'printf' and 'dologf', which should eliminate disgusting blocks of code like this:
To be replaced with:
This gives much cleaner code, and much cleaner output, too!
I'm undecided on this whole 'no magic number' business again. On one hand, things like this: return pci_read32(0, 31, 0, 0x40) & 0xFF80; do look pretty magic and hard to maintain; indeed, it has even been the source of a bug, since '31' was originally typoed as '21'! But on the other hand, replacing with named constants is pretty ugly too; my RSI is acting up just thinking about this: return pci_read32(ICH2_LPC_BUS, ICH2_LPC_DEV, ICH2_LPC_FN, ICH2_LPC_PCI_PMBASE) & ICH2_PMBASE_MASK;. Yikes.
So I guess the next step after this stuff gets cleaned up is to start trying to hide the NIC. Since PCI interception doesn't work, I guess we get to turn off the BARs, and hope that Linux does not turn them back on for us. We shall see...
Of note also is that we now have 'printf' and 'dologf', which should eliminate disgusting blocks of code like this:
strcpy(s, "READxxxxxxxxxxxxxxxx");
tohex(s+4, cts);
b = inb(cts & 0xFFFF);
tohex(s+12, b);
dolog(s);
To be replaced with:
b = inb(cts & 0xFFFF);
dologf("READ: %08x (%02x)", cts, b);
This gives much cleaner code, and much cleaner output, too!
I'm undecided on this whole 'no magic number' business again. On one hand, things like this: return pci_read32(0, 31, 0, 0x40) & 0xFF80; do look pretty magic and hard to maintain; indeed, it has even been the source of a bug, since '31' was originally typoed as '21'! But on the other hand, replacing with named constants is pretty ugly too; my RSI is acting up just thinking about this: return pci_read32(ICH2_LPC_BUS, ICH2_LPC_DEV, ICH2_LPC_FN, ICH2_LPC_PCI_PMBASE) & ICH2_PMBASE_MASK;. Yikes.
So I guess the next step after this stuff gets cleaned up is to start trying to hide the NIC. Since PCI interception doesn't work, I guess we get to turn off the BARs, and hope that Linux does not turn them back on for us. We shall see...
Saturday, September 13, 2008
Good news and bad news
The good news is that we now know how to trap on arbitrary I/O reads/writes. We successfully have it wired up such that when you press escape, and when the OS goes to read the escape key, the system reboots, which is great fun for annoying vi users. We have both the 'special' traps (keyboard/mouse) and normal traps (arbitrary I/O ports) working.
Now, the bad news is that 32-bit accesses to the PCI config I/O ports 0xCF8/0xCFC are caught by the memory controller hub (MCH), which comes before the ICH, and that means that we can't trap on those accesses. So, we can't get in the way there, which kind of sucks. I was trying to get in the way by trapping on the IO ports allocated to the 3c905, but it turns out that's also bound to memory mapped regions; I think that if we intercept PCI before Linux starts and deconfigure the BARs for the MMIO registers on the 3c905, then we can force it to use the I/O ports (and subsequently force Linux not to see them). Perhaps better, we could just deconfigure both BARs and only configure them when we're in the SMM handler and we want to talk to the card... hmmm...
Now, the bad news is that 32-bit accesses to the PCI config I/O ports 0xCF8/0xCFC are caught by the memory controller hub (MCH), which comes before the ICH, and that means that we can't trap on those accesses. So, we can't get in the way there, which kind of sucks. I was trying to get in the way by trapping on the IO ports allocated to the 3c905, but it turns out that's also bound to memory mapped regions; I think that if we intercept PCI before Linux starts and deconfigure the BARs for the MMIO registers on the 3c905, then we can force it to use the I/O ports (and subsequently force Linux not to see them). Perhaps better, we could just deconfigure both BARs and only configure them when we're in the SMM handler and we want to talk to the card... hmmm...
Thursday, September 11, 2008
Pre-sleep updates
- System now boots with Jacob's ELF loader, and returns with my real mode code to reboot into grub, and can do full Linux boot process with SMM monitor.
- SMM monitor currently breaks ACPI, because it is used for APM ports (0xB2/B3) -- can we fake it well enough, or do we have to chain the old one? (ewww)
- We have a log console for debug messages that shows up at the top right of the screen
So, both "immediate todos" are complete. Now need new immediate todos... to be discussed tomorrow if we have time. Refactoring is imminent.
The git repository is now publicly accessible: NetWatch git
Photo of the day:
Wednesday, September 10, 2008
Status update
Current status as of first update:
Immediate todos:
Later todos relating to current code:
Code available:
git clone http://nyus.joshuawise.com/storage/git/netwatch.git
- We can open up aseg and write to it on our test machine, ainfvec (ICH2).
- We can trigger and retrigger SMIs on ainfvec.
- We have working aseg code that writes to video memory from C space.
- We have PCI write skeletons for Linux and raw I/O.
- We have a working ELF loader that 'raw loads' ELFs into memory from inside Linux.
- We have a multiboot kernel that can be loaded from GRUB, using Joshua's p1 console.c. Does nothing more than print parameters and spin.
- Build system surely needs work.
- Modularity need work.
Immediate todos:
- Get grubload to return to GRUB later.
- Load ELF/SMM code from grubload.
Later todos relating to current code:
- Refactor machine specific/northbridge specific code into users of a PCI module.
- Have PCI code scan bus and enumerate cards.
Code available:
git clone http://nyus.joshuawise.com/storage/git/netwatch.git
Subscribe to:
Posts (Atom)