본문으로 건너뛰기
cccskills
무료GitHub에 공개

linux-kernel-modules

Use when writing loadable kernel modules: Kbuild, module parameters, proc and sysfs entries, char devices, or ftrace debugging. Not for driver architecture: use device-drivers.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(3)

  • SKILL.md8.8 KB
  • agents/openai.yaml201 B
  • references/kbuild-basics.md2.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Linux kernel modules

A loadable module runs in kernel space with no safety net. The build system, the userspace interfaces, and the debugging paths are all prescribed; follow them and the module stays debuggable.

Contract

FieldBound contract
TriggerThe task writes or builds an out-of-tree .ko, adds module parameters, creates proc or sysfs entries, registers a char device, debugs with KDB or ftrace, or signs modules for Secure Boot.
AuthorityReversible local: writes only the module source, Kbuild files, built artifacts, and local signing keys, plus load and unload of the module on this machine; rollback is rmmod for the loaded module and version control for the files. No remote mutation.
Side effectLocal build outputs, module insertion and removal, entries under /proc and /sys while loaded, and generated key material when signing is set up.
DoneThe module builds against the running kernel's build tree, loads, exposes its interfaces, and unloads without leaving state behind.

Inputs

  • The running kernel version and its build directory: required. uname -r and /lib/modules/$(uname -r)/build.
  • Root access: required for insmod, rmmod, and signing enrollment.
  • The module's userspace interface: required before writing code. Proc entry, sysfs attributes, or a char device.
  • For Secure Boot: the platform's key enrollment path.

Procedure

  1. Write the minimal module and build it through Kbuild. The Makefile is one line plus the invocation; Kbuild supplies every kernel flag. Done when: modinfo hello.ko prints the metadata and insmod plus rmmod round-trip cleanly.
#include <linux/module.h>
#include <linux/init.h>

static int __init hello_init(void) {
    pr_info("hello: loaded\n");
    return 0;                 // nonzero return aborts the load
}

static void __exit hello_exit(void) {
    pr_info("hello: unloaded\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Name");
MODULE_DESCRIPTION("Minimal loadable module");
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean
make
sudo insmod hello.ko
lsmod | grep hello
sudo rmmod hello
dmesg | tail
  1. Add parameters for values that must change without a rebuild. The permission argument controls the sysfs visibility of each parameter. Done when: sudo insmod hello.ko count=3 applies the value and /sys/module/hello/parameters/count exists.
#include <linux/moduleparam.h>

static char *name = "world";
static int count = 1;
module_param(name, charp, S_IRUGO);
module_param(count, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(name, "Name to greet");
MODULE_PARM_DESC(count, "Number of times to greet");
  1. Create a proc entry when a reader needs formatted state. The seq_file callbacks fill one buffer per read; the file mode controls access. Done when: cat /proc/mymod prints the state.
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int mymod_show(struct seq_file *m, void *v) {
    seq_printf(m, "state: %d\n", my_state);
    return 0;
}

static int mymod_open(struct inode *inode, struct file *file) {
    return single_open(file, mymod_show, NULL);
}

static const struct proc_ops mymod_pops = {
    .proc_open    = mymod_open,
    .proc_read    = seq_read,
    .proc_lseek   = seq_lseek,
    .proc_release = single_release,
};

proc_create("mymod", 0444, NULL, &mymod_pops);
// remove_proc_entry("mymod", NULL); in module_exit
  1. Expose sysfs attributes for values that userspace reads and may write. sysfs_create_group attaches them under /sys/kernel/mymod/. Done when: read and write through the attribute round-trip the value.
#include <linux/kobject.h>
#include <linux/sysfs.h>

static struct kobject *mymod_kobj;
static int mymod_value;

static ssize_t value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) {
    return sysfs_emit(buf, "%d\n", mymod_value);
}
static ssize_t value_store(struct kobject *kobj, struct kobj_attribute *attr,
                           const char *buf, size_t count) {
    sscanf(buf, "%d", &mymod_value);
    return count;
}
static struct kobj_attribute value_attr = __ATTR(value, 0664, value_show, value_store);

mymod_kobj = kobject_create_and_add("mymod", kernel_kobj);
sysfs_create_group(mymod_kobj, &attr_group);   // check the return value
  1. Register a char device when userspace needs open, read, write on a node. A misc device gets a dynamic minor and creates /dev/mymod through udev without manual mknod. Done when: cat /dev/mymod reads data and the buffer bounds hold.
#include <linux/cdev.h>
#include <linux/uaccess.h>

#define BUF_SIZE 1024
static char dev_buf[BUF_SIZE];

static ssize_t mydev_read(struct file *f, char __user *buf, size_t len, loff_t *off) {
    size_t to_copy = min(len, (size_t)BUF_SIZE);
    if (copy_to_user(buf, dev_buf, to_copy))
        return -EFAULT;
    return to_copy;
}

static const struct file_operations mydev_fops = {
    .owner = THIS_MODULE,
    .read  = mydev_read,
};

static struct miscdevice mydev_misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = "mymod",
    .fops  = &mydev_fops,
};
misc_register(&mydev_misc);      // check the return value
misc_deregister(&mydev_misc);    // in module_exit
  1. Debug with KDB and ftrace. KDB over serial or kgdboc gives a kernel debugger; ftrace traces function calls live and answers most timing questions without a debugger. Done when: the misbehaving call path or timing is captured.
