Skip to main content
Topic: Buildig a module-less kernel (Read 782 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Buildig a module-less kernel

Hello everyone,

I try to explore linux and specially his kernel. I have succeed to compile a regular kernel and to remove a lot of unnecessary features. I am to the point where I have even transform all modules into a built-in features.
So my plan is to build a module-less or monolithic kernel.
When i searched how to do it i was surprised to see very little topic on the subject the only one i found in gentoo was extremly short (5 lines no more).

My issue is to succeed to compile a complete kernel. With menu makeconfig i have disable modules and after failing with this message :
Code: [Select]
***
*** The present kernel configuration has modules disabled.
*** To use the module feature, please run "make menuconfig" etc.
*** to enable CONFIG_MODULES.
***
make: *** [Makefile:1771 : modules_install] Erreur 1

I create a patch to allow me to proceed.

So there is my actual files :

my patch "moduleless.patch" :
Code: [Select]
##
##  Allowing a moduleless kernel. Made for kernel 6.0.3
##

diff --unified --recursive --text --color a/include/config/auto.conf b/include/config/auto.conf
--- a/include/config/auto.conf
+++ b/include/config/auto.conf
@@ -213,7 +213,6 @@
 CONFIG_USB=y
 CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
 CONFIG_ACPI_PCI_SLOT=y
-CONFIG_MODULES_USE_ELF_RELA=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_UBSAN_ARRAY_BOUNDS=y
 CONFIG_WLAN_VENDOR_REALTEK=y
@@ -1647,7 +1646,6 @@
 CONFIG_KVM_XFER_TO_GUEST_WORK=y
 CONFIG_SERIAL_8250_PERICOM=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
 CONFIG_CPU_SUP_HYGON=y
 CONFIG_DMA_OPS=y
 CONFIG_NET_EGRESS=y


diff --unified --recursive --text --color a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@
 VERSION = 6
 PATCHLEVEL = 0
 SUBLEVEL = 3
-EXTRAVERSION =
-NAME = Hurr durr I'ma ninja sloth
+EXTRAVERSION = custom
+NAME = Hurr durr I'm a crazy ninja sloth
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -648,7 +648,7 @@
 # Decide whether to build built-in, modular, or both.
 # Normally, just do built-in.
 
-KBUILD_MODULES :=
+KBUILD_MODULES := 0
 KBUILD_BUILTIN := 1
 
 # If we have only "make modules", don't compile built-in objects.
@@ -661,11 +661,11 @@
 # Just "make" or "make all" shall build modules as well
 
 ifneq ($(filter all modules nsdeps %compile_commands.json clang-%,$(MAKECMDGOALS)),)
-  KBUILD_MODULES := 1
+  KBUILD_MODULES := 0
 endif
 
 ifeq ($(MAKECMDGOALS),)
-  KBUILD_MODULES := 1
+  KBUILD_MODULES := 0
 endif
 
 export KBUILD_MODULES KBUILD_BUILTIN
@@ -1142,7 +1142,7 @@
 # For the kernel to actually contain only the needed exported symbols,
 # we have to build modules as well to determine what those symbols are.
 # (this can be evaluated only once include/config/auto.conf has been included)
-KBUILD_MODULES := 1
+KBUILD_MODULES := 0
 
 autoksyms_recursive: descend modules.order
  $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
@@ -1716,8 +1716,8 @@
 # in the basis kernel ordinary make commands (without M=...) must be used.
 
 # We are always building only modules.
-KBUILD_BUILTIN :=
-KBUILD_MODULES := 1
+KBUILD_BUILTIN := 1
+KBUILD_MODULES := 0
 
 build-dirs := $(KBUILD_EXTMOD)
 $(MODORDER): descend
@@ -1788,7 +1788,7 @@
  @echo >&2 '*** To use the module feature, please run "make menuconfig" etc.'
  @echo >&2 '*** to enable CONFIG_MODULES.'
  @echo >&2 '***'
- @exit 1
+ @exit 0
 
 endif # CONFIG_MODULES
 
@@ -1827,7 +1827,7 @@
  $(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$m;) } > $(MODORDER)
  $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
 
-KBUILD_MODULES := 1
+KBUILD_MODULES := 0
 
 export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod_prefix), $(single-no-ko))
 
@@ -1838,7 +1838,7 @@
 endif
 
 ifndef CONFIG_MODULES
-KBUILD_MODULES :=
+KBUILD_MODULES := 0
 endif
 
 # Handle descending into subdirectories listed in $(build-dirs)

and my pkgbuild :

