Slackware Kernel HUGE and GENERIC

Here is a background on the difference between both flavors.
How you can switch from one to the other kernel from the Slackware package tree.

If you let Slackware installer makes the bootloader’s config, it will use the HUGE kernel. The documentation recommends that your switch afterwards on a GENERIC kernel.

This article will cover the switch from HUGE to GENERIC, but will also overlook the Initrd subject and giving some hint and advices.

Don’t be afraid, all is gonna be fine if you understand what you do ! ( do not just copy paste 😉 )

Background first

The HUGE kernel, as the name suggest, is big. Reason is that it has a lot of kernel modules directly built in it. You can see some of those modules as drivers for your hardware, the more you have, the more chance you will have a successful boot after installation.

On the other hand, you won’t probably need all those modules to make your machine works. That’s a goal of the GENERIC kernel, that are built with minimal hardware support, and loads dynamically modules when needed.

From my readings, I didn’t find a real technical reason not to keep the HUGE kernel for the lambda user except maybe the size of the Kernel on tiny machines ( around 40% bigger than the GENERIC )

$ ls -lh /boot/vmlinuz-*
-rw-r--r-- 1 root root 5.3M Jan  5 20:19 /boot/vmlinuz-4.14.12
lrwxrwxrwx 1 root root   23 Jan  5 18:32 /boot/vmlinuz-generic -> vmlinuz-generic-4.14.11
-rw-r--r-- 1 root root 5.3M Jan  3 03:06 /boot/vmlinuz-generic-4.14.11
lrwxrwxrwx 1 root root   20 Jan  5 18:32 /boot/vmlinuz-huge -> vmlinuz-huge-4.14.11
-rw-r--r-- 1 root root 8.3M Jan  3 20:11 /boot/vmlinuz-huge-4.14.11

Also, GENERIC kernels needs and initial ramdisk – initrd – to work.

GENERIC with its initrd has its utility of course other than the size, specifically it permits the 2 phases boot ability , than can be used for ( but not limited to) booting from an encrypted partition, or other special cases like RAID or NFS/diskless setup.

First phase is the bootloader initializing the ram disk prior and creates a temporary root partition to start the kernel . The ramdisk contains the modules and utility/tools.

Second phase is the kernel being able to load additional modules from the ram disk . When it’s done, the `real` root partition can be mounted from the real root partition location.

Obviously I won’t cover the encrypted partition case in that article, but in the encryption context: during the second phase, the kernel will load the encryption module and start the tool that will prompt you for the passphrase prior to mount the real root partition.

I’m not a power user  and  I must admit that I’ve changed to GENERIC not that long ago, just because I’ve never had a real reason to do so ( yes I didn’t followed the doc 😉 ).

The starting point for me was the need of the  GENERIC kernel to be able to use Docker on my machine.

What type of kernel am I using ?

That’s is a tricky question actually, and so far I’ve looked on the net, I couldn’t find a command that return the answer.

Clue/Hints

Instead, it’s more or less some hints about what you are running:

Uname is not really giving infos:

# uname -a
Linux ws1 4.14.11 #1 SMP Tue Jan 2 20:05:07 CST 2018 x86_64 Intel(R) Xeon(R) CPU D-1540 @ 2.00GHz GenuineIntel GNU/Linux

Content of /proc/cmdline will show the parameter given to kernel prior to load it. Here it shows just Linux … ok well it’s light but it’s usefull anyway.

# cat /proc/cmdline
auto BOOT_IMAGE=Linux ro root=801

LILO is the bootloader used by default on Slackware, and the BOOT_IMAGE return at least the ‘label’ of the entry: let’s check for that in /etc/lilo.conf

# Linux bootable partition config begins
image = /boot/vmlinuz
  root = /dev/sda1
  label = Linux
  read-only

It’s not obvious if you don’t know it…. but as GENERIC requires an initrd,  it should be present. No sign of an initrd there => very good chances that your are running HUGE.

Another way, trying to find something that is different between HUGE and GENERIC. As a good example, I’ve learned that the support for your filesystem is build-in for the HUGE kernel and compiled as a module in case of the GENERIC.

I use an EXT4 Filesystem and I’m running the HUGE kernel at the moment, so let’s look in the kernel config setting for that FS.

# zgrep 'CONFIG_EXT4_FS=' /proc/config.gz
CONFIG_EXT4_FS=y
#

On a GENERIC kernel:

# zgrep 'CONFIG_EXT4_FS=' /proc/config.gz
CONFIG_EXT4_FS=m
#

Here is a small bash script – genericOrHugeKernel.sh – that checks how the kernel has been configured for the filesystem ( and avoid me to remember the command).

#! /bin/bash

zgrep -q 'CONFIG_EXT4_FS=y' /proc/config.gz && IsGeneric=0 || IsGeneric=1
echo "IsKernelGeneric = $IsGeneric"

Running on a HUGE kernel, the script tells you so:

# ./dev/scripts/genericOrHugeKernel.sh
IsKernelGeneric = 0
#

Bottom line

From here … giving a proper name to your kernel might be a good idea, though it’s not 100% guarantee that it’s true. You can only complain to yourself if it’s not 😉

When running kernels from Slackware tree, I chose to label the GENERIC kernel entry like gen-X.Y.Z , while keeping the slackware ‘default’ Linux + symlink for the HUGE.

For out-of-tree kernel, I choose a different name but it’s another article.

 $ cat /proc/cmdline 
BOOT_IMAGE=gen-4.14.11 ro root=801

Following my naming convention, I’m pretty confident to run Slackware GENERIC 4.14.11 kernel.

Switching HUGE to GENERIC

Slackpkg Kernel Package

Slackware ships both version with each update, the latest kernel on Current was 4.14.11 at time of writing. Below is what I got after search packages with kernel in the name.

# slackpkg search kernel

Looking for kernel in package list. Please wait... DONE

The list below shows all packages with name matching "kernel".

[ installed ] - kernel-firmware-20180102git-noarch-1
[ installed ] - kernel-generic-4.14.11-x86_64-1
[ installed ] - kernel-huge-4.14.11-x86_64-2
[ installed ] - kernel-modules-4.14.11-x86_64-1
[ installed ] - kernel-headers-4.14.11-x86-1
[ installed ] - kernel-source-4.14.11-noarch-1

Make sure you have the generic and modules packages installed 😉

Kernels are stored in /boot , vmlinuz is the name of the Linux kernel executable. You can see below that you have the 2 kernels, vmlinuz-huge-4.14.11 and vmlinuz-generic-4.14.11

Symlinks are here I guess simplify the installer’s job with LILO. Aka the installer never touch /etc/lilo.conf file, it just changes the symlink and update LILO.

# ls -l /boot/vmlinuz*
lrwxrwxrwx 1 root root 20 Jan 5 18:32 /boot/vmlinuz -> vmlinuz-huge-4.14.11
lrwxrwxrwx 1 root root 23 Jan 5 18:32 /boot/vmlinuz-generic -> vmlinuz-generic-4.14.11
-rw-r--r-- 1 root root 5482256 Jan 3 03:06 /boot/vmlinuz-generic-4.14.11
lrwxrwxrwx 1 root root 20 Jan 5 18:32 /boot/vmlinuz-huge -> vmlinuz-huge-4.14.11
-rw-r--r-- 1 root root 8636176 Jan 3 20:11 /boot/vmlinuz-huge-4.14.11
#

Speaking of the lilo configuration, by default, Slackware put an entry only for the HUGE Kernel. You can see that image is pointing to /boot/vmlinuz which is a symlinks to vmlinuz-huge-X.Y.Z

# cat /etc/lilo.conf

<--- SNIP -->

# End LILO global section                                                                                                                 
# Linux bootable partition config begins                                                                                                  
image = /boot/vmlinuz                                                                                                                     
  root = /dev/sda1                                                                                                                        
  label = Linux                                                                                                                           
  read-only                                                                                                                               
                                       
# Linux bootable partition config ends

Creating the Initial Ramdisk – initrd

As explained earlier, the GENERIC kernel needs an initrd to work, and is not part of the kernel installation via slackpkg. I suppose the reason is that the GENERIC needs an initrd tailored for -your- machine and automate the initrd creation process would be pretty hard.

If you check in /boot/, you will find the initrd README, which you can obviously read of course 🙂

 # ls /boot/ | grep initrd
README.initrd@
#

The creation is helped thanks to 2 tools:

  • mkinitrd , it should be already installed, if not, feel free to use slackpkg for that.
# slackpkg search mkinitrd

Looking for mkinitrd in package list. Please wait... DONE

The list below shows all packages with name matching "mkinitrd".

[ installed ] - mkinitrd-1.4.11-x86_64-5

You can search specific files using "slackpkg file-search file".
  •  mkinitrd_command_generator.sh, which is a bash script that generate for you a proper command to use with mkinird.
# /usr/share/mkinitrd/mkinitrd_command_generator.sh
#
# mkinitrd_command_generator.sh revision 1.45
#
# This script will now make a recommendation about the command to use
# in case you require an initrd image to boot a kernel that does not
# have support for your storage or root filesystem built in
# (such as the Slackware 'generic' kernels').
# A suitable 'mkinitrd' command will be:

mkinitrd -c -k 4.14.11 -f ext4 -r /dev/sda1 -m xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:jbd2:mbcache:ext4 -u -o /boot/initrd.gz

The only thing I’ve changed from the proposed command, is that I always add the kernel version in the output initrd file. In that case the command will be something like:

