“With a bit of C and microprocessors knowledge, this article shows it’s possible to write your own device drivers in Linux. It might not be the easiest thing to do, but it’s great to see that writing device drivers doesn’t require black magic – it’s just a matter of talking to the Linux kernel!” And a matter of praying that Linux’s driver interface doesn’t change while writing your driver, of course.
More of these.
Second that.
However, I am trying to write so drivers for BeOS where I am finding two problrems that I am sure applies to Linux too.
1) Hardware information. Even hardware that is suppose to be documented tends to have gaps when the person writting the docs thinks something is so clear and oviuous that it does not need writting down. Trust me, it does need to be written, exspecially if you are using the hardware for something totally diffirent than it was designed for.
2) Software information, AAAARRRRHHHHH! What can I say otherwise. The sample code I find is missing all sorts of docs of what it is doing in places. Code written so dense than one line of code does 5 diffirent things at the same time. And worse special code needed to write for special hardware. The example driver in the article is pretty standard of what I find out there and it tells you nothing about a ‘hot’ plug device like USB or PCcards.
I wish I could get more details.
I thought this keyword is a big no-no, espcially in kernel-mode code, where using it a bit incorrectly can crash the system.
While having the potential for abuse and having been misused so badly there is actually nothing wrong with a forward jump done correctly and can actually lead to better code albeit this is a powerful tool that should be only in the hands of the skilled master. Hence the philosophy of leaving label jumping in there but advising amateurs never to use it.
Because C has no exception handling system, it’s common enough to use goto to jump to a certain code block when an error occurs so you can clean up.
Without goto you have the following
———————————————–
if (! fin = fopen (“inputfile”, “r”))
{
perror (argv[0]);
return EXIT_FAILURE;
}
if (! fout = fopen (“outputfile”, “w”))
{
fclose (fin);
perror (argv[0]);
return EXIT_FAILURE;
}
if (! fread (buffer, BUFF_SIZE, 1, fin)
{
fclose (fin);
fclose (fout);
perror (argv[0]);
return EXIT_FAILURE;
}
if (! fwrite (buffer, BUFF_SIZE, 1, fout)
{
fclose (fin);
fclose (fout);
perror (argv[0]);
return EXIT_FAILURE;
}
fclose (fin);
fclose (fout);
return EXIT_SUCCESS;
———————————————–
However if you use goto to manage your error handling you’ll have
———————————————–
if (! fin = fopen (“inputfile”, “r”))
{
perror (argv[0]);
return EXIT_FAILURE;
}
if (! fout = fopen (“outputfile”, “w”))
{
perror (argv[0]);
goto fout_fail;
}
if (! fread (buffer, BUFF_SIZE, 1, fin)
{
perror (argv[0]);
goto fail;
}
if (! fwrite (buffer, BUFF_SIZE, 1, fout)
{
perror (argv[0]);
goto fail;
}
/* do stuff */
/* then clean up */
fclose (fin);
fclose (fout);
return EXIT_SUCCESS;
fail:
fclose (fout);
fout_fail:
fclose (fin);
return EXIT_FAILURE
———————————————–
It’s basically one of the very few clean(-ish) ways of doing error handling in C. It’s okay so long as you don’t use it to control the algorithmic flow.
Edited 2006-04-26 17:18
Once you’re touching the kernel, it’s ok to use a goto.
It’s a matter of taste.
I prefer to have a nice goto than having a lot
of logic to avoid one.
It’s kind of sad, in a way. Dykstra’s “Goto considered harmful” paper and Knuth’s response should be required reading for every programmer.
The upshot is that Dykstra found a lot of bad programs which were hard to follow because they had no structure. Inevitably in these programs, goto was used in place of structure. So he wrote a paper declaring goto must go.
But he overshot the mark, and Knuth pointed out that what Dykstra was really arguing against was those gotos that reduced the structure and readability of a program, but that there are clearly cases in which a goto improves the structure and readability.
In the simplest form, the forward goto that jumps out of a deeply nested set of control structures to a cleanup case at the end of the routine is almost always more readable than trying to structure the code to avoid using gotos at all.
(BTW, the debate predates C, and the issues aren’t about lack of exception handling. Classic examples include search success in a complex nested search, in which the goto is used for the non-exception case and the fall through is the exception case…)
And a matter of praying that Linux’s driver interface doesn’t change while writing your driver, of course.
How about just not upgrading the kernel while you’re writing a driver?
I just spit lunch across the room in laughter when I saw “And a matter of praying that Linux’s driver interface doesn’t change while writing your driver, of course.”
Which is still linux’s greatest shortcoming and the REAL reason the biggest problem with linux is driver support for… anything.
Got your Ralink wireless working in 2.4.13? Don’t upgrade to the 2.4.14 kernel or you’ll break it… but don’t worry, it’s supported in 2.6 (which breaks half your binaries anyhow)
Who’d have thought a stable, mature, fixed way of interacting with the hardware would be so hard for an open source project to settle on.
Unfortunately, it’s intentional. I see it as somewhat childish. There are ten thousand ways to solve the problem of letting binary drivers interface with the kernel without breakage on every upgrade. But the problem is that Linus and co. don’t want there to be a stable interface for political reasons. For reasons like this, Linux is *not* easy to develop drivers for, and until it is, Linux will stay with >1% marketshare.
Unfortunately, it’s intentional.
No, it isn’t. It’s not like Linus says “oh, we haven’t changed the driver API in a few releases, let’s just change something trivial to break proprietary drivers.”.
That just doesnt happen. What does happen is that when a bug is found, or a new approach is discovered that would improve the design of the kernel, then that is fixed/implemented even if it means a change in the API.
It is not an intentional malicious change so much as a very low priority on API stability for proprietary drivers if it will improve the kernel as a whole. Big difference there.
Except you’re wrong. Linus and others have explicitly stated that they will not support binary drivers and that they have ideological (in addition to technical) reasons to do so. Like I said, there are a thousand different ways to support binary drivers without tying the kernel down: compatibility layers, a subset stable API, etc. But they have absolutely 0% interest in doing this because they just don’t want binary drivers. They wan’t open source drivers that live in the mainline kernel and anything else, they won’t waste their time on. It’s a damn shame too, because not everybody agrees that the entire universe should be open source.
Linus and others have explicitly stated that they will not support binary drivers and that they have ideological (in addition to technical) reasons to do so.
I don’t deny that they have idealogical as well as technical reasons for not supporting closed source drivers. But there’s a difference between not putting in extra effort to support them and making changes for the sole purpose of breaking them. I don’t think you can find a single commit in the Linux kernel that was solely there for the purpose of breaking compatibility.
Like I said, there are a thousand different ways to support binary drivers without tying the kernel down: compatibility layers, a subset stable API, etc
Of course it’s possible, but don’t pretend like there are no downsides to doing this. Increased complexity, a lot more code to maintain, etc. The kernel crew made the choice to not drag along this kind of baggage.
I don’t deny that they have idealogical as well as technical reasons for not supporting closed source drivers. But there’s a difference between not putting in extra effort to support them and making changes for the sole purpose of breaking them. I don’t think you can find a single commit in the Linux kernel that was solely there for the purpose of breaking compatibility.
See under “Symbols, exporting”
The ideological aspect of it has nothing to do with “the universe should be open source”. Linus is no RMS. What it comes down to is the fact that open-source drivers are a tremendous deal easier for them to support than closed-source ones.
ISVs have offered to come up with a solution for creating a binary ABI and supporting it. Linus and co. simply aren’t interested.
Nobody’s saying that binary drivers aren’t harder to support. That goes without saying. But that’s no excuse for the kernel devs to just throw up their hands and say “no way”. There are a multitude of much harder problems that have been solved in the kernel besides this one. If they weren’t ideologically opposed to binary modules, they’d have already found a good solution by now.
ISVs have offered to come up with a solution for creating a binary ABI and supporting it. Linus and co. simply aren’t interested
The kernel is Free Software, nothing prevents a coalition of ISV to provide a binary ABI and supporting it.
But that’s no excuse for the kernel devs to just throw up their hands and say “no way”
They never did that. They said they support free drivers, but ISV and co. simply aren’t interested.
But that’s no excuse for the ISV devs to just throw up their hands and say “no way”.
See the supidity of your argument ? This one is contradictory and is as valid as yours.
There are a multitude of much harder problems that have been solved in the kernel besides this one. If they weren’t ideologically opposed to binary modules, they’d have already found a good solution by now.
Why ? They don’t do binary modules, so I would like to understand why they should find a solution to a problem that is not theirs.
Linux has not acquired so much free drivers by supporting closed ones you know.
What it comes down to is the fact that open-source drivers are a tremendous deal easier for them to support than closed-source ones.
I don’t know what it comes down to, but it’s definitely not this. The issue here isn’t supporting drivers, it is supporting a stable driver interface.
If there was actual innovation in the driver interface, the frequent breakage would make sense, but there isn’t, and so it doesn’t.
Amazingly enough, after more than 40 years of attaching device drivers to operating system kernels, the industry does have workable models for stable driver interfaces that would be suitable for linux.
don’t know what it comes down to, but it’s definitely not this. The issue here isn’t supporting drivers, it is supporting a stable driver interface.
A stable driver interface encourages closed-source drivers. Closed-source drivers are an enormous PITA for them to maintain. Ergo, supporting a stable driver interface just results in more work for them.
Consider all the XGL-related brouhaha. The Linux folks are having a very hard time creating a compositing desktop because they don’t have the source code to the OpenGL drivers. NVIDIA shares its driver source code with Microsoft and Apple, which has allowed them to modify the 3D drivers to suit their compositing desktop. The Linux folks are just as capable of doing that, but they’ve been hampered by having to reverse-engineer the 3D drivers first. No matter how you slice it, the Linux folks would rather have OSS drivers than closed ones, and not just for ideological reasons.
If there was actual innovation in the driver interface, the frequent breakage would make sense, but there isn’t, and so it doesn’t.
Compare the differences between the driver APIs in Linux 2.4 and 2.6 and tell me that they didn’t need to change. Linux doesn’t operate on the principle of “Solaris does it, so it must be good.” It operates on Darwinian principles — “this has proven to be better in practice”. The minute you throw interface stakes in the ground, you hamper this evolutionary model of development.
There is also the flip side to this argument. Why don’t hardware manufacturers just release specs? It’s not like there is anything “innovative” going on in the NIC world! There are some driver interfaces complex enough that I can see they’re worth protecting (eg: a GPU), but honestly, most hardware manufacturers are deluding themselves if they think their devices are special enough to warrent keeping interface specs secret…
Edited 2006-04-27 20:14
A stable driver interface encourages closed-source drivers. Closed-source drivers are an enormous PITA for them to maintain. Ergo, supporting a stable driver interface just results in more work for them.
No, it encourages driver writers to keep their drivers current. It gets tedious, even for those of us with open source drivers, to constantly have to reimplement them against a new kernel interface.
Besides, they don’t maintain the drivers, closed or open source. That’s a red herring. They maintain the driver interface, and even for them, figuring out a stable one and sticking to it would be less of a pain than constantly changing it.
Compare the differences between the driver APIs in Linux 2.4 and 2.6 and tell me that they didn’t need to change. Linux doesn’t operate on the principle of “Solaris does it, so it must be good.” It operates on Darwinian principles — “this has proven to be better in practice”. The minute you throw interface stakes in the ground, you hamper this evolutionary model of development.
Oh, the 2.4 model sucked, and the 2.6 model sucks marginally less. No doubt about that.
But it’s not about “Darwinian principles”, since driver models are changed frequently enough that little or no experience is gained with one before the next is introduced, as has happened in recent 2.6 kernels.
If anything, the Linux kernel has the opposite problem: too much random thrashing specifically because of the not-invented-here syndrome.
“high rate of change” does not equal “evolution”, and CS guys should stick to CS and leave evolutionary biology to biologists.
(For those who care, “Darwinian principles” applied to Linux would mean deploying a lot of different driver models in the same kernel release and then picking the ones that proved out over time. This is not what is happening.)
It’s both political and technical. The underlying technical reasoning is that they don’t want to be tied down by driver compatibility issues. Given that Linux is a rapidly evolving system, this is a big deal. The underlying politcal reason is that closed-source drivers are a PITA for them to support. Linux is invariably a second-tier platform for major companies, and the closed-source drivers tend to be fragile and not often updated. It’s more productive for the Linux developers to just write the drivers themselves, because at least then they can fix it if something goes wrong, instead of having to go pleading to the company.
Regarding “Linux won’t gain marketshare until drivers are easier to write”, that’s bollocks. Until 10.4, OS X didn’t guarantee driver ABI stability either (for the same technical reason — the kernel was rapidly evolving during that time). That doesn’t seem to have hurt its market share. Linux’s marketshare is small for the same reason OS X’s is: it’s very difficult to get off Windows, even if you want to. Software compatibility, not things like driver models, are what drive the market.
Which is still linux’s greatest shortcoming and the REAL reason the biggest problem with linux is driver support for… anything.
No, it’s not, not in the way you think at least.
Got your Ralink wireless working in 2.4.13? Don’t upgrade to the 2.4.14 kernel or you’ll break it… but don’t worry, it’s supported in 2.6 (which breaks half your binaries anyhow)
Beside your stupid troll about broken binaries, it has to be noted that the wireless driver do not support SMP and kernel preempt.
So basically, what you say is to stay stuck behind because of a driver, instead of fixing the driver.
I’m very happy the kernel dev avoid this path that you seem to like so much.
Who’d have thought a stable, mature, fixed way of interacting with the hardware would be so hard for an open source project to settle on
Noone, you just have it completely backwards. 3 things :
– The hardware vendors are the one responsible for keeping their drivers up to date. They don’t support their driver, and you manage to blame Linux !
– The drivers in the kernel work without problem, and at least are supported by the kernel devs. So your Ralink example, which is not in the kernel, is just BS.
– The driver you cited can not even work in an SMP system, like a lot of wireless drivers (hello Dual Core is here). Wireless drivers particularly, are in a poor state in every OS, where for the same chip, you have a lot of different drivers on Windows, depending on the vendor. Who’d have though a stable, mature, fixed way of interacting with the wireless hardware would be so hard for a closed-source vendor to setlle on ?
Edited 2006-04-27 09:42