Skip to content
Snippets Groups Projects
Commit 30d0c719 authored by David Maul's avatar David Maul :crab:
Browse files

feat: add basic shared memory to kernel module

parent f7a7c38d
Branches
No related tags found
No related merge requests found
#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/ktime.h>
#include <linux/kthread.h>
#include <linux/delay.h>
// Device name
#define DEVICE_NAME "sibyl"
static int major_number;
static struct class *shm_class;
static struct cdev shm_cdev;
static void *shm_buffer;
// Max number entries
#define MAX_ENTRIES 512
// Max size of entries in bytes
#define MAX_ENTRY_SIZE 4096
typedef struct entry
{
bool ready;
void *buffer;
size_t length;
} entry_t;
static entry_t *entries;
static size_t num_entries;
// Kernel thread
static struct task_struct *kthread;
// File operations
static int shm_open(struct inode *inode, struct file *file)
{
return 0;
}
static int shm_release(struct inode *inode, struct file *file)
{
return 0;
}
static int shm_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start;
void *buffer;
if (size > MAX_ENTRY_SIZE || num_entries >= MAX_ENTRIES)
return -EINVAL;
// Allokiere Speicher für den Buffer
buffer = kmalloc(size, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
// Erstelle neuen Entry
entries[num_entries].buffer = buffer;
entries[num_entries].length = size;
entries[num_entries].ready = false;
// Mappe den neuen Buffer
unsigned long pfn = virt_to_phys(buffer) >> PAGE_SHIFT;
vm_flags_set(vma, VM_IO);
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot))
{
kfree(buffer);
return -EAGAIN;
}
num_entries++;
return 0;
}
static const struct file_operations shm_fops = {
.owner = THIS_MODULE,
.open = shm_open,
.release = shm_release,
.mmap = shm_mmap,
};
static int thread(void *data)
{
while (!kthread_should_stop())
{
u64 ms = ktime_get_real_ns() / 1000000;
printk(KERN_INFO "Zeit: %llu ms\n", ms);
ssleep(1); // 1 Sekunde schlafen
}
return 0;
}
static int __init lkm_init(void)
{
pr_info("Hello world.\n");
// Initialize entries
num_entries = 0;
entries = (entry_t *)kmalloc(sizeof(entry_t) * MAX_ENTRIES, GFP_KERNEL);
if (!entries)
{
printk(KERN_ERR "Failed to allocate memory\n");
return -ENOMEM;
}
int err;
dev_t dev;
err = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
if (err)
{
printk(KERN_ERR "Failed to allocate char device region\n");
kfree(shm_buffer);
return err;
}
major_number = MAJOR(dev);
shm_class = class_create(DEVICE_NAME);
if (IS_ERR(shm_class))
{
printk(KERN_ERR "Failed to create device class\n");
unregister_chrdev_region(dev, 1);
kfree(shm_buffer);
return PTR_ERR(shm_class);
}
if (device_create(shm_class, NULL, dev, NULL, DEVICE_NAME) == NULL)
{
printk(KERN_ERR "Failed to create device\n");
class_destroy(shm_class);
unregister_chrdev_region(dev, 1);
kfree(shm_buffer);
return -EINVAL;
}
cdev_init(&shm_cdev, &shm_fops);
err = cdev_add(&shm_cdev, dev, 1);
if (err)
{
printk(KERN_ERR "Failed to add char device\n");
device_destroy(shm_class, dev);
class_destroy(shm_class);
unregister_chrdev_region(dev, 1);
kfree(shm_buffer);
return err;
}
printk(KERN_INFO "SHM device initialized\n");
kthread = kthread_run(thread, NULL, "kthread");
return PTR_ERR_OR_ZERO(kthread);
printk(KERN_INFO, "Kernel thread started\n");
return 0;
}
static void __exit lkm_exit(void)
{
pr_info("Goodbye world.\n");
dev_t dev = MKDEV(major_number, 0);
cdev_del(&shm_cdev);
device_destroy(shm_class, dev);
class_destroy(shm_class);
unregister_chrdev_region(dev, 1);
kfree(shm_buffer);
printk(KERN_INFO "SHM device removed\n");
kthread_stop(kthread);
printk(KERN_INFO, "Kernel thread stopped\n");
for (size_t i = 0; i < num_entries; i++)
{
kfree(entries[i].buffer);
}
kfree(entries);
}
module_init(lkm_init);
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment