Code Monkey home page Code Monkey logo

akms's Introduction

Alpine Kernel Module Support (AKMS)

AKMS is a tool that enables building out-of-tree (external) Linux kernel modules from source for each installed kernel on the user’s system in an automated and organized fashion. The concept is to have kernel modules automatically rebuilt when a new kernel version is installed.

AKMS is inspired by DKMS (Dynamic Kernel Module Support) used on many Linux distributions. It has been designed specifically for Alpine Linux and APK; implemented with simplicity, reliability, and security in mind.

See the following manual pages for more information.

Requirements

Runtime:
  • POSIX-sh compatible shell with pipefail (e.g. Busybox ash, ZSH, bash, …)

  • env, grep, install, mount, umount, sed, su, tr (Busybox or GNU)

  • depmod from kmod

  • apk-tools

  • bubblewrap

  • Linux kernel with OverlayFS and namespaces

Build:

Installation

Install package akms on Alpine Linux v3.15 or later:

apk add akms

License

This project is licensed under MIT License. For the full text of the license, see the LICENSE file.

akms's People

Contributors

jirutka avatar nekopsykose avatar ptrcnull avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

sodomon2 ptrcnull

akms's Issues

akms fails if the kernel is not in aports

akms gets confused if the target kernel is not in aports, since it tries to install the -dev pacakge for the kernel (even if that package is already installed...):

❯ doas apk add ~/packages/community/x86_64/linux-edge{,-dev}-5.16-r0.apk
...
Executing busybox-1.35.0-r1.trigger
Executing akms-0.2.0-r0.trigger
akms: Building module librem-ec-acpi/0.91 for kernel 5.16.0-0-edge
akms: ERROR: Package linux-edge-dev=5.16.0-r0 is not available in the repositories!

edit: no, I had the -k option wrong.. it fails for the same reason above if I use the right version (5.16.0-0 in this case)

