To prave zalezi na nastaveni kazde distribuce, co "pribali" do stock jadra, co dovoli jako modul, a co nezahrne vubec. Ja treba mel dost problem se starsi wifi kartou od Broadcomu, kdyz se Ubuntu rozhodlo, ze v jadre bude nova verze driveru, ktera se vzajemne vylucuje s tou, kterou potrebovala moje karta. Obecne ted dost mainstream distribuci upousti od prikladani driveru pro velmi stary HW.
Pri sestavovani jadra se da nastavit, co vsechno clovek chce, pomoci napr. menuconfig: https://en.wikipedia.org/wiki/Menuconfig#/media/File:Linux_x86_3.10.0-rc2_Kernel_Configuration.png .
Hloubeji do technikalii nevidim, ale predstavuju si to tak, ze kazda volba v menuconfigu bud splni a nebo nesplni nejakou template promennou, a v kodu pak jsou #ifdefy. Plus jsou samozrejme ruzne kody pro ruzne platformy, a vzdycky se sestavuje jen to, co ma smysl (opet bud pomoci #ifdef, nebo je to dano adresarovou strukturou jadra).
Dobre cteni je tady: https://superuser.com/a/370588/255660 .
Ze mého pohledu ze značné dálky vyplývá tohle (rád se nechám opravit někým kdo o věci ví víc):
To co si vybíráte v menuconfig se bere z adresáře linux/arch/[architektura]]/Kconfig, například linux/arch/x86/Kconfig. Tam najdete jednotlivé volby a jejich popis (často žádný neexistuje), a jsou tam i linky na další Kconfig soubory nezávislé na architektuře.
Vybrané volby se zapíšou do souboru .config, který nastavuje proměnné. Například volba MICROCODE_AMD má v UI popis "AMD microcode loading support", má dokonce help text "If you select this option, microcode patch loading support for AMD processors will be enabled.", a nastaví v .config MICROCODE_AMD=y. Pokud volba není zapnutá, najdete v .config komentář typu # MICROCODE_AMD is not set.
Při kompilaci se nějakým skriptem vytváří ze souboru .config header include/generated/autoconf.h, ve kterém najdete vlastní #define MICROCODE_AMD. Ve zdrojáku je pak použitý #ifdef. Například v linux/arch/x86/include/asm/microcode_amd.h uvidíte, jak se metody #ifdefem mění na prázdný inline blok:
#ifdef CONFIG_MICROCODE_AMD
extern void __init load_ucode_amd_bsp(unsigned int family);
extern void load_ucode_amd_ap(unsigned int family);
extern int __init save_microcode_in_initrd_amd(unsigned int family);
void reload_ucode_amd(void);
#else
static inline void __init load_ucode_amd_bsp(unsigned int family) {}
static inline void load_ucode_amd_ap(unsigned int family) {}
static inline int __init
save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
void reload_ucode_amd(void) {}
#endif
Pokud jde o moduly, tak ty jsou v Kconfig (nejčastěji pod větví linux/drivers) jako tristate, a v .config skončí hodnota y (statická kompilace) nebo m (dynamický modul). V makefiles jsou pak použité konstrukce, které používají ty proměnné, typicky takto:
obj-$(CONFIG_SCSI) += scsi_mod.o
A to nakonec skončí sesbíráním object files do kernel image a modulů.