According to cloc run against 3.13, Linux is about 12 million lines of code.
- 7 million LOC in drivers/
- 2 million LOC in arch/
- only 139 thousand LOC in kernel/
lsmod | wc on my Debian laptop shows 158 modules loaded at runtime, so dynamically loading modules is a well-used way of supporting hardware.
The robust configuration system (e.g.
make menuconfig) is used to select which code to compile (and more to your point, which code to not compile). Embedded systems define their own
.config file with just the hardware support they care about (including supporting hardware built-in to the kernel or as loadable modules).
For anyone curious, here’s the linecount breakdown for the GitHub mirror:
============================================= Item Lines % ============================================= ./usr 845 0.0042 ./init 5,739 0.0283 ./samples 8,758 0.0432 ./ipc 8,926 0.0440 ./virt 10,701 0.0527 ./block 37,845 0.1865 ./security 74,844 0.3688 ./crypto 90,327 0.4451 ./scripts 91,474 0.4507 ./lib 109,466 0.5394 ./mm 110,035 0.5422 ./firmware 129,084 0.6361 ./tools 232,123 1.1438 ./kernel 246,369 1.2140 ./Documentation 569,944 2.8085 ./include 715,349 3.5250 ./sound 886,892 4.3703 ./net 899,167 4.4307 ./fs 1,179,220 5.8107 ./arch 3,398,176 16.7449 ./drivers 11,488,536 56.6110 =============================================
drivers contributes to a lot of the linecount.
Drivers are maintained in-kernel so when a kernel change requires a global search-and-replace (or search-and-hand-modify) for all users of a function, it gets done by the person making the change. Having your driver updated by people making API changes is a very nice advantage, instead of having to do it yourself when it doesn’t compile on a more recent kernel.
The alternative (which is what happens for drivers maintained out-of-tree), is that the patch has to get re-synced by its maintainers to keep up with any changes.
A quick search turned up a debate over in-tree vs. out-of-tree driver development.
The way Linux is maintained is mostly by keeping everything in the mainline repo. Building of small stripped-down kernels is supported by config options to control
#ifdefs. So you can absolutely build tiny stripped-down kernels which compile only a tiny part of the code in the whole repo.
The extensive use of Linux in embedded systems has led to better support for leaving stuff out than Linux had years earlier when the kernel source tree was smaller. A super-minimal 4.0 kernel is probably smaller than a super-minimal 2.4.0 kernel.