though it seems fine if I run akms build -k manually (presumably because it doesn't try to install deps?)

❯ doas akms build /usr/src/librem-ec -k 5.16-0-edge -r
akms: Building module librem-ec-acpi/0.91 for kernel 5.16-0-edge
make: Entering directory '/usr/src/linux-headers-5.16-0-edge'
  CC [M]  /var/lib/akms/5.16-0-edge/librem-ec-acpi/0.91/build/librem_ec_acpi.o
  MODPOST /var/lib/akms/5.16-0-edge/librem-ec-acpi/0.91/build/Module.symvers
  CC [M]  /var/lib/akms/5.16-0-edge/librem-ec-acpi/0.91/build/librem_ec_acpi.mod.o
  LD [M]  /var/lib/akms/5.16-0-edge/librem-ec-acpi/0.91/build/librem_ec_acpi.ko
make: Leaving directory '/usr/src/linux-headers-5.16-0-edge'
akms: Module librem-ec-acpi/0.91 for 5.16-0-edge is built successfully

Fix problem with loading overlay module right after kernel is upgraded

apk upgrade
(1/8) Upgrading connman (1.40-r4 -> 1.40-r5)
Executing connman-1.40-r5.post-upgrade
(2/8) Upgrading connman-openrc (1.40-r4 -> 1.40-r5)
(3/8) Upgrading connman-nftables (1.40-r4 -> 1.40-r5)
(4/8) Upgrading ead (1.15-r1 -> 1.16-r1)
(5/8) Upgrading ead-openrc (1.15-r1 -> 1.16-r1)
(6/8) Upgrading iwd (1.15-r1 -> 1.16-r1)
(7/8) Upgrading iwd-openrc (1.15-r1 -> 1.16-r1)
(8/8) Upgrading linux-lts (5.10.55-r0 -> 5.10.56-r0)
Executing busybox-1.33.1-r3.trigger
Executing kmod-29-r0.trigger
depmod: WARNING: could not open modules.order at /lib/modules/5.10.55-0-lts: No such file or directory
depmod: WARNING: could not open modules.builtin at /lib/modules/5.10.55-0-lts: No such file or directory
Executing kernel-hooks-0.1-r1.trigger
kernel-hooks: executing hook 20-akms.hook (lts, 5.10.56-0, 5.10.55-0)
akms: Uninstalling module all (5_git20210716-r0) from kernel 5.10.55-0-lts
akms: Building module rtw89 5_git20210716-r0 for kernel 5.10.56-0-lts
mount: mounting overlay on /tmp/akms/1628117069/overlay failed: No such device
akms: ERROR: Failed to mount OverlayFS on top of / at /tmp/akms/1628117069/overlay
umount: can't unmount /tmp/akms/1628117069/overlay: Invalid argument
akms: ERROR: Failed to umount root overlay at /tmp/akms/1628117069/overlay, unmount it and remove manually!
kernel-hooks: ERROR: hook 20-akms.hook failed, skipping hooks for linux-lts
Executing dbus-1.12.20-r2.trigger
Executing mkinitfs-3.5.0-r0.trigger
==> initramfs: creating /boot/initramfs-lts
OK: 1274 MiB in 270 packages
akms: ERROR: Failed to mount OverlayFS on top of / at /tmp/akms/1628117069/overlay

^
This actually means that mount failed to load overlay module because /lib/modules/$(uname -r) has been already removed by the upgrade.

can't load module: "disagrees about version of symbol module_layout"

I find myself using AKMS as part of installing acpi_call-src package. The module builds, but won't load:

# akms --rebuild install all
akms: Building module acpi_call/1.2.2-r0 for kernel 5.15.115-0-lts
make: Entering directory '/usr/src/linux-headers-5.15.115-0-lts'
  CC [M]  /var/lib/akms/5.15.115-0-lts/acpi_call/1.2.2-r0/build/acpi_call.o
  MODPOST /var/lib/akms/5.15.115-0-lts/acpi_call/1.2.2-r0/build/Module.symvers
  CC [M]  /var/lib/akms/5.15.115-0-lts/acpi_call/1.2.2-r0/build/acpi_call.mod.o
  LD [M]  /var/lib/akms/5.15.115-0-lts/acpi_call/1.2.2-r0/build/acpi_call.ko
make: Leaving directory '/usr/src/linux-headers-5.15.115-0-lts'
akms: Installing module acpi_call 1.2.2-r0 for kernel 5.15.115-0-lts
akms: Module acpi_call/1.2.2-r0 for 5.15.115-0-lts installed successfully

# modprobe acpi_call
modprobe: ERROR: could not insert 'acpi_call': Exec format error

The error is located in dmesg:

acpi_call: disagrees about version of symbol module_layout

I've checked the following:

  • Alpine Linux up-to-date (3.17.3)
  • Running kernel matches installed kernel
  • Kernel -dev package installed
  • Cleared /var/lib/akms directory
  • Reboots

There's not really many controls here, so I've run out of things to try, and mostly this system is a default Alpine install. The differences are an encrypted partition layout and EFI boot process using SYSLINUX.

Some more system information:

# cat /etc/alpine-release
3.17.3

# akms status
5.15.115-0-lts  acpi_call       1.2.2-r0        installed

# uname -a
Linux tamla 5.15.115-0-lts #1-Alpine SMP Mon, 05 Jun 2023 10:22:35 +0000 x86_64 GNU/Linux

# cd /var/lib/akms/5.15.115-0-lts/acpi_call/1.2.2-r0/modules
# file acpi_call.ko.gz
acpi_call.ko.gz: gzip compressed data, max compression, from Unix, original size modulo 2^32 18808
# ls -l acpi_call.ko.gz
-rw-r--r-- 1 root root 5257 Jun  7 10:07 acpi_call.ko.gz

Fix builddir not available after build failed

The problem is that it’s on the overlay.

akms: ERROR: Failed to build module rtw89 5_git20210716-r0 for 5.10.55-0-virt
akms: ERROR: examine /tmp/akms/1628025705/overlay/var/lib/akms/5.10.55-0-virt/rtw89/5_git20210716-r0/build

cannot compile bcmwl-kernel-source_6.30.223.271+bdcom-0ubuntu10~22.04.1_amd64

how to compile bcmwl-kernel-source_6.30.223.271+bdcom-0ubuntu10~22.04.1_amd64 ?

it's copy from install media of ubuntu. usually i use it with dkms to get my bcm43142 wifi card to work.

KBUILD_NOPEDANTIC=1 make -C /lib/modules/`uname -r`/build M=`pwd`
CFG80211 API is prefered for this kernel version
Using CFG80211 API
  CC [M]  /akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.o
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_dma_alloc_consistent':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:603:14: error: implicit declaration of function 'pci_alloc_consistent'; did you mean 'osl_dma_alloc_consistent'? [-Werror=implicit-function-declaration]
  603 |         va = pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap);
      |              ^~~~~~~~~~~~~~~~~~~~
      |              osl_dma_alloc_consistent
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:603:12: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
  603 |         va = pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap);
      |            ^
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_dma_free_consistent':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:616:9: error: implicit declaration of function 'pci_free_consistent'; did you mean 'osl_dma_free_consistent'? [-Werror=implicit-function-declaration]
  616 |         pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa);
      |         ^~~~~~~~~~~~~~~~~~~
      |         osl_dma_free_consistent
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_dma_map':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:626:38: error: 'PCI_DMA_TODEVICE' undeclared (first use in this function); did you mean 'DMA_TO_DEVICE'?
  626 |         dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
      |                                      ^~~~~~~~~~~~~~~~
      |                                      DMA_TO_DEVICE
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:626:38: note: each undeclared identifier is reported only once for each function it appears in
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:626:56: error: 'PCI_DMA_FROMDEVICE' undeclared (first use in this function); did you mean 'DMA_FROM_DEVICE'?
  626 |         dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
      |                                                        ^~~~~~~~~~~~~~~~~~
      |                                                        DMA_FROM_DEVICE
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:659:17: error: implicit declaration of function 'pci_map_single'; did you mean 'dma_map_single'? [-Werror=implicit-function-declaration]
  659 |         return (pci_map_single(osh->pdev, va, size, dir));
      |                 ^~~~~~~~~~~~~~
      |                 dma_map_single
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_dma_unmap':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:668:38: error: 'PCI_DMA_TODEVICE' undeclared (first use in this function); did you mean 'DMA_TO_DEVICE'?
  668 |         dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
      |                                      ^~~~~~~~~~~~~~~~
      |                                      DMA_TO_DEVICE
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:668:56: error: 'PCI_DMA_FROMDEVICE' undeclared (first use in this function); did you mean 'DMA_FROM_DEVICE'?
  668 |         dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
      |                                                        ^~~~~~~~~~~~~~~~~~
      |                                                        DMA_FROM_DEVICE
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:669:9: error: implicit declaration of function 'pci_unmap_single'; did you mean 'dma_unmap_single'? [-Werror=implicit-function-declaration]
  669 |         pci_unmap_single(osh->pdev, (uint32)pa, size, dir);
      |         ^~~~~~~~~~~~~~~~
      |         dma_unmap_single
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_reg_map':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:945:17: error: implicit declaration of function 'ioremap_nocache'; did you mean 'ioremap_cache'? [-Werror=implicit-function-declaration]
  945 |         return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
      |                 ^~~~~~~~~~~~~~~
      |                 ioremap_cache
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:945:17: warning: returning 'int' from a function with return type 'void *' makes pointer from integer without a cast [-Wint-conversion]
  945 |         return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c: In function 'osl_os_get_image_block':
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:1079:35: warning: passing argument 2 of 'kernel_read' makes pointer from integer without a cast [-Wint-conversion]
 1079 |         rdlen = kernel_read(fp, fp->f_pos, buf, len);
      |                                 ~~^~~~~~~
      |                                   |
      |                                   loff_t {aka long long int}