Code: [Select]
pkgbase=linux-custom
pkgver=6.0.3
pkgrel=3
pkgdesc='Linux kernel and modules'
url="https://www.kernel.org/"
arch=(x86_64)
license=(GPL2)
makedepends=(
  bc kmod libelf pahole cpio perl tar xz
  xmlto graphviz imagemagick cpio
)
options=('!strip')
_srcname=linux-$pkgver
source=(
  https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/${_srcname}.tar.{xz,sign}
  config         # the main kernel config file
  0001-ZEN-Add-sysctl-and-CONFIG-to-disallow-unprivileged-C.patch
  0003-iommu_intel_do_deep_dma-unmapping_to_avoid_kernel-flooding.patch
  moduleless.patch
)
validpgpkeys=(
  'ABAF11C65A2970B130ABE3C479BE3E4300411886'  # Linus Torvalds
  '647F28654894E3BD457199BE38DBBDC86092693E'  # Greg Kroah-Hartman
)
# https://www.kernel.org/pub/linux/kernel/v5.x/sha256sums.asc
sha256sums=('b0d522241805794d8af3a67d331ba063a16496c6fb6d365d48f7ed78ee1c3dcf'
            'SKIP'
            '8dd9236334113c523007a237f6db93ea167b4c074c2be8ef733d027db6db584a'
            '17b9a8c2d0c02a8841c4b8d94a6ba0c8323e404bad19c71903a1ad665a25b1be'
            '864f299d3d990c98e1cc088d3a27661ae998ca2801cb025fa3dcdcdf5713e8ce'
            'fbd5e9dc23e74aead48b95e9819a49a9e05e9593c2375594e1eeb4c05001fba1')

export KBUILD_BUILD_HOST=artixlinux
export KBUILD_BUILD_USER=$pkgbase
export KBUILD_BUILD_TIMESTAMP="$(date -Ru${SOURCE_DATE_EPOCH:+d @$SOURCE_DATE_EPOCH})"


prepare() {
  cd $_srcname

  echo "Setting config..."
  cp ../config .config
  make  menuconfig  && make prepare
#  diff -u ../config .config || :

  echo "Setting version..."
  scripts/setlocalversion --save-scmversion
  echo "-$pkgrel" > localversion.10-pkgrel
  echo "${pkgbase#linux}" > localversion.20-pkgname

  local src
  for src in "${source[@]}"; do
    src="${src%%::*}"
    src="${src##*/}"
    [[ $src = *.patch ]] || continue
    echo "Applying patch $src..."
    patch -Np1 < "../$src"
  done


#return 1
  make -s kernelrelease > version
  echo "Prepared $pkgbase version $(<version)"
}

build() {
  cd $_srcname
  make
  make install
}

_package() {
  pkgdesc="The $pkgdesc kernel and modules"
  depends=(coreutils kmod initramfs)
  optdepends=('crda: to set the correct wireless channels of your country'
              'linux-firmware: firmware images needed for some devices')
  provides=(VIRTUALBOX-GUEST-MODULES WIREGUARD-MODULE)
  replaces=(wireguard)

  cd $_srcname
  local kernver="$(<version)"
  local modulesdir="$pkgdir/usr/lib/modules/$kernver"

  echo "Installing boot image..."
  # systemd expects to find the kernel here to allow hibernation
  # https://github.com/systemd/systemd/commit/edda44605f06a41fb86b7ab8128dcf99161d2344
  install -Dm644 "$(make -s image_name)" "$modulesdir/vmlinuz"

  # Used by mkinitcpio to name the kernel
  echo "$pkgbase" | install -Dm644 /dev/stdin "$modulesdir/pkgbase"

}

