Note: this .TXT version of this howto is out of date. Further updates and expansion has moved into a proper HTML version: http://support.fccps.cz/download/adv/frr/kernel-compile-howto.htm # For the compilation itself, you may need several packages. # Historically I seem to recall packages such as # gcc # make (gmake, GNU make) # binutils # bc # kernel-headers (perhaps not necessary) # bison # byacc # flex # ncurses-dev # libssl-dev # libelf-dev # bzip2 (for .tar.bz2, rather than just .tar.gz, # so that tar knows 'xvjf', rather than just 'xvzf') # # If unsure/lazy, just try the following steps, and see if you can # get by without checking the required packages. # Modern distros often have them all in the base install. # Download and unpack a kernel tarball from kernel.org. # Feel free to use a browser to select a version that suits you. cd /usr/src wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.13.tar.xz tar xvf linux-5.0.13.tar.xz cd linux-5.0.13 # Alternatively, you can install the kernel source for your distro kernel # from RPM/DEB depending on distribution... (using RPM, YUM, APT, whatever) # Tell the newly unpacked kernel sources to get comfortable # in your system make mrproper # configure the kernel, using one of the following: make oldconfig # or cp /boot/config- ./.config # The point is that the kernel config is stored in a text file # called .config, that needs to be created in the kernel source # tree root directory (root of the tarball just unpacked). # The pristine kernel tarball does not contain one. If it does, # such .config probably doesn't match your distro/hardware. # How you arrive at a plausible .config, that's your choice. # # You can either use the traditional "make oldconfig", # which will try to find a backup of the running kernel's config # somewhere in the system. # Or, you can find the backed-up copy in the /boot directory # of your distro. The backup copy is not mandatory for a proper # boot of the distro, it's there merely for your convenience. # # If you copy the .config from a backup by hand, and the kernel # version is not a precise match (likely it is not), menuconfig # can sort that out - it'll drop options it doesn't know for the # kernel version being configured. The .config that you save on # exit from menuconfig will be valid. # # Beware, the new kernel may add options (and defaults for them) # that were not present in the old .config. # Such as, recent kernels seem to add EXPERT and DEBUG_KERNEL: # General setup -> Configure standard kernel features (expert users) # Kernel hacking -> Kernel debugging # DEBUG_KERNEL gets auto-selected by EXPERT. # And, DEBUG_KERNEL leaves debugging symbols in the binaries, # which means that the kernel and all the modules are HUUUGE. # For normal use, you definitely want to avoid these two options. # # You can also create a new .config from scratch, by running # make menuconfig in a pristine kernel source tree. # # Beware of kernel module versioning. Depending on how advanced you are, # it may help you avoid goofed-up kernel reinstalls, or it may # present a hassle if you DO NOT want to recompile+reinstall # the modules every time your main monolithic binary is recompiled. # For least hassle, turn off kernel module versioning *and signing*. # That's in menuconfig # Enable loadable module support -> Module versioning support # Enable loadable module support -> Module signature verification # Note that this makes your system less secure against malicious # module injection (a local attack, probably requiring root privileges anyway) # Run 'make menuconfig', make your choices. # Upon leaving menuconfig, elect to save the configuration into a fresh .config. # # Historical snippet of advice: # You may want to compile the driver for your bootable disk controller # into the main kernel binary monolithically (not as a module), # later on this will get you slightly further down the boot process, # even if you goof up when creating the initrd. # As a downside, you may expect some error messages from the HWconf/udev # subsystems during boot, as they don't find the disk controller driver # module :-) # On modern distroes, this should be a non-issue, as the updateinitramfs # should find all the necessary drivers. make menuconfig # Next, you need to get a kernel binary, and a set of modules. # Modules will be created for components, that you tagged with "M" # in menuconfig. # (Note that you can skip these two commands, make install # and make modules_install will call these automatically if omitted.) make bzImage make modules # The resulting bootable kernel binary will be left at # ./arch/i386/boot/bzImage # The modules will be interspersed with source files throughout # the whole source tree. # # You can copy the monolithic kernel by hand # from arch/i386/boot/bzImage to wherever you want it, # probably /boot/SOME_NICE_NAME. # # Or you can call "make install" to select a name for # your new kernel and do the copy to /boot. # # You definitely want to perform "make modules_install", # which will collect the resulting binary modules (*.ko) # into /lib/modules/kernel_version/, # which is where you want to leave them (unless you're # going to copy them to another bootable disk / image, # and obviously you know what you're doing) make install make modules_install # This has put the monolithic binary and the modules # into place, automagically. # # Let's take a look into the boot directory. cd /boot ls ls -l # Most modern distro's are using a temporary "initial ramdisk", # for various reasons. It used to be required for loading # hardware-specific disk controller drivers as modules, # nowadays there are further dependencies (LVM, udev, ...). # # You can often get the distro to boot with a monolithic # kernel, but it takes time to pick the right options that # need to be made monolithic. # # It's usually a safe bet to do something like "make oldconfig" # and then build your own initial ramdisk with all the modules. # The distro usually contains a script called something like # mkinitrd, which requires a kernel version / path to the modules # to be copied to the ramdisk image. # Debian/Ubuntu: # # update /etc/initramfs-tools/initramfs.conf # (for a smaller size, specify MODULES=dep) # # update /etc/initramfs-tools/modules - you may wish to add some of: # raid1 # sd_mod # crc16 # crc32c_intel # crc32c_generic # # Check /etc/default/grub , you may want to add the following # at the kernel cmdline: # # To disable any Spectre/Meltdown safeguards that eat CPU horsepower: # The old way: # pti=off nospectre_v1 spectre_v2=off l1tf=off nospec_store_bypass_disable no_stf_barrier noretpoline # The new way (since Kernel 5.2): # mitigations=off # # If you want to let hwmon (lm_sensors) to access the SuperIO HW monitor chip: # acpi_enforce_resources=lax # # To force a particular video mode (e.g. if a KVM switch is giving you trouble): # video=1280x1024@60 # (Note: the frame rate after @ is important / required. # 60 Hz is a good value for most LCD's.) # # To work around some bugs in Intel ATOM BayTrail/Braswell IGP power saving, # that cause freezes when running X-Windows with or even without video # playback, try the following curse: # intel_idle.max_cstate=1 # # Return to the good old Ethernet netdevice names such as eth0, eth1 etc.: # net.ifnames=0 # # To make the system more talkative at boot time, try removing "quiet" and "splash". # # Note that you can test the individual kernel cmdline curses at runtime, # without clobbering your grub.conf forever - choose "extended options" in # the Grub menu and pres "e" to edit the entry. # Whatever options you add or erase, they won't get stored into grub.conf . ################################################################ # # NOTE THAT SO FAR, YOU HAVEN'T SPOILED YOUR BOOT CONFIGURATION. # YOU HAVE MERELY COPIED A FEW NEW FILES SOMEPLACE HARMLESS. # # ON TO THE HARMFUL STUFF. # ################################################################ # Auto-update or manually create from scratch an initial ramdisk # for your new kernel: # update-initramfs # = this is a higher level automagical tool OR maybe mkinitramfs [kernel_version] # a lower level tool # Then finally, tell grub to update its config: update-grub # Now the harm has been done, potentially :-) reboot # Further updates to the compiled and installed kernel: # At the compilation stage, if you want to erase any previously compiled # object files (binary snippets comprising the final monolith), # just call 'make clean' before, after or without 'make menuconfig'. # Note that 'make mrproper' does an even more thorough cleanup, # specifically it deletes any existing .config . make clean make menuconfig make bzImage make modules ...etc # If you turn off kernel module versioning (often a good thing), # but you still want to keep a few different boot profiles with different # kernel configurations, you need to have a few different module subdirs under # /lib/modules, for the same kernel version. Some global configuration options # can change your monolith and modules to the point that they're incompatible # with a different configuration of the same version kernel source tree. # So, to achieve the multiple copies of the module set under your # /lib/modules subdir, consider explicitly modifying the top-level Makefile # in the kernel source tree, the appropriate line is called # EXTRAVERSION # (somwehere at the top of the file) # Such as, VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 21 EXTRAVERSION = .7-HACKED-v001 # You should edit the Makefile before "make bzImage" and "make modules", # i.e. before you start compiling the binaries. # If you do it even before "make menuconfig", the new EXTRAVERSION # gets reflected in .config (just in the comments on top, # doesn't affect the compiled binaries) # # The following invocation of "make modules_install" will automatically # create a separate directory under /lib/modules, named accordingly. # # At the very least, you can use a custom extraversion to distinguish your # own cut of the modules from the distro-default modules (if you're recompiling # the distro's default kernel version from source). # # In general, use a different extraversion if # - you want to keep a default boot profile with the distro-original # kernel+modules, and add your custom kernel as a new profile, # while the custom kernel is the same version as the default kernel # - you want to have multiple custom kernels (custom configs of # the same version) in the bootloader, e.g. for different CPU's # You need to recompile and reinstall from scratch (start with "make clean") # and maybe modify the EXTRAVERSION if # - you have modified some key features in the config (CPU subtype, # with/w.o. SMP, some other global optimization stuff) # Actually this case is noticed consistently and handled automatically # with the more modern Kbuild versions (kernel versions). # - you have hacked some global header files even just a little bit # (the automatic dependency checking may not notice) # OTOH, you can avoid "make clean" if # - you only modified an isolated .c file (or several .c files) in the tree, # which is a change that doesn't affect other translation units other than # the file modified. "Make" will notice the change of file creation date # and update the object files automatically. # All you need to do next is reinstall the affected kernel binaries # (the monolith or the respective moodule). If you're building some modules out of tree (which appears to be turning into a no-no recently) you need to have "modversions.h" already created in the tree you're building against. I.e., your tree already needs to be past "make modules" (if not past "make modules-install").