driver-tutorial finished

This commit is contained in:
2025-02-25 08:19:58 +00:00
parent 8a8b8cf56a
commit 9eed2d489b
17 changed files with 2393 additions and 0 deletions

30
interrupt/interrupt.c Normal file
View File

@@ -0,0 +1,30 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <linux/interrupt.h>
irqreturn_t myIRQ(int irq, void *devid){
//Clear pending interrupt
return IRQ_HANDLED;
}
int my_open(void){
//Set polarity and type of interrupt
//this is the api to register interrupt to
//kernel driver.
requet_irq(30, myIRQ, 0, "MYIRQ", 1);
//This 30 is the line number in interrupt register
//stored. It's like a id to the interrupt handler.
//The last line is the decive number. If multiple
//device uses same IRQ handler, then this last argument
//is used to diffrentiate between various devices using
//the same IRQ Handler.
}
void my_release(void){
//To release the interrupt handler
//free_irq api is used.
free_irq(30,1);
}

Binary file not shown.

View File

@@ -0,0 +1 @@
savedcmd_/home/junet/driver-tutorial/kernel_timer/Module.symvers := scripts/mod/modpost -M -m -a -o /home/junet/driver-tutorial/kernel_timer/Module.symvers -T /home/junet/driver-tutorial/kernel_timer/modules.order -i Module.symvers -e

View File

@@ -0,0 +1 @@
savedcmd_/home/junet/driver-tutorial/kernel_timer/demo_timer_driver.ko := ld -r -m elf_x86_64 -z noexecstack --no-warn-rwx-segments --build-id=sha1 -T scripts/module.lds -o /home/junet/driver-tutorial/kernel_timer/demo_timer_driver.ko /home/junet/driver-tutorial/kernel_timer/demo_timer_driver.o /home/junet/driver-tutorial/kernel_timer/demo_timer_driver.mod.o

View File

@@ -0,0 +1 @@
savedcmd_/home/junet/driver-tutorial/kernel_timer/demo_timer_driver.mod := printf '%s\n' demo_timer_driver.o | awk '!x[$$0]++ { print("/home/junet/driver-tutorial/kernel_timer/"$$0) }' > /home/junet/driver-tutorial/kernel_timer/demo_timer_driver.mod

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
savedcmd_/home/junet/driver-tutorial/kernel_timer/modules.order := { echo /home/junet/driver-tutorial/kernel_timer/demo_timer_driver.o; :; } > /home/junet/driver-tutorial/kernel_timer/modules.order

7
kernel_timer/Makefile Normal file
View File

@@ -0,0 +1,7 @@
obj-m += demo_timer_driver.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

View File

View File

