At Opensolaris.org they have made a quick comparison of Linux, Solaris and FreeBSD kernels covering (amongst others) Scheduling and Schedulers, Memory Management and Paging, and File Systems.
The article seems very objective, but don't forget that it's found at Opensolaris.org
Solaris, FreeBSD, and Linux are obviously benefiting from each other. With Solaris going open source, I expect this to continue at a faster rate. My impression is that change is most rapid in Linux. The benefits of this are that new technology has a quick incorporation into the system. Unfortunately, the documentation (and possibly some robustness) sometimes lags behind. Linux has many developers, and sometimes it shows. FreeBSD has been around (in some sense) the longest of the three systems. Solaris has its basis in a combination of BSD Unix and AT&T Bell Labs Unix. Solaris uses more data abstraction layering, and generally could support additional features quite easily because of this. However, most of the layering in the kernel is undocumented. Probably, source code access will change this.
A brief example to highlight differences is page fault handling. In Solaris, when a page fault occurs, the code starts in a platform-specific trap handler, then calls a generic as_fault() routine. This routine determines the segment where the fault occurred and calls a “segment driver” to handle the fault. The segment driver calls into file system code. The file system code calls into the device driver to bring in the page. When the page-in is complete, the segment driver calls the HAT layer to update page table entries (or their equivalent). On Linux, when a page fault occurs, the kernel calls the code to handle the fault. You are immediately into platform-specific code. This means the fault handling code can be quicker in Linux, but the Linux code may not be as easily extensible or ported.
Kernel visibility and debugging tools are critical to get a correct understanding of system behavior. Yes, you can read the source code, but I maintain that you can easily misread the code. Having tools available to test your hypothesis about how the code works is invaluable. In this respect, I see Solaris with kmdb, mdb, and DTrace as a clear winner. I have been “reverse engineering” Solaris for years. I find that I can usually answer a question by using the tools faster than I can answer the same question by reading source code. With Linux, I don't have as much choice for this. FreeBSD allows use of gdb on kernel crash dumps. gdb can set breakpoints, single step, and examine and modify data and code. On Linux, this is also possible once you download and install the tools.