_package-headers() {
  pkgdesc="Headers and scripts for building modules for the $pkgdesc kernel"
  depends=(pahole)

  cd $_srcname
  local builddir="$pkgdir/usr/lib/modules/$(<version)/build"

  echo "Installing build files..."
  install -Dt "$builddir" -m644 .config Makefile System.map \
    localversion.* version vmlinux
  install -Dt "$builddir/kernel" -m644 kernel/Makefile
  install -Dt "$builddir/arch/x86" -m644 arch/x86/Makefile
  cp -t "$builddir" -a scripts

  # add objtool for external module building and enabled STACK_VALIDATION option
  install -Dt "$builddir/tools/objtool" tools/objtool/objtool

  # add xfs and shmem for aufs building
  mkdir -p "$builddir"/{fs/xfs,mm}

  echo "Installing headers..."
  cp -t "$builddir" -a include
  cp -t "$builddir/arch/x86" -a arch/x86/include
  install -Dt "$builddir/arch/x86/kernel" -m644 arch/x86/kernel/asm-offsets.s

  install -Dt "$builddir/drivers/md" -m644 drivers/md/*.h
  install -Dt "$builddir/net/mac80211" -m644 net/mac80211/*.h

  # https://bugs.archlinux.org/task/13146
  install -Dt "$builddir/drivers/media/i2c" -m644 drivers/media/i2c/msp3400-driver.h

  # https://bugs.archlinux.org/task/20402
  install -Dt "$builddir/drivers/media/usb/dvb-usb" -m644 drivers/media/usb/dvb-usb/*.h
  install -Dt "$builddir/drivers/media/dvb-frontends" -m644 drivers/media/dvb-frontends/*.h
  install -Dt "$builddir/drivers/media/tuners" -m644 drivers/media/tuners/*.h

  # https://bugs.archlinux.org/task/71392
  install -Dt "$builddir/drivers/iio/common/hid-sensors" -m644 drivers/iio/common/hid-sensors/*.h

  echo "Installing KConfig files..."
  find . -name 'Kconfig*' -exec install -Dm644 {} "$builddir/{}" \;

  echo "Removing unneeded architectures..."
  local arch
  for arch in "$builddir"/arch/*/; do
    [[ $arch = */x86/ ]] && continue
    echo "Removing $(basename "$arch")"
    rm -r "$arch"
  done

  echo "Removing documentation..."
  rm -r "$builddir/Documentation"

  echo "Removing broken symlinks..."
  find -L "$builddir" -type l -printf 'Removing %P\n' -delete

  echo "Removing loose objects..."
  find "$builddir" -type f -name '*.o' -printf 'Removing %P\n' -delete

  echo "Stripping build tools..."
  local file
  while read -rd '' file; do
    case "$(file -bi "$file")" in
      application/x-sharedlib\;*)      # Libraries (.so)
        strip -v $STRIP_SHARED "$file" ;;
      application/x-archive\;*)        # Libraries (.a)
        strip -v $STRIP_STATIC "$file" ;;
      application/x-executable\;*)     # Binaries
        strip -v $STRIP_BINARIES "$file" ;;
      application/x-pie-executable\;*) # Relocatable binaries
        strip -v $STRIP_SHARED "$file" ;;
    esac
  done < <(find "$builddir" -type f -perm -u+x ! -name vmlinux -print0)

  echo "Stripping vmlinux..."
  strip -v $STRIP_STATIC "$builddir/vmlinux"

  echo "Adding symlink..."
  mkdir -p "$pkgdir/usr/src"
  ln -sr "$builddir" "$pkgdir/usr/src/$pkgbase"
}


pkgname=("$pkgbase" "$pkgbase-headers" )
for _p in "${pkgname[@]}"; do
  eval "package_$_p() {
    $(declare -f "_package${_p#$pkgbase}")
    _package${_p#$pkgbase}
  }"
done

When i compile i have this warning who is more than a warning because my network is now a mess ... I am clearly not an expert but i'd like to learn so i may have make obvious mistakes.

Code: [Select]
==> WARNING: No modules were added to the image. This is probably not what you want.
==> Creating zstd-compressed initcpio image: /boot/initramfs-linux-Custs-fallback.img
==> WARNING: errors were encountered during the build. The image may not be complete.

What am i missing ?

Re: Buildig a module-less kernel

Reply #1
>So my plan is to build a module-less or monolithic kernel.

That's not what "monolithic kernel" means.

https://html.duckduckgo.com/html?q=monolithic%20kernel

Also I would suggest compiling your kernel straight from upstream and not using the ABS since I'm guessing somewhere something ( probably mkinitcpio ) expects a kernel with module loading support.

Re: Buildig a module-less kernel

Reply #2
Thanks for your answers.

sorry if i choose my word poorly. i meant to say an "all built-in" kernel, that why i use monolithic even if it's not totally correct.

In my pkgbuild posted previously the source is already :  https://cdn.kernel.org/pub/linux/kernel/XXX
is that what you are suggesting ?

I am going to look at mkinitcpio in details, here is my actual hooks

HOOKS="base udev autodetect modconf block keyboard keymap consolefont filesystems fsck"

 

Re: Buildig a module-less kernel

Reply #3
An update to my tests:

Thanks to  @Lancia  i manage to generate  an successful image with mkinitcpio.

Now things who remains to figure out :

* manage to integrate firmware in my module-less kernel. ( for example to incle intel/amd-ucode) . I try to integrate them by name the necessary firmware in the firmware > firmware build options, and it 's not working the kernel telling me for this file,  there is no rule to know what to do with it.
* see how far i can use KSPP recommendations ( see here for more :
https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings  )

If you have ideas or documentation for me to look, please don't hesitate.