Skip to content
Snippets Groups Projects
Commit 542b8674 authored by root's avatar root
Browse files

Feat: TP2 made by valentin and adil with love

parent f9e0469e
No related branches found
No related tags found
No related merge requests found
KDIR=../../build/kvm/
obj-m += pipebis.o
PWD := $(CURDIR)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
/root/Desktop/asee/work/tp2/pipebis.o
/*
* pipebis.c: Creates a read-only char device that says how many times
* you have read from the dev file
*/
#include <linux/atomic.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h> /* for sprintf() */
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/types.h>
#include <linux/uaccess.h> /* for get_user and put_user */
#include <linux/version.h>
#include <asm/errno.h>
/* Prototypes - this would normally go in a .h file */
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char __user *, size_t,
loff_t *);
#define SUCCESS 0
#define DEVICE_NAME "asee_mod" /* Dev name as it appears in /proc/devices */
#define BUF_LEN 16 /* Max length of the message from the device */
/* Global variables are declared as static, so are global within the file. */
static char *msg; /* The msg the device will give when asked */
static struct kobject *pipebis_module;
static int asee_buf_count = 0;
static int asee_buf_size = BUF_LEN;
static ssize_t asee_buf_size_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", asee_buf_size);
}
static ssize_t asee_buf_size_store(struct kobject *kobj, struct kobj_attribute *attr, char *buf, size_t count)
{
int old_size = asee_buf_size;
sscanf(buf, "%du", &asee_buf_size);
if (asee_buf_size <= asee_buf_count) {
asee_buf_size = old_size;
pr_err("New size for buffer should be less than current content in it");
return count;
}
char * second_message = kcalloc(asee_buf_size, sizeof(char), GFP_KERNEL);
for(int cpt = 0; cpt < old_size; cpt++) {
second_message[cpt] = msg[cpt];
}
kfree(msg);
msg = second_message;
// TODO: incresae buffer size
return count;
}
static struct kobj_attribute asee_buf_size_attribute = __ATTR(asee_buf_size, 0660, asee_buf_size_show, (void *)asee_buf_size_store);
static ssize_t asee_buf_count_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", asee_buf_count);
}
static ssize_t asee_buf_count_store(struct kobject *kobj, struct kobj_attribute *attr, char *buf, size_t count)
{
return count;
}
static struct kobj_attribute asee_buf_count_attribute = __ATTR(asee_buf_count, 0660, asee_buf_count_show, (void *)asee_buf_count_store);
static int major; /* major number assigned to our device driver */
enum {
CDEV_NOT_USED = 0,
CDEV_EXCLUSIVE_OPEN = 1,
};
/* Is device open? Used to prevent multiple access to device */
static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED);
static struct class *cls;
static struct file_operations pipebis_fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
};
static int __init pipebis_init(void)
{
major = register_chrdev(0, DEVICE_NAME, &pipebis_fops);
if (major < 0) {
pr_alert("Registering char device failed with %d\n", major);
return major;
}
pr_info("I was assigned major number %d.\n", major);
msg = kcalloc(asee_buf_size, sizeof(char), GFP_KERNEL);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)
cls = class_create(DEVICE_NAME);
#else
cls = class_create(THIS_MODULE, DEVICE_NAME);
#endif
device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
pr_info("Device created on /dev/%s\n", DEVICE_NAME);
pipebis_module = kobject_create_and_add("asee_mod", kernel_kobj);
if (!pipebis_module) return -ENOMEM;
int error = 0;
error = sysfs_create_file(pipebis_module, &asee_buf_size_attribute.attr);
error += sysfs_create_file(pipebis_module, &asee_buf_count_attribute.attr);
if (error) {
pr_info("failed to create a asee variable in /sys/kernel/asee_mod\n");
return error;
}
return SUCCESS;
}
static void __exit pipebis_exit(void)
{
device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
/* Unregister the device */
unregister_chrdev(major, DEVICE_NAME);
kobject_put(pipebis_module);
}
/* Methods */
/* Called when a process tries to open the device file, like
* "sudo cat /dev/pipebis"
*/
static int device_open(struct inode *inode, struct file *file)
{
if (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN))
return -EBUSY;
try_module_get(THIS_MODULE);
return SUCCESS;
}
/* Called when a process closes the device file. */
static int device_release(struct inode *inode, struct file *file)
{
/* We're now ready for our next caller */
atomic_set(&already_open, CDEV_NOT_USED);
/* Decrement the usage count, or else once you opened the file, you will
* never get rid of the module.
*/
module_put(THIS_MODULE);
return SUCCESS;
}
/* Called when a process, which already opened the dev file, attempts to
* read from it.
*/
static int last_writen_bytes;
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
char __user *buffer, /* buffer to fill with data */
size_t length, /* length of the buffer */
loff_t *offset)
{
/* Number of bytes actually written to the buffer */
int bytes_read = 0;
char *msg_ptr = msg;
/* Actually put the data into the buffer */
while (asee_buf_count > 0) {
if (last_writen_bytes >= asee_buf_size) {
last_writen_bytes = 0;
}
/* The buffer is in the user data segment, not the kernel
* segment so "*" assignment won't work. We have to use
* put_user which copies data from the kernel data segment to
* the user data segment.
*/
put_user(*(msg_ptr + last_writen_bytes), buffer++);
// Try to clear the read
*(msg_ptr + last_writen_bytes) = '\0';
last_writen_bytes++;
asee_buf_count--;
bytes_read++;
}
*offset = last_writen_bytes;
/* Most read functions return the number of bytes put into the buffer. */
return bytes_read;
}
/* Called when a process writes to dev file: echo "hi" > /dev/hello */
static ssize_t device_write(struct file *filp, const char __user *buff,
size_t len, loff_t *off)
{
int bytes_writen = 0;
int current_bytes = last_writen_bytes;
for (int cpt = 0; cpt < len; cpt++) {
if (current_bytes >= asee_buf_size) {
current_bytes = 0;
}
get_user(*(msg + current_bytes), buff + cpt);
current_bytes++;
bytes_writen++;
asee_buf_count++;
}
last_writen_bytes = current_bytes;
*off = last_writen_bytes;
return bytes_writen;
}
module_init(pipebis_init);
module_exit(pipebis_exit);
MODULE_LICENSE("GPL");
\ No newline at end of file
#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 struct modversion_info ____versions[]
__used __section("__versions") = {
{ 0x6bc3fbc0, "__unregister_chrdev" },
{ 0xecc78457, "kobject_put" },
{ 0x73895700, "__register_chrdev" },
{ 0x122c3a7e, "_printk" },
{ 0xeb233a45, "__kmalloc" },
{ 0xfb890f0b, "class_create" },
{ 0x41b15bc9, "device_create" },
{ 0xa6ef1646, "kernel_kobj" },
{ 0x10bd90f2, "kobject_create_and_add" },
{ 0xa3efd5d1, "sysfs_create_file_ns" },
{ 0xbcab6ee6, "sscanf" },
{ 0x37a0cba, "kfree" },
{ 0xbdfb6dbb, "__fentry__" },
{ 0x5b8239ca, "__x86_return_thunk" },
{ 0xc3aaf0a9, "__put_user_1" },
{ 0x167e7f9d, "__get_user_1" },
{ 0x3c3ff9fd, "sprintf" },
{ 0xab632ed, "module_put" },
{ 0x47143bb3, "try_module_get" },
{ 0xf23bcaeb, "device_destroy" },
{ 0xfdfe3852, "class_destroy" },
{ 0x76800044, "module_layout" },
};
MODULE_INFO(depends, "");
MODULE_INFO(srcversion, "0407622983A4737B8D0E5C8");
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment