--- /dev/null
+
+KDIR ?= /lib/modules/$(shell uname -r)/build
+
+
+PWD := $(shell pwd)
+obj-m += krealloc.o
+EXTRA_CFLAGS += -DDEBUG
+
+all:
+ @echo
+ @echo '--- Building : KDIR=${KDIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} EXTRA_CFLAGS=${EXTRA_CFLAGS} ---'
+ @echo
+ make -C $(KDIR) M=$(PWD) modules
+install:
+ @echo
+ @echo "--- installing ---"
+ @echo
+ make -C $(KDIR) M=$(PWD) modules_install
+clean:
+ @echo
+ @echo "--- cleaning ---"
+ @echo
+ make -C $(KDIR) M=$(PWD) clean
+ rm -f *~ # from 'indent'
+
--- /dev/null
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define OURMODNAME "slab1_krealloc"
+
+MODULE_AUTHOR("seantywork");
+MODULE_LICENSE("Dual MIT/GPL");
+MODULE_VERSION("0.1");
+
+static char *gkptr;
+
+static int __init slab1_init(void)
+{
+ gkptr = kmalloc(1024, GFP_KERNEL);
+ if (!gkptr) {
+ goto out_fail1;
+ }
+ pr_info("%s: context struct realloc'ed (actual KVA ret = %px)\n",
+ OURMODNAME, gkptr);
+ print_hex_dump_bytes("ptr: ", DUMP_PREFIX_OFFSET, gkptr, 32);
+
+ gkptr = krealloc(gkptr, 2048, GFP_KERNEL);
+ if (!gkptr){
+ goto out_fail2;
+ }
+ pr_info("%s: context struct realloc'ed (actual KVA ret = %px)\n",
+ OURMODNAME, gkptr);
+ print_hex_dump_bytes("ptr: ", DUMP_PREFIX_OFFSET, gkptr, 32);
+ return 0; /* success */
+
+ out_fail2:
+ kfree(gkptr);
+ out_fail1:
+ return -ENOMEM;
+}
+
+static void __exit slab1_exit(void)
+{
+ kfree(gkptr);
+ pr_info("%s: freed slab memory, removed\n", OURMODNAME);
+}
+
+module_init(slab1_init);
+module_exit(slab1_exit);
\ 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
+++ /dev/null
-obj-m += user_value.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
-
-echo "***** char dev result"
-
-cat /dev/user_value
-
-echo "*****"
\ No newline at end of file
+++ /dev/null
-#!/bin/bash
-
-sudo insmod ./user_value.ko
-dev="user_value"
-major="$(grep "$dev" /proc/devices | cut -d ' ' -f 1)"
-sudo mknod "/dev/$dev" c "$major" 0
-
-echo "dev node created"
-echo "/dev/$dev"
\ No newline at end of file
+++ /dev/null
-#!/bin/bash
-
-
-sudo rm /dev/user_value
-sudo rmmod user_value
-
-
-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>
-
-static int device_open(struct inode *, struct file *);
-static int device_release(struct inode *, struct file *);
-static ssize_t device_read(struct file *, char *, size_t, loff_t *);
-static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
-
-#define SUCCESS 0
-#define DEVICE_NAME "user_value"
-#define BUF_LEN 80
-
-
-static int dev_major;
-static int device_open_counter = 0;
-static char msg[BUF_LEN];
-static char *msg_buff_ptr;
-
-static struct file_operations fops = {
- .read = device_read,
- .write = device_write,
- .open = device_open,
- .release = device_release
-};
-
-
-
-static int device_open(struct inode *inode, struct file *filp){
- static int counter = 0;
- if (device_open_counter)
- return -EBUSY;
- device_open_counter++;
- sprintf(msg, "counter: %d\n", counter++);
- msg_buff_ptr = msg;
- 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 length,
- loff_t *offset)
-{
-
- int bytes_read = 0;
- if (*msg_buff_ptr == 0){
- return 0;
- }
- while (length && *msg_buff_ptr) {
- put_user(*(msg_buff_ptr++), buffer++);
- length--;
- bytes_read++;
- }
- return bytes_read;
-}
-
-
-static ssize_t device_write(struct file *filp, const char *buf, size_t len, loff_t *off){
- printk(KERN_ALERT "operation not supported.\n");
- return -EINVAL;
-}
-
-static int __init init_user_value(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_user_value(void){
- unregister_chrdev(dev_major, DEVICE_NAME);
-}
-
-module_init(init_user_value);
-module_exit(exit_user_value);
-MODULE_LICENSE("GPL");
\ No newline at end of file