Thursday, July 8, 2010

Cryptic Error Messages--find: paths must precede expression

So, I learned how to use 'find'. find lets you find files in the filesystem. It has a few nice uses. As a software developer who works with make, it is often useful to run:

$ find . -name *.d -delete

which finds all files with the extension .d and deletes them.

Well, yesterday, I was trying to do something a bit complicated, apparently. I wanted to grep for files with a certain pattern but where the filenames end in ",v". So naturally, I typed:

$ find . -name *,v

There was other stuff after that, 'xargs' and 'grep' (don't ask--'cvs' is my mortal enemy and it has to do with that.). But the line above illustrates the issue.

Anyway, I got this error message:

find: paths must precede expression

Huh? Paths must precede expression? What paths? What expression? Is it the comma? Naturally, I had to google to find the answer. What did linux people do before google. I got the answer but still didn't know what was wrong. Then this morning I googled some more and finally learned why it was a problem.

Here it is. The bash shell does something called globbing. That means, when you put wildcards on the command line, it looks for all files that match that pattern and then, if there is something, replaces the expression with the wildcards with that list.

So if I'm in the directory that has no *.d files, *.d doesn't turn into anything and hence, isn't replaced. So the first line above works fine.

But in the case of the *,v file, there were files that matched that. So behold the following example where I make a directory and create 2 empty files in it:

$ mkdir -p /tmp/test
$ cd /tmp/test
$ touch a,v
$ touch b,v
$ find . -name *,v

I'll get an error. Why? Because even though I typed find . -name *,v, the find command doesn't get ".", "-name", and "*,v". No, the *,v is replaced with "a,v b,v" so find gets ".", "-name" "a,v", and "b,v". So it thinks I'm looking for only files named "a,v" and that I want to "b,v" them. I guess... I still don't get the "paths must precede expression" but at least I know why there is a problem.

The solution? Quotes. Double or single. Doesn't matter if you're not using variables.

$ find . -name '*,v'

This does what I want.

Wow! So long since I posted

It's been a long time. But I've been learning linux like crazy. I wish I could say I love it, but I don't. In fact, the GNU tools and shell pretty much drive me bananas.

If I can, I'll try to blog about various things I learned....

Friday, August 28, 2009

A Job Where I Use Linux

OK, it's been a while since my last update. But that's OK because nobody is reading this blog anyway. In the space between my last post and this post, I have managed to secure a job where developing software in Linux is something I'll actually be paid for.

So, this post is mostly to mark this event in my life. I will now start updating more often as I am now in pretty deep learning mode. I'll see if I can do a daily post on one of the aspects I'm learning.

Thursday, July 16, 2009

Probing Works--But Still Error 12

I've been off on a little side project learning SQL for something sort of interesting. So I haven't been working on my Linux stuff. But this morning is a good time to check it out. Last time, I had finally gotten the new driver to compile after getting the detection code connected and got it loaded on my USB stick. Sooo....

I rebooted my computer and from the GRUB menu, typed in 'bootp'.

There is some searching for items on the PCI bus, but here is the most important output:


bus 02, function 00, vendor 8086, device 109a
Found Intel EtherExpressPro1000 Marks Kluge at 0x3000, ROM address 0x0000
NIC_LIST start
...
NIC_LIST vendor = 8086 dev_id = 109a ioaddr=3000
NIC_LIST end
Probing...[Intel EtherExpressPro1000 Marks Kluge]e1000: hw_addr=00000000, rom_addr=00000000
Can't do this! Mark.e1000: mmio_start = 00067c3c, mmio_len = 04000000
PCI latency timer (CLFI) is unreasonably low at 0. Setting to 32 clocks.
vendor = 00008086, device = 0000109a, revision = 00000000, subsys = 0000107b
e1000_set_mac_type
e1000: Unknown MAC type

Error 12: Invalid device requested

So, progress. But still a lot of questions. Why is a mmio_start not some nice round number? Why is the PCI latency timer 0? What is the PCI latency timer? Are 0 valid values for hw_addr and rom_address?

Hopefully, these are answers I can find. I've come pretty far. The light on the horizon is fading a bit, but it's not extinguished. Stay tuned...

Tuesday, July 7, 2009

Adding a Kluge

I added a couple of things to my drivers. The big one is this addition to config.c.

{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER,
"Intel EtherExpressPro1000 82545EB Fiber", 0, 0, 0, 0},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER,
"Intel EtherExpressPro1000 82546GB Copper", 0, 0, 0, 0},
/* Mark start */
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MARKS_KLUGE,
"Intel EtherExpressPro1000 Marks Kluge", 0, 0, 0, 0},
/* Mark end */
This makes it recognize my device by telling the pci.c to expect it. I saw the debug code print out that it found it, but I still got the Error 12: Invalid device.

So I looked and found another structure I hadn't updated yet in config.c:


static struct pci_dispatch_table PCI_NIC[] =
{
...
# ifdef INCLUDE_E1000
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MARKS_KLUGE, e1000_probe },
# endif /* INCLUDE_E1000 */
...


e1000_probe is the function that finds the device and actually assigns pointers to the correct driver functions (I hope they are correct enough) to the driver struct that holds pointers.

Baby steps. It's my first time working with drivers in Linux. It sure has its challenges.

So, I make. And as you might expect, I get build errors.

Seems the e1000.c uses pci_read_config_word whereas the rest of the files use pcibios_read_config_word. The same pattern applies to a few pci BIOS access routines. Those are easy enough with #defines for the time being. But there are 2 undefined functions--pci_bar_start and pci_bar_size. This will be a little tougher. There is code out there for VirtualBox. Is it the same thing?

Well, I guess I'll post this now and see what this bar address stuff is all about. Stay tuned.

Monday, July 6, 2009

Finding The E1000 HW

I've been of doing something else for a little while, so I haven't been doing Linux stuff. But as of today, I'm back at it.

So, to recap, I can get my USB drive to boot properly and it loads stage 2. But it can't find my Intel ethernet card when I enter dhcp or bootp. So time to see what I can get it to tell me. The first step--see if I can turn on some debug information.

builtins.c is where there bootp and dhcp commands are found. They probe the drive with eth_probe(...) in config.c and e1000_probe(...) in e1000.c. Turning on DEBUG caused the build to fail. But it was a simple fix--just a printf printing a non-existent field.

So, I'm now in the process of tracking down the problem. I was lead to pci.c where it seems to be failing to find the ethernet card. I can see it looking through the stuff out there on the PCI bus.

I see things that have the Intel vendor ID (0x8086) but none that have an e1000 device ID. So I headed off to check out /proc/bus/pci and found my e1000 NIC device. It has a device ID of 0x109a. Hmmm.... My driver has a list of devices but none go that high.

Well, it's 11:30 at night right now. I guess I'll see what I can do in the morning. But I'm off again. And making progress.

Wednesday, June 17, 2009

Solving Error 12: Invalid device requested

OK, I found a problem. INCLUDE_PCI wasn't defined because I didn't have INCLUDE_E1000 in the list of drivers that bring in INCLUDE_PCI. So all is not lost!

I fixed this issue and a little hiccup with device ID definitions not being found. But now ready to reboot and see what happens...

[It is now Monday. I have been busy this weekend and won't be getting back to this until Tuesday, so I thought I'd just publish as is.]