ec-su-axb35-kernel-module

star 0

Build, sign, install, and manage the ec_su_axb35 kernel module (Sixunited AXB35-02 Embedded Controller) for fan and power control on the m5 headless server.

crycriM By crycriM schedule Updated 6/6/2026

name: ec-su-axb35-kernel-module description: Build, sign, install, and manage the ec_su_axb35 kernel module (Sixunited AXB35-02 Embedded Controller) for fan and power control on the m5 headless server. version: 1.0

ec_su_axb35 Kernel Module

Custom out-of-tree kernel module for the Sixunited AXB35-02 Embedded Controller. Provides fan control and APU power mode management on the m5 server (headless, BIOS power mode set to normal to avoid breaker trips on shared 16A circuit).

Source Location

~/sources/ec-su_axb35-linux/

Contains: source (src/), Makefile, MOK signing keys (MOK.key, MOK.der), scripts (scripts/su_axb35_monitor).

Sysfs Interface

Once loaded, the module exposes:

  • /sys/class/ec_su_axb35/apu/power_mode — write quiet, normal, or performance
  • Current setting: echo quiet|normal|performance | sudo tee /sys/class/ec_su_axb35/apu/power_mode

Build for a Specific Kernel

The .ko is kernel-version specific (vermagic check). Must rebuild when kernel changes.

cd ~/sources/ec-su_axb35-linux
make clean
make KERNEL_BUILD=/lib/modules/TARGET_KERNEL/build

Sign the Module (Secure Boot)

The server uses Secure Boot. The module must be signed with the MOK keys stored in the source dir:

cd ~/sources/ec-su_axb35-linux
kmodsign sha512 MOK.key MOK.der ec_su_axb35.ko

If MOK key is not yet enrolled on this kernel:

sudo mokutil --import MOK.der
# Enter a one-time password, then reboot
# At MOK Manager prompt: Enroll MOK → Continue → Enter password → Reboot

Headless caveat: MOK enrollment requires physical console or IPMI/serial to interact with Shim's MOK Manager at boot. Plan accordingly.

Install

cd ~/sources/ec-su_axb35-linux
sudo make KERNEL_BUILD=/lib/modules/TARGET_KERNEL/build install
# This runs modules_install + depmod

Verify:

modinfo -n ec_su_axb35
sudo modprobe ec_su_axb35
lsmod | grep ec_su
ls /sys/class/ec_su_axb35/

Set GRUB to Boot a Specific Kernel

When the module isn't built for the latest kernel yet, pin GRUB to the kernel that has it:

# Check available entries
sudo grep -E 'menuentry' /boot/grub/grub.cfg | grep -v 'recovery' | head -10

# Pin to specific kernel (e.g., 7.0.0-12)
sudo sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 7.0.0-12-generic"/' /etc/default/grub
sudo update-grub

Revert to latest:

sudo sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT=0/' /etc/default/grub
sudo update-grub

Full Rebuild Workflow (new kernel)

cd ~/sources/ec-su_axb35-linux
make clean
make KERNEL_BUILD=/lib/modules/NEW_KERNEL/build
kmodsign sha512 MOK.key MOK.der ec_su_axb35.ko
sudo make KERNEL_BUILD=/lib/modules/NEW_KERNEL/build install

# If MOK already enrolled for this key, just reboot:
sudo reboot

# Check GRUB pin is in place — it should auto-target the pinned kernel:
grep "^GRUB_DEFAULT" /etc/default/grub
# Expected: GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux KERNEL_VERSION-generic"

# If not pinned, revert to latest or pin to current:
# Pin to current running kernel:
CURRENT=$(uname -r)
MENUENTRY=$(sudo grep -E "^menuentry" /boot/grub/grub.cfg | grep "$CURRENT" | head -1 | sed "s/menuentry '\([^']*\)'.*/\1/")
sudo sed -i "s/^GRUB_DEFAULT=.*/GRUB_DEFAULT=\"Advanced options for Ubuntu>$MENUENTRY\"/" /etc/default/grub
sudo update-grub

