Android - Why are there so many different Android kernels?
Kernels vary from manufacturer to manufacturer. A lot of those kernels come from the pure stock kernel line of sources found on CAF, what these manufacturers do is take those stock sources, modify them to suit based on the board/chipset used, also, implement their own drivers.
Take a good look around you, there's variations of touchscreens, variations of wifi chipsets, not to mention, accelerometer, sensors, batteries, compass, sound, graphics.
Taking one kernel source from for example HTC will not work on a Samsung, and vice versa.
The manufacturers are free to cherry-pick or out-source various bits that get incorporated into the circuit board. There is no hard or fast rules involved. Hence the lot of hacking/modifications to get the kernel to work properly.
You must not ever, compare to desktop Linux distribution kernels in which it has PCI, PCI-Express, SATA, VGA, SVGA, USB, Ethernet as they are a totally different ball-park game. The major differences with CentOS and with Android's Linux Kernel is this - ALL drivers are compiled either as modules or built-in, hence any Linux distribution will simply "work out of the box". Again, with desktop Linux distributions - you have one architecture - x86 hence one Linux kernel from say a Dell PC, can work out of the box on a Lenovo provided that the bog-standard drivers are compiled.
Don't forget, in the Android world, there's variations of the kernel built for specific ARM chipsets, such as ARMv6, ARMv7, there's TEGRA, there's EXYNOS, and they are binary incompatible with one another. Hence if a kernel is compiled for TEGRA, forget it, it will not work on ARMv7!
The reason some kernels on Android appear to be "broken" is down to the manufacturer. Some (Zte is one very good example) release a butchered source that may compile from source but fails to boot due to a missing driver that is not covered by the GPLv2 or GPLv3 licence. That's the problem, hence some hackers have to go scouring around github looking for some clues; some manufacturers, if not all, do comply. The current incarnation of Zte's source is purportedly to be 18.104.22.168, but in reality its actually 22.214.171.124 source base with a lot of modifications thus does not represent the true kernel source for 126.96.36.199!
This is where the manufacturers have to release their respective sources, not just out of being compliant with GPLv2 or later, but rather, for the community to be able to mod it, such as adding overclocking capabilities.
Hence there's hacking involved behind the scenes and a lot of messing about with drivers trying to get it to work, and its not easy to debug either.. Some drivers may be cross-licensed, BUT cannot be distributed depending on the clause and conditions as negotiated.
Thankfully, that's all changed now with kernel 3.x.x. line of sources, as Android drivers are now integrated into the mainstream sources. But there's a gotcha!
Try porting a 3.x.x. kernel to an existing handset that is about 12-18 months old; Not a snowball's chance in hell would it work, that's because, of the differing factors, the 3.x.x sources is vastly different to the 2.6.x source and would take a lot of hacking to get it working - I should know, have tried porting 188.8.131.52 source for the Zte Blade and failed.
Likewise, the latest kernel release 3.0.1 - when working on the ics4blade project over on Modaco, have made numerous attempts to port it but that's down to the simple fact that Zte made a very bad mess of the source which rendered porting nigh on impossible.
The PC architecture is built around commodity parts because it started out as clones of a specific product, the IBM PC, that were specifically designed to be compatible with it, and therefore with each other. Generally speaking, you could take a program or peripheral device from one PC-compatible and put it into another, and expect it to work. That ability is useful enough that people have continued to demand it even as the technology evolved. You can put a PCI Express card in any modern PC just like you could put an ISA card in any PC clone back then.
Smartphones have no such history. They're designed as monolithic products, a complete system consisting of hardware and software that "just works" as-is. There's no expectation that people will take parts out of one phone and put them into another, so engineers don't have to take interoperability into account when they design their products.
Even within the Linux kernel source tree, there's a lot of fragmentation in the drivers for ARM platforms. Since phones are usually designed behind closed doors, engineering teams at different companies often end up doing duplicate work, designing basically the same hardware as their competitors and then writing their own drivers for their own design. Once they're done and the product is released, they go straight to working on the next one; it's not worth their time to go back and refactor the drivers for past products or merge them with competitors' drivers. The result is a plethora of one-off drivers for devices that are similar but not quite the same.
In addition, smartphones are usually based on SOCs that have specialized hardware integrated together with the processor. For some of this, it can be more than a matter of whether to load or not load a certain driver; the kernel as a whole may need to be built with special configuration options for running on one SOC, which are incompatible with the special options needed to run on another SOC.
The reason is because Android's Linux kernel are generally not compiled on Android itself, instead it had to be cross compiled from another computer. This causes various issues, because the device configuration are not available on compile time, and it is not feasible to compile a generic kernel with all drivers due to space limitation (whereas most desktop distros simply had all drivers compiled into modules loaded from an initramfs). Therefore developers had to figure out which drivers to package for each particular device. Not only that, each drivers generally have a dozen or so of compile time options to toggle various driver features, and manufacturers usually do not release their official configuration (the worst offenders don't even open source their drivers, or didn't keep upstream's copy of the drivers up to date). Because manufacturer's don't release their configurations, often the slightly different configuration that the developer uses will expose subtle bugs that doesn't exist with manufacturer's configuration.
Driver programming is much more difficult than application programming, as there is no kernel that shield you from the fickle hardware that have a specific real-time timing requirements and the such, and this means even having a different performance characteristic may cause the driver to miss some hard real time events from the hardware; these misses may surface as either bugs or performance issues.
Another issue is binary incompatibility. There are two cause of binary incompatibility, first is CPU type, which has been covered by t0mm13b well, but the other issue which is more relevant to porting is the ABI incompatibility (application binary interface). If manufacturers don't open source their drivers, then developers had to use the compiled module from a stock ROM. This raises various ABI incompatibility issues, since the driver modules itself have specific expectations about, for example, struct layout and function calling parameters, and when the kernel is compiled, it does not have the header file to describe the ABI at the time the driver is compiled, so developers had to reverse engineer the driver to create a header file or the header files in the source tree might have been modified heavily since the driver is compiled and developers had to revert those modifications to make the kernel compatible again with the driver's ABI. Unlike compiling from source, compiling for binary driver will not trigger compilation error due to function parameter mismatch or struct incompatibility, it will simply just crash your device while it's running, and debugging these issues are very difficult. In the PC world, we're familiar with the mess that nVidia and ATi left us, due to their insistence on releasing binary only drivers, imagine having that mess for all drivers, imagine the "fun" it creates.
PC hardware are also generally better standardized than mobile hardware, most PCs don't need drivers for vibrators, accelerometer, gyroscope, 3G radio, proximity sensor, NFC, etc. Even on devices that have 3G, it usually connects to the hardware using standardized connections like PCMCIA or PCI-E.