--- /dev/null
+#
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#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
--- /dev/null
+#!/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
--- /dev/null
+#!/bin/bash
+
+sudo rm ./user/chr_store
+sudo rmmod chr_store
+
+
+echo "dev node destroyed"
\ No newline at end of file
--- /dev/null
+all:
+ gcc -Wall -o u.out u.c
+clean:
+ rm -rf *.out *.o
\ No newline at end of file
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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
+++ /dev/null
-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
+++ /dev/null
-#!/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
+++ /dev/null
-#!/bin/bash
-
-sudo rm ./user/mem_storage
-sudo rmmod mem_storage
-
-
-echo "dev node destroyed"
\ No newline at end of file
+++ /dev/null
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#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
+++ /dev/null
-all:
- gcc -Wall -o u.out u.c
-clean:
- rm -rf *.out *.o
\ No newline at end of file
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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