May 2025 session: After kernel 7.0.0-15 update, module was already GRUB-pinned. Verified: extra/ dir had stale unsigned .ko, updates/ had correct signed one. Cleaned extra/, confirmed updates/ takes precedence. GRUB pin already active — no action needed beyond confirming.

Pitfalls

Monitoring and automatic mode switching

You can add a lightweight watchdog that checks the APU power mode and temperature every 30 seconds. If the mode stays in quiet for longer than 10 minutes and the CPU temperature exceeds 65 °C, the watchdog will automatically switch the mode to balanced to avoid prolonged throttling.

Example systemd service

Create /etc/systemd/system/ec-apu-watchdog.service:

[Unit]
Description=Watchdog for ec_su_axb35 APU power mode
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/ec-apu-watchdog.sh

Create the script /usr/local/bin/ec-apu-watchdog.sh:

#!/usr/bin/env bash
MODE=$(cat /sys/class/ec_su_axb35/apu/power_mode)
TEMP=$(cat /sys/class/thermal/thermal_zone*/temp | head -1)
# temperature in millidegree Celsius
if [[ "$MODE" == "quiet" && $TEMP -gt 65000 ]]; then
    echo "APU quiet mode + high temp, switching to balanced"
    echo balanced > /sys/class/ec_su_axb35/apu/power_mode
fi

Make it executable:

chmod +x /usr/local/bin/ec-apu-watchdog.sh
systemctl daemon-reload
systemctl enable --now ec-apu-watchdog.service

This ensures the system automatically falls back to a safer power mode without manual intervention.

Monitoring and automatic mode switching

You can add a lightweight watchdog that checks the APU power mode and temperature every 30 seconds. If the mode stays in quiet for longer than 10 minutes and the CPU temperature exceeds 65°C, the watchdog will automatically switch the mode to normal to avoid prolonged throttling.

Example systemd service

Create /etc/systemd/system/ec-apu-watchdog.service:

[Unit]
Description=Watchdog for ec_su_axb35 APU power mode
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/ec-apu-watchdog.sh

Create the script /usr/local/bin/ec-apu-watchdog.sh:

#!/usr/bin/env bash
MODE=$(cat /sys/class/ec_su_axb35/apu/power_mode)
TEMP=$(cat /sys/class/thermal/thermal_zone*/temp | head -1)
# temperature in millidegree Celsius
if [[ "$MODE" == "quiet" && $TEMP -gt 65000 ]]; then
    echo "APU quiet mode + high temp, switching to normal"
    echo normal > /sys/class/ec_su_axb35/apu/power_mode
fi

Make it executable:

chmod +x /usr/local/bin/ec-apu-watchdog.sh
systemctl daemon-reload
systemctl enable --now ec-apu-watchdog.service

This ensures the system automatically falls back to a safer power mode without manual intervention.

  • Version mismatch: Module won't load if vermagic doesn't match running kernel. Always rebuild.
  • Secure Boot: Unsigned module will be rejected. Always sign with MOK keys.
  • Unattended upgrades may install a new kernel and remove old ones. After a kernel update, the module must be rebuilt or GRUB pinned to the old kernel.
  • DKMS not used — this module is not registered with DKMS, so it won't auto-rebuild on kernel updates. Consider setting up DKMS if kernel changes become frequent.
  • Duplicate .ko files: The module has been found in both /lib/modules/KVER/updates/ and /lib/modules/KVER/extra/. The updates/ path takes precedence. Clean up duplicates if needed.
  • Power mode caution: APU power mode performance can trip the breaker on the shared 16A circuit. Use normal for the BIOS, normal or quiet for APU power mode.
Install via CLI
npx skills add https://github.com/crycriM/hermes-skills --skill ec-su-axb35-kernel-module
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator