I've gotten a little further into learning about device drivers and made a simple char device module that allocates 4k of contiguous memory and supposedly attaches it for universal use to a device node:
Code:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
MODULE_LICENSE("GPL");
#define DEVSIZE 4096
typedef struct {
char data[DEVSIZE];
struct cdev cdev;
} OneDevice;
void cleanup(void);
int init(void);
ssize_t read_onedev(struct file *file, char __user *buf, size_t count, loff_t *pos);
ssize_t write_onedev(struct file *file, const char __user *buf, size_t count, loff_t *pos);
//int open_onedev(struct inode *inode, struct file *file);
int Major;
int Minor = 0;
OneDevice TestOne;
char *Current=TestOne.data; /* position pointer */
void cleanup(void) {
memset(TestOne.data,0,4096);
cdev_del(&TestOne.cdev);
printk(KERN_ALERT "Unloaded Test One\n");
}
int init(void) {
int err;
dev_t devMM = 0;
struct file_operations fops = {
.owner = THIS_MODULE,
.read = read_onedev,
.write = write_onedev,
// .open = open_onedev,
};
printk("Loading Test One...");
if ((err=alloc_chrdev_region(&devMM,Minor,1,"testone"))<0) {
printk(KERN_WARNING "alloc_chrdev failed!\n");
return err; }
Major=MAJOR(devMM);
printk("registered MAJOR %d MINOR 0\n",Major);
memset(TestOne.data,0,DEVSIZE);
MKDEV(Major,Minor);
cdev_init(&TestOne.cdev,&fops);
return 0;
}
ssize_t read_onedev(struct file *file, char __user *buf, size_t count, loff_t *pos) {
const void *ptr=Current+(long)*pos;
if ((long)ptr-(long)TestOne.data>=DEVSIZE) { return 0; }
if (DEVSIZE-((long)ptr-(long)TestOne.data)<count) count=DEVSIZE-((long)ptr-(long)TestOne.data);
memcpy((void*)buf,ptr,count);
*pos+=count;
Current=TestOne.data+(long)*pos;
return count;
}
ssize_t write_onedev(struct file *file, const char __user *buf, size_t count, loff_t *pos) {
void *ptr=Current+(long)*pos;
if (DEVSIZE-((long)ptr-(long)TestOne.data)<count) count=DEVSIZE-((long)ptr-(long)TestOne.data);
if (count<=0) { return 0; }
memcpy(ptr,(const void*)buf,count);
*pos+=count;
Current=TestOne.data+(long)*pos;
return count;
}
module_init(init);
module_exit(cleanup);
It compiles, loads, and registers fine. Then I get the actual device node number from /var/messages and use it as an argument to this shell script:
Code:
#!/bin/bash
if [ -c /dev/testone ]
then
rm -v -f /dev/testone
fi
mknod /dev/testone c $1 0
chgrp wheel /dev/testone
chmod 664 /dev/testone
Now, supposedly I should be able to do basic normal things like "cat somefile > /dev/testone" but when I try, I get "bash: /dev/testone: No such device or address" altho stat says it exists and is a character special file.
So I was just wondering if anyone had done this stuff before and might have an insight.