diff --git a/README.md b/README.md index 8337458..aeb23e6 100644 --- a/README.md +++ b/README.md @@ -303,6 +303,7 @@ But TODO I don't think you can see where you are in the kernel source code and l 1. Examples 1. [Host](host/) 1. Buildroot + 1. [module_init](kernel_module/module_init.c) 1. Debugging 1. [hello](kernel_module/hello.c) 1. [hello2](kernel_module/hello2.c) @@ -318,3 +319,4 @@ But TODO I don't think you can see where you are in the kernel source code and l 1. [kthread_uninterruptible](kernel_module/kthread_uninterruptible.c) 1. [timer](kernel_module/timer.c) 1. [work_from_work](kernel_module/work_from_work.c) + 1. [irq](irq.c) diff --git a/kernel_module/external.mk b/kernel_module/external.mk index 89029e1..29ea33f 100644 --- a/kernel_module/external.mk +++ b/kernel_module/external.mk @@ -13,6 +13,12 @@ define KERNEL_MODULE_BUILD_CMDS endef define KERNEL_MODULE_INSTALL_TARGET_CMDS + # The modules are already installed by the kernel-module package type + # under /lib/modules/**, but let's also copy the modules to the root + # for insmod convenience. + # + # Modules can be still be easily inserted with "modprobe module" however. + $(INSTALL) -D -m 0655 $(@D)/*.ko '$(TARGET_DIR)' $(INSTALL) -D -m 0755 $(@D)/test/*.out '$(TARGET_DIR)' endef diff --git a/kernel_module/irq.c b/kernel_module/irq.c new file mode 100644 index 0000000..339509a --- /dev/null +++ b/kernel_module/irq.c @@ -0,0 +1,42 @@ +/* +TODO: get handler running multiple times on some existing interrupt from /proc/interrupts. +*/ + +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * Return value from kernel docs:* + * + * enum irqreturn + * @IRQ_NON interrupt was not from this device or was not handled + * @IRQ_HANDLED interrupt was handled by this device + * @IRQ_WAKE_THREAD handler requests to wake the handler thread + */ +static irqreturn_t handler(int i, void *v) +{ + pr_info("handler %llu\n", (unsigned long long)jiffies); + return IRQ_HANDLED; +} + +int init_module(void) +{ + irqreturn_t r; + r = request_irq( + 1, + handler, + IRQF_SHARED, + "myirqhandler0", + 0 + ); + pr_info("request_irq %llu\n", (unsigned long long)r); + return 0; +} + +void cleanup_module(void) +{ +} diff --git a/kernel_module/module_init.c b/kernel_module/module_init.c new file mode 100644 index 0000000..bae16d5 --- /dev/null +++ b/kernel_module/module_init.c @@ -0,0 +1,26 @@ +/* +Hello world with module_init / exit macros. + +TODO: vs direct init_module and cleanup_module. + +- modprobe only works with the macros. Try "modprobe module_init". +*/ + +#include +#include + +MODULE_LICENSE("GPL"); + +static int module_init_init(void) +{ + pr_info("module_init init\n"); + return 0; +} + +static void module_init_exit(void) +{ + pr_info("module_exit cleanup\n"); +} + +module_init(module_init_init) +module_exit(module_init_exit)