In file included from ./include/linux/huge_mm.h:8,
                 from ./include/linux/mm.h:745,
                 from /akms/bcmwl-6.30.223.271+bdcom/src/include/linuxver.h:65,
                 from /akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:25:
./include/linux/fs.h:3033:43: note: expected 'void *' but argument is of type 'loff_t' {aka 'long long int'}
 3033 | extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
      |                                           ^~~~~~
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:1079:44: warning: passing argument 3 of 'kernel_read' makes integer from pointer without a cast [-Wint-conversion]
 1079 |         rdlen = kernel_read(fp, fp->f_pos, buf, len);
      |                                            ^~~
      |                                            |
      |                                            char *
./include/linux/fs.h:3033:51: note: expected 'size_t' {aka 'long unsigned int'} but argument is of type 'char *'
 3033 | extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
      |                                                   ^~~~~~
/akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.c:1079:49: warning: passing argument 4 of 'kernel_read' makes pointer from integer without a cast [-Wint-conversion]
 1079 |         rdlen = kernel_read(fp, fp->f_pos, buf, len);
      |                                                 ^~~
      |                                                 |
      |                                                 int
./include/linux/fs.h:3033:59: note: expected 'loff_t *' {aka 'long long int *'} but argument is of type 'int'
 3033 | extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
      |                                                           ^~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:250: /akms/bcmwl-6.30.223.271+bdcom/src/shared/linux_osl.o] Error 1
make[1]: *** [Makefile:2014: /akms/bcmwl-6.30.223.271+bdcom] Error 2
make: *** [Makefile:140: all] Error 2

Modules fail to build with restrictive umask

Setup:

  • akms 0.1.1 (Alpine)
  • have umask set to 077
  • try building anything directly with akms, fails with "bwrap: Can't find source path /tmp/akms/<timestamp>/overlay: Permission denied"

Looks like directories created by script are just not readable by akms user. Happy to provide more info if needed.

Login shell is used when building modules

AKMS uses su -l to switch to a build user. If a system has custom "/etc/profile", unrelated actions might be executed during the build process. It could create confusion (e.g., print unrelated messages) or interfere with AKMS (by setting variables to unexpected values).

su -l could be avoided by using --clearenv/--setenv from bubblewrap (or env -i) and setting variables manually. Looks like setting PATH to "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin" is enough for simple modules, however more variables might be needed in some cases?

EDIT: It might be simpler to clear environment and then execute commands in a new non-login shell. However, it might complicate argument handling in "akms-runas".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.