@@ -0,0 +1,133 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
//Timer Variable
#define TIMEOUT 5000 //milliseconds
static struct timer_list demo_timer;
static unsigned int count = 0;
dev_t dev = 0;
static struct class *dev_class;
static struct cdev demo_timer_cdev;
static int __init demo_timer_driver_init(void);
static void __exit demo_timer_driver_exit(void);
/***************Driver fucntions******************/
static int demo_timer_open(struct inode *inode, struct file *file);
static int demo_timer_release(struct inode *inode , struct file *file);
static ssize_t demo_timer_read(struct file *filp, char __user *buf, size_t len, loff_t *off);
static ssize_t demo_timer_write(struct file *filp, const char __user *buf, size_t len, loff_t *off);
/*************************************************/
//File operation structure
static struct file_operations fops = {
.owner = THIS_MODULE,
.read = demo_timer_read,
.write = demo_timer_write,
.open = demo_timer_open,
.release = demo_timer_release
};
//Timer Callback function. This will be called when timer expires
void timer_callback(struct timer_list *timer){
/* do your timer stuff here */
pr_info("Timer Callback function Called [%d]\n", count++);
/**
* Re-enable timer. Because this function will be called only first time.
* If we re-enable this will work like periodic timer.
*/
mod_timer(&demo_timer, jiffies + msecs_to_jiffies(TIMEOUT));
}
/**
* This function will be called when we open the device file
*/
static int demo_timer_open(struct inode *inode, struct file *file){
pr_info("Device File Opened...!!!\n");
return 0;
}
/**
* This function will be called when we close the Device file
*/
static int demo_timer_release(struct inode *inode , struct file *file){
pr_info("Read Function\n");
return 0;
}
/**
* This function will be called when we read the Device file
*/
static ssize_t demo_timer_read(struct file *filp, char __user *buf, size_t len, loff_t *off){
pr_info("Read function\n");
return 0;
}
/**
* This function will be called when we write the Device file
*/
static ssize_t demo_timer_write(struct file *filp, const char __user *buf, size_t len, loff_t *off){
pr_info("Write function\n");
return len;
}
/**
* Module Init function
*/
static int __init demo_timer_driver_init(void){
/*Allocating Major number*/
if(alloc_chrdev_region(&dev, 0, 1, "demo_timer_Dev") < 0 ){
pr_err("Cannot allocate major number\n");
return -1;
}
pr_info("Major = %d Minor = %d \n", MAJOR(dev), MINOR(dev));
/*Creating cdev structure*/
cdev_init(&demo_timer_cdev, &fops);
/*Adding character device to the system*/
if((cdev_add(&demo_timer_cdev, dev, 1)) < 0){
pr_err("Cannot add the device to the system\n");
}
/* setup your timer to call my_timer_callback */
timer_setup(&demo_timer, timer_callback, 0);
//We can also use add_timer.
/* setup timer interval to based on TIMEOUT Macro */
/* kernel timer should be in ticks or jiffs*/
mod_timer(&demo_timer, jiffies + msecs_to_jiffies(TIMEOUT));
pr_info("Device Driver Insert...Done!!!\n");
return 0;
}
/**
*
* Module exit function
*/
static void __exit demo_timer_driver_exit(void){
/* remove kernel when unloading module */
del_timer(&demo_timer);
cdev_del(&demo_timer_cdev);
unregister_chrdev_region(dev, 1);
pr_info("Device Driver Remove...Done!!!\n");
}
module_init(demo_timer_driver_init);
module_exit(demo_timer_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Junet Hossain");
MODULE_DESCRIPTION("A Simple kernel timer module");

Binary file not shown.

View File

@@ -0,0 +1 @@
/home/junet/driver-tutorial/kernel_timer/demo_timer_driver.o

View File

@@ -0,0 +1,69 @@
#include <linux/module.h>
#define INCLUDE_VERMAGIC
#include <linux/build-salt.h>
#include <linux/elfnote-lto.h>
#include <linux/export-internal.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
#ifdef CONFIG_UNWINDER_ORC
#include <asm/orc_header.h>
ORC_HEADER;
#endif
BUILD_SALT;
BUILD_LTO_INFO;
MODULE_INFO(vermagic, VERMAGIC_STRING);
MODULE_INFO(name, KBUILD_MODNAME);
__visible struct module __this_module
__section(".gnu.linkonce.this_module") = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
#ifdef CONFIG_RETPOLINE
MODULE_INFO(retpoline, "Y");
#endif
static const char ____versions[]
__used __section("__versions") =
"\x1c\x00\x00\x00\x2b\x2f\xec\xe3"
"alloc_chrdev_region\0"
"\x14\x00\x00\x00\x5f\x7c\x28\xd8"
"cdev_init\0\0\0"
"\x14\x00\x00\x00\xda\xfb\x89\x12"
"cdev_add\0\0\0\0"
"\x18\x00\x00\x00\x39\x63\xf4\xc6"
"init_timer_key\0\0"
"\x18\x00\x00\x00\x55\x48\x0e\xdc"
"timer_delete\0\0\0\0"
"\x14\x00\x00\x00\xa2\x7e\x12\x7c"
"cdev_del\0\0\0\0"
"\x24\x00\x00\x00\x33\xb3\x91\x60"
"unregister_chrdev_region\0\0\0\0"
"\x14\x00\x00\x00\xbb\x6d\xfb\xbd"
"__fentry__\0\0"
"\x10\x00\x00\x00\x7e\x3a\x2c\x12"
"_printk\0"
"\x1c\x00\x00\x00\xca\x39\x82\x5b"
"__x86_return_thunk\0\0"
"\x10\x00\x00\x00\xa6\x50\xba\x15"
"jiffies\0"
"\x14\x00\x00\x00\xb8\x83\x8c\xc3"
"mod_timer\0\0\0"
"\x18\x00\x00\x00\xf8\x1a\x94\x92"
"module_layout\0\0\0"
"\x00\x00\x00\x00\x00\x00\x00\x00";
MODULE_INFO(depends, "");
MODULE_INFO(srcversion, "7D7C66AAC1FA4296375BED7");

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
/home/junet/driver-tutorial/kernel_timer/demo_timer_driver.o