Waarschuwing: lange post

Ik snap eigenlijk niet waarom de AMD GPU driver onderdeel uit maakt van de kernel. ...
Een paar weken geleden stelde iemand vrijwel dezelfde vraag in
Linux kernel 4.1 beschikbaar, waar ik een heel uitgebreid antwoord op heb gegeven. Omdat dit vrijwel dezelfde discussie is, maar ik geen zin heb weer zo'n lang verhaal te schrijven neem ik even de vrijheid hem hier te copy/pasten
ultimasnake vroeg:Toch vind ik het nog steeds knap/apart dat in de kernel ondersteuning zit voor dingen waar ik dacht dat altijd drivers voor bedoeld zijn. Waarom zou je in de kernel zelf ondersteuning inbouwen voor een ledje van een specifieke laptop b.v.? Kan iemand mij dit uitleggen? (mogelijk mis ik het hele punt als Mac/windows gebruiker

)
Waarop Umbrah antwoordde:Misschien is het nuttig om kernel ontwerp eens te gaan bestuderen. Linux is een vrij taditionele monlitische kernel. Wel flexibel, maar in feite is alles wat je denkt nodig te hebben onderdeel van de kernel. Er is ook een gigantisch debat voor de modulaire kernel, QNX en Darwin (van MacOS) zijn meer microkernels. Dan heb je natuurlijk ook nog een hybride model (Windows heeft een hybride kernel), wat 'best of both' zou moeten zijn, en in feite is Linux al een beetje die kant opgegaan, uiteraard, maar de kern van dit soort dingen is natuurlijk: "er is een nieuwe kernel, en het filesystem kan ineens meer", terwijl in de Windows kernel de HAL in feite niks kan, en zelfs NTFS een module is.
Leuke discussie:
https://en.wikipedia.org/...m%E2%80%93Torvalds_debate
Hierop antwoordde ik onderstaand verhaal:Misschien is het nuttig om kernel ontwerp eens te gaan bestuderen. Linux is een vrij taditionele monlitische kernel.
De reden heeft weinig te maken met het (inmiddels achterhaalde) onderscheid tussen monolithische kernels en microkernels.
De Linux kernel core bevat hoofdzakelijk hoognodige infrastructuur; geheugenmanagement, task scheduler, interne libraries voor datastructuren en interne communicatie, etc. (een uitzondering is core TCP/IP, dat zit ook in de kernel zelf).
Al het andere, met name hardware drivers en filesystem drivers, maar ook zaken als extra TCP/IP functionaliteit, het audio subsystem, hashing en encryptie, en software RAID, bestaan als LKMs - Loadable Kernel Modules (onder andere OSsen soms bekend als Kernel Extensions). Dit zijn als het ware plugins, die als ze geladen worden onderdeel worden van de kernel.
Dat laatste is zo ongeveer de definitie van een monolithische kernel; een LKM wordt in de adresruimte van de kernel geladen. Het wordt onderdeel van de kernel, op gelijke voet met de overige kernelcode. Bij een ware microkernel zou een LKM in zijn eigen adresruimte moeten draaien, het liefst als een los user-space proces.
De keyboard-backlight ondersteuning voor Dell laptops bevindt zich dan ook in de Dell laptop driver, "dell-laptop" genaamd. Dit is dus een module, een driver, die geladen kan worden als dat wenselijk is (op Dell laptops bijvoorbeeld

).
Waarom staat dit dan in het nieuwsbericht van Linux 4.1? Waarin verschilt dit van bijvoorbeeld Windows? Dat heeft niet te maken met de architectuur van de Linux kernel, maar het ontwikkelmodel ervan.
Om een kernel driver voor Windows te maken moet je de juiste SDK hebben (in essentie, de juiste header files en compile/link flags). Iemand schijft dan code voor de driver (bv met de SDK voor Windows 7), compiled die op de juiste manier, en vervolgens kan de driver verspreid worden en geladen worden door andere mensen (in de kernel dus, net als op Linux).
De kernel van specifieke Windows-versie heeft een vaststaande interne API/ABI (interface) waardoor dit - als het goed is - werkt. En dat is waar de zaken met Linux gaan verschillen; de Linux kernel heeft geen vastgelegde interne API, laat staan ABI (de ABI die definieert hoe userspace programma's de kernel kunnen aanroepen zijn een ander verhaal, die ligt juist erg vast).
De reden daarvoor is dat Linus de vrijheid wil houden de interne structuur van de kernel te verbeteren. Het resultaat daarvan is dat een LKM gemaakt voor Linux 3.16 mogelijk niet te laden is op 3.17, en misschien zelfs niet eens te compilen is voor 3.17 zonder wijzigingen.
Een ander verschil is dat open source Linux kernel drivers van oudsher in dezelfde source tree zitten als de Linux kernel zelf. Vrijwel alle netwerkkaarten, geluidskaarten, (core support voor) videokaarten, bergen en bergen USB devices, filesystems, al die drivers krijg je mee als je de source voor de Linux kernel downloadt. Dat maakt het vorige puntje, interface-stabiliteit, ook meteen een stuk minder pijnlijk - bij aanpassingen die bepaalde LKMs beïnvloeden kunnen die LKMs ook meteen mee-geupdate worden.
Het betekent ook dat de standaard-plek waar Linux kernel drivers gehost en gereleased worden de Linux kernel source tree is. En dat is waarom je nieuws over Dell keyboardverlichting (waarvan ik me overigens niet voor kan stellen dat het een van de meest interessante verbeteringen is

) terugvindt in een nieuwspost over Linux 4.1.
Als je trouwens de
Linux kernel source downloadt en een beetje rondbrowset, dan kun je ook zien hoe de hoeveelheden code zich verhouden. De volledige 4.1 source tree is zo'n 655MB, maar daarvan is de core ergens tussen de 10 en 15 MB: kernel/ (de core) 7MB, mm/ (memory management) 3MB, lib/ 3MB. Groter zijn de interfaces tussen de verschillende onderdelen: include/ 32MB, processorarchitectuur-specifieke ondersteuning: arch/ 131MB en de drivers: drivers/ 333MB, sound/ 29MB, net/ 26MB.
Bovenstaand stukje gaat over de source code, maar het gecompileerde resultaat laat een vergelijkbaar verhaal zien; De (gecomprimeerde) kernel image op mijn systeem, /boot/vmlinuz-3.16.0-4-amd64, is 3MB. Alle beschikbare LKMs (/lib/modules) zijn zo'n 160MB, en mijn systeem telt op dit moment 99 geladen kernel modules (goed voor zo'n 7MB, te zien met lsmod).
Overigens heeft het Linux-model vergeleken met bv Windows zowel voordelen (oude drivers worden goed bijgehouden, een goede kernel package heeft enorm veel out-of-the-box hardware-ondersteuning) als nadelen (een recentere driver op een oudere kernel gebruiken is zoveel gedoe dat een kernel upgrade meestal een aantrekkelijkere optie is)
(tot slot nog even dit; Linux LKMs kunnen ook rechtstreeks in de kernel meegecompiled worden, maar dit is tegenwoordig erg ongebruikelijk - buiten bepaalde embedded systemen kan ik me niet voorstellen dat dat nog ergens gebeurt)
Er is ook een gigantisch debat voor de modulaire kernel, QNX en Darwin (van MacOS) zijn meer microkernels. Dan heb je natuurlijk ook nog een hybride model (Windows heeft een hybride kernel), ...
Met QNX ben ik nauwelijks bekend, maar XNU (Darwin is het basis-OS, XNU de kernel) kan ik nauwelijks een microkernel noemen. Lang verhaal kort gebruikt XNU Mach (een echte microkernel), waarna ze voorzover ik weet nog steeds bijna alle functionaliteit in één address space stoppen omdat het anders te traag is.
... terwijl in de Windows kernel de HAL in feite niks kan, en zelfs NTFS een module is.
In Linux zijn filesystems ook modules. Op de computer waar ik nu achter zit is ext4 (het filesytem op mijn schijf) geladen als module

% lsmod | grep ext4
ext4 473802 3
crc16 12343 1 ext4
mbcache 17171 1 ext4
jbd2 82413 1 ext4