GithubHelp home page GithubHelp logo

Comments (4)

sgielen avatar sgielen commented on July 24, 2024

I consider it mostly outside of the scope of this project but I'd be happy to help regardless. In principle, missing kernel modules are a problem of the rpi-firmware project, since they don't publish additional modules or even their own kernel headers.

First, you'll need the kernel module itself. Perhaps someone already published it somewhere for the armv8 kernel from the rpi firmware. If you already have one, you can write it to /lib/modules/$(uname -r)/extra, run depmod and you should be able to just run modprobe.

I had to build a kernel module of my own recently, I'll share some of the steps and hopefully get you going a long way.

Since I had no cross compilation toolchain and didn't want to compile on the host, I started a Pod on the running k3s cluster:

apiVersion: v1
kind: Pod
metadata:
  name: buildpod
spec:
  volumes:
  - name: modules
    hostPath:
      path: /lib/modules
  containers:
    - name: buildpod
      image: ubuntu:bionic
      stdin: true
      tty: true
      securityContext:
        privileged: true
      volumeMounts:
      - name: modules
        mountPath: /lib/modules
  nodeSelector:
    kubernetes.io/hostname: [the hostname of the node you want the kernel module for]

I ran this Pod and used kubectl exec -ti buildpod bash to get a shell inside it. Note that it's privileged and has read-write access to /lib/modules of the host.

First, I installed the necessary tools:

# apt-get update
# apt-get install -y git bc bison flex libssl-dev sudo wget python jq build-essential libncurses5-dev kmod gcc-8

Then, downloaded the rpi-source tool which retrieves kernel sources for the exact kernel you're running currently. If you don't know your $FIRMWAREVER anymore, you can look up which Raspberry Pi firmware conforms to your Linux kernel version by going to https://github.com/raspberrypi/firmware/tree/1.20210201/modules and changing the tag version until you've found your kernel version.

# wget https://raw.githubusercontent.com/RPi-Distro/rpi-source/master/rpi-source -O rpi-source
# chmod +x rpi-source
# ./rpi-source -q --tag-update

# mkdir -p $(dirname /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz)
# FIRMWAREVER=1.20190925
# COMMIT=$(wget -qO- https://api.github.com/repos/raspberrypi/firmware/commits/$FIRMWAREVER | jq -r '.sha')
# echo "firmware as of $COMMIT" | gzip -c > /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz

In my case, I had to trick the tool into configuring the kernel source tree correctly, since it assumed we're running arm32 but this project uses arm64 instead. This causes it to download the incorrect Symvers file. This is the fix:

# perl -pi -e \
    's/def processor_type_suffix\(\):/def processor_type_suffix(): return "8"\ndef old_processor_type_suffix():/' \
    rpi-source

Then, I ran rpi-source which downloads everything into /root/linux. After this, you can run make menuconfig to get the kernel configuration screen.

# ./rpi-source
# cd /root/linux
# make menuconfig

In the menu, find anything you want to have a module for, and set its status to 'M'. In my case, since I wanted to run Ceph, I set "Device drivers" -> "Block devices" -> "RBD" to 'M'. After saving, you can find a diff of running config with the new config like this:

# zcat /proc/config.gz > .config.running
# scripts/diffconfig .config.running .config
-ARCH_USES_HIGH_VMA_FLAGS y
-ARM64_AS_HAS_MTE y
-ARM64_MTE y
-ARM64_PTR_AUTH y
-AS_HAS_CFI_NEGATE_RA_STATE y
-CC_HAS_WORKING_NOSANITIZE_ADDRESS y
-DYNAMIC_FTRACE_WITH_REGS y
-HAVE_DYNAMIC_FTRACE_WITH_REGS y
-KASAN n
 BLK_DEV_RBD n -> m
 CC_VERSION_TEXT "aarch64-linux-gnu-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0" -> "gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
 CEPH_LIB n -> m
 GCC_VERSION 80400 -> 70500
 LD_VERSION 234000000 -> 230000000
+CEPH_LIB_PRETTYDEBUG n
+CEPH_LIB_USE_DNS_RESOLVER n

If your output doesn't contain any GCC_VERSION changes, you don't need to do the next step -- but I had those changes (80400 -> 70500), meaning I had gcc 7 active while the kernel was built with gcc 8. So, switch default gcc to the version the kernel was built with (in my case, 80400):

# update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
# gcc -v
[...]
gcc version 8.4.0 (...)
# make menuconfig
[...]
# scripts/diffconfig .config.running .config
-ARCH_USES_HIGH_VMA_FLAGS y
-ARM64_AS_HAS_MTE y
-ARM64_MTE y
-AS_HAS_CFI_NEGATE_RA_STATE y
 BLK_DEV_RBD n -> m
 CC_VERSION_TEXT "aarch64-linux-gnu-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0" -> "gcc (Ubuntu/Linaro 8.4.0-1ubuntu1~18.04) 8.4.0"
 CEPH_LIB n -> m
 LD_VERSION 234000000 -> 230000000
+CEPH_LIB_PRETTYDEBUG n
+CEPH_LIB_USE_DNS_RESOLVER n

Close enough.

After this, you can start a build using make modules. This takes a long time since it builds all modules; you can find out which directory contains your module sources and build only those. On older kernels you can do this with SUBDIRS; in newer kernels, you just mention the .ko file you need. In my case, there were two such directories, so I ran:

# make prepare
# make net/ceph/libceph.ko
# make drivers/block/rbd.ko

Then, copy the new modules:

# mkdir -p /lib/modules/$(uname -r)/extra
# cp net/ceph/libceph.ko /lib/modules/$(uname -r)/extra
# cp drivers/block/rbd.ko /lib/modules/$(uname -r)/extra
# depmod
# modprobe libceph
# modprobe rbd

Success!

from picl-k3os-image-generator.

sgielen avatar sgielen commented on July 24, 2024

Closing, since it's otherwise out of scope. If you would like to propose changes to the project to better allow this, do feel free to reopen :)

from picl-k3os-image-generator.

Neonox31 avatar Neonox31 commented on July 24, 2024

Thanks for your answer !

I'm not sure to understand well all you said but finally I found a solution.
I will create a PR with changes and let you decide if it is a suitable solution.

from picl-k3os-image-generator.

Neonox31 avatar Neonox31 commented on July 24, 2024

@sgielen Here is the P.R : #9

from picl-k3os-image-generator.

Related Issues (20)

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.