mkinitrd -c -k 4.14.11 -f ext4 -r /dev/sda1 -m <lots of modules here> -u -o /boot/initrd-4.14.11.gz

When executing the command:

# mkinitrd -c -k 4.14.11 -f ext4 -r /dev/sda1 -m xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:hid:usbhid:i2c-hid:hid_generic:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:jbd2:mbcache:ext4 -u -o /boot/initrd-4.14.11.gz
OK: /lib/modules/4.14.11/kernel/drivers/usb/host/xhci-hcd.ko added.
OK: /lib/modules/4.14.11/kernel/drivers/usb/host/xhci-pci.ko added.
OK: /lib/modules/4.14.11/kernel/drivers/usb/host/ehci-hcd.ko added.

<--- Output suppressed -->

OK: /lib/modules/4.14.11/kernel/fs/jbd2/jbd2.ko added.
OK: /lib/modules/4.14.11/kernel/fs/mbcache.ko added.
OK: /lib/modules/4.14.11/kernel/fs/ext4/ext4.ko added.
51688 blocks
/boot/initrd-4.14.11.gz created.
Be sure to run lilo again if you use it.
# 

Indeed, the initrd is located in /boot/ as stated:

# ls /boot/ | grep initrd
README.initrd@
initrd-4.14.11.gz
initrd-tree/
#

Also, if you look inside /boot/initrd-tree/ , you will find many things, including some binaries that can help during the second phase boot. So yeah, initrd is not just about loading modules.

 # ls /boot/initrd-tree/ -lasth
total 96K
4.0K drwxr-xr-x  4 root root 4.0K Jan 13 10:36 ../
4.0K drwxr-xr-x  2 root root 4.0K Jan 11 21:04 lib64/
4.0K drwxr-xr-x 14 root root 4.0K Jan 11 21:04 ./
4.0K drwxr-xr-x  3 root root 4.0K Jan 11 21:04 usr/
4.0K -rwxr-xr-x  1 root root  636 Jan 11 21:04 load_kernel_modules*
4.0K drwxr-xr-x  2 root root 4.0K Jan 11 21:04 sbin/
4.0K -rw-r--r--  1 root root   24 Jan 11 21:04 initrd-name
4.0K -rw-r--r--  1 root root  285 Jan 11 21:04 command_line
4.0K -rw-r--r--  1 root root    5 Jan 11 21:04 rootfs
4.0K -rw-r--r--  1 root root   10 Jan 11 21:04 rootdev
4.0K drwxr-xr-x  2 root root 4.0K Jan 11 21:04 dev/
4.0K drwxr-xr-x  4 root root 4.0K Jan  3 03:08 lib/
 16K -rwxr-xr-x  1 root root  13K Oct  9 20:06 init*
4.0K drwxr-xr-x  2 root root 4.0K Aug 21  2011 run/
4.0K drwxr-xr-x  3 root root 4.0K Apr  1  2010 etc/
   0 -rw-r--r--  1 root root    0 Dec 19  2009 lukskey
4.0K drwxr-xr-x  2 root root 4.0K Nov 26  2008 root/
4.0K drwxr-xr-x  2 root root 4.0K Nov 26  2008 bin/
   0 -rw-r--r--  1 root root    0 Apr  3  2008 keymap
   0 -rw-r--r--  1 root root    0 Feb 20  2008 resumedev
4.0K -rw-r--r--  1 root root    2 Oct  9  2007 wait-for-root
   0 -rw-r--r--  1 root root    0 Jun 27  2007 luksdev
4.0K drwxr-xr-x  2 root root 4.0K Jun  3  2007 sys/
4.0K drwxr-xr-x  2 root root 4.0K Mar  1  2004 proc/
4.0K drwxr-xr-x  2 root root 4.0K Mar  1  2004 mnt/
#

Adding the kernel entry in LILO config

Now that we have the initrd created, lets add an entry in /etc/lilo.conf . As a side note, the order of the entries matters. LILO will boot on the first entry by default.

Bellow is shown only the partition config from the LILO configuration file.

  • Image: Location of the kernel executable
  • Initrd: Location of the initrd file for that kernel.
  • Root: Location of the root (/) partition
  • Label: You can put what you want here, this will be seen on the boot menu and in the out of cat /proc/cmdline

Do not remove the HUGE kernel entry, if the GENERIC failed to load for whatever reason, then you can just reboot again on the HUGE to troubleshoot and fix.

Without a ‘working backup’ kernel, you would need to use a liveCD/USB/Netboot for that.

# Linux bootable partition config begins                                                                                               
image = /boot/vmlinuz                                                                                                                  
  root = /dev/sda1                                                                                                                     
  label = Linux                                                                                                                        
  read-only                                                                                                                            
                                                                                                                                       
