-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlfsr.c
More file actions
80 lines (63 loc) · 1.95 KB
/
Copy pathlfsr.c
File metadata and controls
80 lines (63 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/random.h>
#define DEVICE_NAME "lfsr"
static int dev_open(struct inode*, struct file*);
static int dev_release(struct inode*, struct file*);
static ssize_t dev_read(struct file*, char*, size_t, loff_t*);
static ssize_t dev_write(struct file*, const char*, size_t, loff_t*);
static int lfsr_state(void);
static const struct file_operations fops = {
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
};
static int major;
static __uint128_t state;
static int __init lfsr_init(void) {
uint64_t seed = get_random_u64();
state = ((__uint128_t)1 << 127) | (__uint128_t)seed;
major = register_chrdev(0, DEVICE_NAME, &fops);
if (major < 0) {
printk(KERN_INFO "lfsr load failed\n");
return major;
}
printk(KERN_INFO "lfsr module has been loaded: %d\n", major);
return 0;
}
static void __exit lfsr_exit(void) {
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_INFO "lfsr module has been unloaded\n");
}
static int dev_open(struct inode *inodep, struct file *filep) {
printk(KERN_INFO "lfsr device opened\n");
return 0;
}
static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset) {
printk(KERN_INFO "Sorry, lfsr is read only\n");
return -EFAULT;
}
static int dev_release(struct inode *inodep, struct file *filep) {
printk(KERN_INFO "lfsr device closed\n");
return 0;
}
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset) {
int i, errors = 0;
char c = 0;
for(i = 0; i < 8; ++i)
c |= lfsr_state() << i;
errors = copy_to_user(buffer, &c, 1);
return errors == 0 ? 1 : -EFAULT;
}
static int lfsr_state(void) {
uint8_t out = state & 1;
state = (state >> 1) | ((state ^ (state >> 2) ^ (state >> 27) ^ (state >> 29)) << 127);
return out;
}
module_init(lfsr_init);
module_exit(lfsr_exit);
MODULE_LICENSE ("GPL v2");