# ftrace: trace the module's functions
echo 'mymod_*' > /sys/kernel/debug/tracing/set_ftrace_filter
echo function > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/trace
# and the quick printk path
echo 'file mymod.c +p' > /sys/kernel/debug/dynamic_debug/control
  1. Export symbols for other modules deliberately. EXPORT_SYMBOL shares with any module; EXPORT_SYMBOL_GPL restricts to GPL modules. Loading a module that imports GPL symbols without a GPL license taints the kernel and fails. Done when: modinfo shows the intended license and the import list matches it.
EXPORT_SYMBOL_GPL(my_shared_helper);
  1. Write KUnit tests for the module's pure logic. In-tree kernels build them with CONFIG_KUNIT; out-of-tree tests run as a KUnit module on a test kernel. Done when: the suite loads and reports its cases.
#include <kunit/test.h>

static void parse_valid(struct kunit *test) {
    KUNIT_EXPECT_EQ(test, mymod_parse("42"), 42);
}
static struct kunit_case mymod_cases[] = {
    KUNIT_CASE(parse_valid),
    {}
};
static struct kunit_suite mymod_suite = { .name = "mymod", .test_cases = mymod_cases };
kunit_test_suite(mymod_suite);
  1. Sign the module when Secure Boot is on. The kernel verifies module signatures against enrolled keys when CONFIG_MODULE_SIG is set, and a lockdown kernel rejects unsigned modules. Done when: modinfo hello.ko | grep signer shows the key and the module loads on the lockdown system.
openssl req -new -x509 -newkey rsa:4096 -keyout signing_key.pem \
        -out signing_cert.pem -nodes -days 36500 -subj "/CN=Module Signing"
scripts/sign-file sha256 signing_key.pem signing_cert.pem hello.ko
sudo mokutil --import signing_cert.pem    # enroll through MOK on UEFI, reboot to confirm

Failure and recovery

Failure classBehavior
Unknown symbol at insmodThe module imports a symbol nothing exports. Check the import list and the exporting module, and the license match for EXPORT_SYMBOL_GPL.
Invalid module formatThe module was built against a different kernel or architecture. Rebuild against uname -r's build tree.
Load leaves stale /proc or /sys stateThe exit path skipped cleanup. Make module_exit the mirror of module_init and reload.
Module hangs the boxReboot, then reproduce under ftrace with a filter narrowed to the module's functions before loading again.
Signature rejected on lockdownThe key is not enrolled, or the signature was invalidated by a rebuild. Re-sign after every rebuild and re-enroll once.
make cannot find the build treeThe kernel headers package is missing. Install the matching headers before building.

Output

The built and loadable module, its userspace interface verified by reads through /proc, /sys, or the device node, and clean unload evidence in dmesg. The Kbuild variable table and the out-of-tree versus in-tree comparison are in references/kbuild-basics.md. The mainline kernel this tree pins is 7.2 with LTS 6.18.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

af-xdp

무료

Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

agents-md

무료

Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

OutlineDriven의 스킬 모두 보기

이 스킬의 문제 신고