From: seantywork Date: Wed, 5 Nov 2025 04:24:13 +0000 (+0000) Subject: chr store X-Git-Url: https://git.feebdaed.xyz/?a=commitdiff_plain;h=26fd7b145e715a00c7f0f97d8674b43e4ea94890;p=linuxyz.git chr store --- diff --git a/kchr-store/2025-1105.xyz.md b/kchr-store/2025-1105.xyz.md new file mode 100644 index 0000000..4e768b5 --- /dev/null +++ b/kchr-store/2025-1105.xyz.md @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/kchr-store/Makefile b/kchr-store/Makefile new file mode 100644 index 0000000..f417896 --- /dev/null +++ b/kchr-store/Makefile @@ -0,0 +1,5 @@ +obj-m += chr_store.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 \ No newline at end of file diff --git a/kchr-store/chr_store.c b/kchr-store/chr_store.c new file mode 100644 index 0000000..103f3a8 --- /dev/null +++ b/kchr-store/chr_store.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define SUCCESS 0 +#define DEVICE_NAME "chr_store" +#define MAX_LEN 256 +#define BLK_LEN 4096 + +static int dev_major; +static int device_open_counter = 0; +static int blk_count = 0; +static __u8* msg = NULL; + +static int device_open(struct inode *inode, struct file *filp){ + if (device_open_counter){ + return -EBUSY; + } + device_open_counter++; + try_module_get(THIS_MODULE); + return SUCCESS; +} + + +static int device_release(struct inode *inode, struct file *filp){ + device_open_counter--; + module_put(THIS_MODULE); + return SUCCESS; +} + + +static ssize_t device_read(struct file *filp, char *buffer, size_t len, loff_t *offset){ + int _blk_count = 0; + ssize_t n = 0; + printk(KERN_INFO "chr_store: r length: %lu\n", len); + if (blk_count == 0){ + return 0; + } + _blk_count = len / BLK_LEN; + if(len % BLK_LEN != 0){ + _blk_count += 1; + } + if(_blk_count > MAX_LEN){ + printk(KERN_ERR "requested data out of range\n"); + return -EINVAL; + } + n = copy_to_user(buffer, msg, len); + (*offset) += len; + return len - n; +} + + +static ssize_t device_write(struct file *filp, const char *buf, size_t len, loff_t *offset){ + + int _blk_count = 0; + ssize_t n = 0; + printk(KERN_INFO "chr_store: w length: %lu\n", len); + _blk_count = len / BLK_LEN; + if(len % BLK_LEN != 0){ + _blk_count += 1; + } + if(_blk_count > MAX_LEN){ + printk(KERN_ERR "invalid total length\n"); + return -EINVAL; + } + if(_blk_count == 0){ + if(msg != NULL){ + blk_count = 0; + kfree(msg); + } + return 0; + } + if(msg == NULL){ + msg = kzalloc(_blk_count * BLK_LEN,GFP_KERNEL); + if(msg == NULL){ + printk(KERN_ERR "failed to add new data\n"); + return -ENOMEM; + } + n = copy_from_user(msg, buf, len); + } else { + memset(msg, blk_count * BLK_LEN, 0); + if(blk_count != _blk_count){ + msg = krealloc(msg, _blk_count * BLK_LEN, GFP_KERNEL); + } + n = copy_from_user(msg, buf, len); + } + (*offset) += len; + blk_count = _blk_count; + return len - n; +} + +static loff_t device_llseek(struct file* filp, loff_t offset, int whence){ + + loff_t retval = 0; + if(blk_count == 0){ + return 0; + } + switch(whence){ + case SEEK_END: + retval = strlen(msg); + break; + case SEEK_SET: + retval = 0; + break; + default: + retval = 0; + break; + } + return retval; +} + + + + +static struct file_operations fops = { + .llseek = device_llseek, + .read = device_read, + .write = device_write, + .open = device_open, + .release = device_release +}; + + +static int __init init_chr_store(void){ + dev_major = register_chrdev(0, DEVICE_NAME, &fops); + if (dev_major < 0) { + printk(KERN_ALERT "registering char device failed with %d\n", dev_major); + return dev_major; + } + printk(KERN_INFO "dev_major number: %d\n", dev_major); + return SUCCESS; +} + + +static void __exit exit_chr_store(void){ + unregister_chrdev(dev_major, DEVICE_NAME); + if(msg != NULL){ + kfree(msg); + } + printk(KERN_INFO "dev_major: %d: gone\n", dev_major); +} + +module_init(init_chr_store); +module_exit(exit_chr_store); +MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/kchr-store/dev_create.sh b/kchr-store/dev_create.sh new file mode 100755 index 0000000..090de35 --- /dev/null +++ b/kchr-store/dev_create.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +sudo insmod ./chr_store.ko +dev="chr_store" +major="$(grep "$dev" /proc/devices | cut -d ' ' -f 1)" +#sudo mknod "/dev/$dev" c "$major" 0 +sudo mknod "./user/$dev" c "$major" 0 +echo "dev node created" +#echo "/dev/$dev" +echo "./user/$dev" \ No newline at end of file diff --git a/kchr-store/dev_destroy.sh b/kchr-store/dev_destroy.sh new file mode 100755 index 0000000..faa87c3 --- /dev/null +++ b/kchr-store/dev_destroy.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +sudo rm ./user/chr_store +sudo rmmod chr_store + + +echo "dev node destroyed" \ No newline at end of file diff --git a/kchr-store/user/Makefile b/kchr-store/user/Makefile new file mode 100644 index 0000000..67b995c --- /dev/null +++ b/kchr-store/user/Makefile @@ -0,0 +1,4 @@ +all: + gcc -Wall -o u.out u.c +clean: + rm -rf *.out *.o \ No newline at end of file diff --git a/kchr-store/user/u.c b/kchr-store/user/u.c new file mode 100644 index 0000000..1e8a866 --- /dev/null +++ b/kchr-store/user/u.c @@ -0,0 +1,65 @@ +#include +#include +#include + +#define DEV_NAME "./chr_store" + +void print_help(){ + printf("r $number: reads $number of characters from the beginning\n"); + printf("w \"$message\": write $message to the file\n"); +} + +int main(int argc, char** argv){ + + FILE* f = NULL; + int number = 0; + char* buff = NULL; + if(argc != 3){ + print_help(); + return -1; + } + f = fopen(DEV_NAME, "r+"); + if(f == NULL){ + printf("failed to open file: %s\n", DEV_NAME); + return -1; + } + if(strcmp(argv[1], "r") == 0){ + long fsize = 0; + sscanf(argv[2], "%d", &number); + if(fseek(f, 0L, SEEK_END) == 0){ + fsize = ftell(f); + if(fsize < 0){ + printf("failed to seek size\n"); + goto out; + } + if(fseek(f, 0L, SEEK_SET) != 0){ + printf("failed to reset pos\n"); + goto out; + } + } else { + printf("failed to seek eof\n"); + goto out; + } + if(fsize == 0){ + printf("nothing to read\n"); + return 0; + } + printf("current chr_storage size: %ld\n", fsize); + buff = calloc(fsize, sizeof(char)); + int n = fread(buff, sizeof(char), number, f); + printf("read: %d: %s\n", n, buff); + free(buff); + } else if(strcmp(argv[1], "w") == 0){ + int arglen = strlen(argv[2]); + int n = fwrite(argv[2], sizeof(char), arglen, f); + printf("write: %d\n", n); + } else { + printf("invalid argument: %s\n", argv[1]); + print_help(); + return -1; + } +out: + fclose(f); + + return 0; +} \ No newline at end of file diff --git a/kmem-storage/Makefile b/kmem-storage/Makefile deleted file mode 100644 index 7dcb971..0000000 --- a/kmem-storage/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-m += mem_storage.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 \ No newline at end of file diff --git a/kmem-storage/dev_create.sh b/kmem-storage/dev_create.sh deleted file mode 100755 index f5602e4..0000000 --- a/kmem-storage/dev_create.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -sudo insmod ./mem_storage.ko -dev="mem_storage" -major="$(grep "$dev" /proc/devices | cut -d ' ' -f 1)" -#sudo mknod "/dev/$dev" c "$major" 0 -sudo mknod "./user/$dev" c "$major" 0 -echo "dev node created" -#echo "/dev/$dev" -echo "./user/$dev" \ No newline at end of file diff --git a/kmem-storage/dev_destroy.sh b/kmem-storage/dev_destroy.sh deleted file mode 100755 index 8bf452c..0000000 --- a/kmem-storage/dev_destroy.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -sudo rm ./user/mem_storage -sudo rmmod mem_storage - - -echo "dev node destroyed" \ No newline at end of file diff --git a/kmem-storage/mem_storage.c b/kmem-storage/mem_storage.c deleted file mode 100644 index 459daa6..0000000 --- a/kmem-storage/mem_storage.c +++ /dev/null @@ -1,127 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define SUCCESS 0 -#define DEVICE_NAME "mem_storage" -#define MAX_LEN 256 -#define BLK_LEN 4096 - -static int dev_major; -static int device_open_counter = 0; -static int blk_count = 0; -static __u8* msg = NULL; - -static int device_open(struct inode *inode, struct file *filp){ - if (device_open_counter){ - return -EBUSY; - } - device_open_counter++; - try_module_get(THIS_MODULE); - return SUCCESS; -} - - -static int device_release(struct inode *inode, struct file *filp){ - device_open_counter--; - module_put(THIS_MODULE); - return SUCCESS; -} - - -static ssize_t device_read(struct file *filp, char *buffer, size_t len, loff_t *offset){ - int _blk_count = 0; - ssize_t n = 0; - printk(KERN_INFO "mst: r length: %lu\n", len); - if (blk_count == 0){ - return 0; - } - _blk_count = len / BLK_LEN; - if(len % BLK_LEN != 0){ - _blk_count += 1; - } - if(_blk_count > MAX_LEN){ - printk(KERN_ERR "requested data out of range\n"); - return -EINVAL; - } - n = copy_to_user(buffer, msg, len); - (*offset) += len; - return len - n; -} - - -static ssize_t device_write(struct file *filp, const char *buf, size_t len, loff_t *offset){ - - int _blk_count = 0; - ssize_t n = 0; - printk(KERN_INFO "mst: w length: %lu\n", len); - _blk_count = len / BLK_LEN; - if(len % BLK_LEN != 0){ - _blk_count += 1; - } - if(_blk_count > MAX_LEN){ - printk(KERN_ERR "invalid total length\n"); - return -EINVAL; - } - if(_blk_count == 0){ - if(msg != NULL){ - blk_count = 0; - kfree(msg); - } - return 0; - } - if(msg == NULL){ - msg = kzalloc(_blk_count * BLK_LEN,GFP_KERNEL); - if(msg == NULL){ - printk(KERN_ERR "failed to add new data\n"); - return -ENOMEM; - } - n = copy_from_user(msg, buf, len); - } else { - memset(msg, blk_count * BLK_LEN, 0); - if(blk_count != _blk_count){ - msg = krealloc(msg, _blk_count * BLK_LEN, GFP_KERNEL); - } - n = copy_from_user(msg, buf, len); - } - (*offset) += len; - blk_count = _blk_count; - return len - n; -} - - -static struct file_operations fops = { - .read = device_read, - .write = device_write, - .open = device_open, - .release = device_release -}; - - -static int __init init_mem_storage(void){ - dev_major = register_chrdev(0, DEVICE_NAME, &fops); - if (dev_major < 0) { - printk(KERN_ALERT "registering char device failed with %d\n", dev_major); - return dev_major; - } - printk(KERN_INFO "dev_major number: %d\n", dev_major); - return SUCCESS; -} - - -static void __exit exit_mem_storage(void){ - unregister_chrdev(dev_major, DEVICE_NAME); - if(msg != NULL){ - kfree(msg); - } - printk(KERN_INFO "dev_major: %d: gone\n", dev_major); -} - -module_init(init_mem_storage); -module_exit(exit_mem_storage); -MODULE_LICENSE("GPL"); \ No newline at end of file diff --git a/kmem-storage/user/Makefile b/kmem-storage/user/Makefile deleted file mode 100644 index 67b995c..0000000 --- a/kmem-storage/user/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: - gcc -Wall -o u.out u.c -clean: - rm -rf *.out *.o \ No newline at end of file diff --git a/kmem-storage/user/u.c b/kmem-storage/user/u.c deleted file mode 100644 index 6675dd9..0000000 --- a/kmem-storage/user/u.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include - -#define DEV_NAME "./mem_storage" - -void print_help(){ - printf("r $number: reads $number of characters from the beginning\n"); - printf("w \"$message\": write $message to the file\n"); -} - -int main(int argc, char** argv){ - - FILE* f = NULL; - int number = 0; - char* buff = NULL; - if(argc != 3){ - print_help(); - return -1; - } - f = fopen(DEV_NAME, "r+"); - if(f == NULL){ - printf("failed to open file: %s\n", DEV_NAME); - return -1; - } - if(strcmp(argv[1], "r") == 0){ - sscanf(argv[2], "%d", &number); - buff = calloc(number, sizeof(char)); - int n = fread(buff, sizeof(char), number, f); - printf("read: %d: %s\n", n, buff); - free(buff); - } else if(strcmp(argv[1], "w") == 0){ - int arglen = strlen(argv[2]); - int n = fwrite(argv[2], sizeof(char), arglen, f); - printf("write: %d\n", n); - } else { - printf("invalid argument: %s\n", argv[1]); - print_help(); - return -1; - } - fclose(f); - - return 0; -} \ No newline at end of file