Initial commit
This commit is contained in:
commit
5fa601852f
|
@ -0,0 +1,7 @@
|
|||
*
|
||||
!.gitignore
|
||||
!bible.c
|
||||
!bible.h
|
||||
!Makefile
|
||||
!LICENSE
|
||||
!README.md
|
|
@ -0,0 +1,19 @@
|
|||
ifneq ($(KERNELRELEASE),)
|
||||
obj-m := bible.o
|
||||
|
||||
else
|
||||
KDIR ?= /lib/modules/`uname -r`/build
|
||||
|
||||
default:
|
||||
$(MAKE) -C $(KDIR) M=$$PWD
|
||||
|
||||
clean:
|
||||
find . \( -name '*.o' -or -name '*.ko' \) -delete
|
||||
rm -f *.mod.c
|
||||
rm -rf modules.order Module.symvers
|
||||
|
||||
install:
|
||||
$(MAKE) -C $(KDIR) M=$$PWD modules_install
|
||||
|
||||
endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# bible
|
||||
|
||||
A Linux kernel module that adds The Holy Bible as a character device, /dev/bible.
|
||||
|
||||
## Building
|
||||
|
||||
~~~~
|
||||
$ make
|
||||
$ sudo make install
|
||||
~~~~
|
||||
|
||||
## Build dependencies
|
||||
|
||||
* Linux kernel headers
|
||||
* make
|
||||
* GCC
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "bible.h"
|
||||
|
||||
MODULE_LICENSE("GPL"); //God's Parables and Liturgy
|
||||
|
||||
int init_module(void);
|
||||
void cleanup_module(void);
|
||||
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 int on_dev_uevent(struct device*, struct kobj_uevent_env*);
|
||||
|
||||
#define DEVICE_NAME "bible"
|
||||
|
||||
static dev_t devt;
|
||||
static struct class* device_class;
|
||||
static struct device* device;
|
||||
static struct cdev character_device;
|
||||
|
||||
static struct file_operations fops = {
|
||||
.read = device_read,
|
||||
.open = device_open,
|
||||
.release = device_release
|
||||
};
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
int result;
|
||||
if((result = alloc_chrdev_region(&devt, 0, 1, DEVICE_NAME)) < 0)
|
||||
{
|
||||
printk(KERN_ALERT "Couldn't alloc chrdev region: %d\n", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if((device_class = class_create(THIS_MODULE, DEVICE_NAME)) == NULL)
|
||||
{
|
||||
printk(KERN_ALERT "Couldn't create device class\n");
|
||||
|
||||
unregister_chrdev_region(devt, 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
device_class->dev_uevent = on_dev_uevent;
|
||||
|
||||
if((device = device_create(device_class, NULL, devt, NULL, DEVICE_NAME)) == NULL)
|
||||
{
|
||||
printk(KERN_ALERT "Couldn't create device\n");
|
||||
|
||||
class_destroy(device_class);
|
||||
unregister_chrdev_region(devt, 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cdev_init(&character_device, &fops);
|
||||
|
||||
if((result = cdev_add(&character_device, devt, 1)) < 0)
|
||||
{
|
||||
printk(KERN_ALERT "Couldn't add character device\n");
|
||||
|
||||
device_destroy(device_class, devt);
|
||||
class_destroy(device_class);
|
||||
unregister_chrdev_region(devt, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_module(void)
|
||||
{
|
||||
device_destroy(device_class, devt);
|
||||
class_destroy(device_class);
|
||||
unregister_chrdev_region(devt, 1);
|
||||
}
|
||||
|
||||
static int on_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
add_uevent_var(env, "DEVMODE=%#o", 0444);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int device_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
try_module_get(THIS_MODULE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int device_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
module_put(THIS_MODULE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if(*offset + length > bible_txt_len)
|
||||
{
|
||||
length = bible_txt_len - *offset;
|
||||
}
|
||||
|
||||
for(; i < length; i++)
|
||||
{
|
||||
put_user(*(bible_txt + *offset + i), buffer + i);
|
||||
}
|
||||
|
||||
*offset += length;
|
||||
|
||||
return i;
|
||||
}
|
Loading…
Reference in New Issue