image = /boot/vmlinuz-generic-4.14.11                                                                                                  
  initrd = /boot/initrd-4.14.11.gz                                                                                                     
  root = /dev/sda1                                                                                                                     
  label = gen-4.14.11                                                                                                                  
  read-only                                                                                                                            
                                                                                                                                       
# Linux bootable partition config ends

My personal way of doing this is keeping the HUGE as the first and default entry, and manually boot the GENERIC until I validated the GENERIC.

Afterward, I either change the order or a use the default=<label> setting of lilo.conf to boot the GENERIC as default.

How you do it is really up to your personal taste… I tend to adapt this to the situation, on my laptop I run only kernels from the Slackware tree so two entries to swap is not big deal. My laptop config is also pretty stable ( no fancy config )

On the other hand, with my workstation, I have more kernels to play with and using the default setting is lazier easier

Then you just need to run lilo -v to update the bootloader’s config and pay attention to errors.

 # lilo -v
LILO version 24.2 (released 22-November-2015)
  * Copyright (C) 1992-1998 Werner Almesberger  (until v20)
  * Copyright (C) 1999-2007 John Coffman  (until v22)
  * Copyright (C) 2009-2015 Joachim Wiedorn  (since v23)
This program comes with ABSOLUTELY NO WARRANTY. This is free software 
distributed under the BSD License (3-clause). Details can be found in 
the file COPYING, which is distributed with this software.

Reading boot sector from /dev/sda
Using BITMAP secondary loader
Calling map_insert_data
Mapping bitmap file /boot/slack.bmp
Warning: Video adapter does not support VESA BIOS extensions needed for
  display of 256 colors.  Boot loader will fall back to TEXT only operation.
Calling map_insert_file

Boot image: /boot/vmlinuz -> vmlinuz-huge-4.14.11
Added Linux  *

Boot image: /boot/vmlinuz-generic-4.14.11
Mapping RAM disk /boot/initrd-4.14.11.gz
The initial RAM disk will be loaded in the high memory above 16M.
Added gen-4.14.11  +

Writing boot sector.
/boot/boot.0800 exists - no boot sector backup copy made.
One warning was issued.
# 

Both entries have been correctly added, which is nice.

You can also see that there was one Warning, related to my video adapter not supporting a certain config. I didn’t find a fix for that…. but the only consequence is stated:

Boot loader will fall back to TEXT only operation.

This means that I won’t have the pretty LILO boot menu with the Slackware Logo ( 🙁 ) to show the available kernels or the timeout. Instead I will have the LILO BOOT: prompt directly. If it’s also your case, then it’s not big deal.

  • LILO default timeout is 120secs and will boot the first kernel entry if you don’t touch any key.  You can edit the timeout =<tenth of second> setting in lilo.conf
  • [ENTER] will boot the first kernel entry
  • [TAB] will show the different available entries. Type fully the name of the entry without typo then [enter] to boot that kernel.

You can also switch to the classic LILO menu if you prefer.

Time to reload

If you are okay, you can reload your machine.

I cannot show you the generated menu, so here is a shot from the LILO prompt right after the BIOS POST, the available kernel matches the lilo.conf and the kernel loading.

LILO prompt, kernel loading and boot start

If  everything goes as expected, you will eventually get to your login prompt.

Checking if I run the GENERIC kernel below with tools we have seen earlier

# 
# cat /proc/cmdline 
BOOT_IMAGE=gen-4.14.11 ro root=801
# 
# zgrep 'CONFIG_EXT4_FS=' /proc/config.gz
CONFIG_EXT4_FS=m
# 
# ./dev/scripts/genericOrHugeKernel.sh 
IsKernelGeneric = 1
# 

If the boot fails, common boot error is hitting KERNEL PANIC. It can be various messages with various root-causes.

It can be hard to pinpoint the cause as you can’t scroll the screen up anymore….my advice is  to get photo/text of the message, reload to the HUGE kernel and start troubleshooting.

 

Sources

Initial Ram Disk – initrd

IBM article on initrd: https://www.ibm.com/developerworks/library/l-initrd/index.html

Wikipedia initial ramdisk page:  https://en.wikipedia.org/wiki/Initial_ramdisk

Initrd man page: https://linux.die.net/man/4/initrd

inird README: http://slackware.mirrors.ovh.net/ftp.slackware.com/slackware-current/README.initrd

LQ forum thread about checking which kernel you are using: https://www.linuxquestions.org/questions/slackware-14/kernel-huge-or-generic-which-is-running-4175597213/

Kernel

Official Documentation : https://docs.slackware.com/slackbook:booting and https://docs.slackware.com/slackware:beginners_guide#switch_to_a_generic_kernel

 

One thought on “Slackware Kernel HUGE and GENERIC”

Leave a Reply

Your email address will not be published. Required fields are marked *