diff options
Diffstat (limited to '1')
-rw-r--r-- | 1/Makefile | 21 | ||||
-rw-r--r-- | 1/config.h | 26 | ||||
-rw-r--r-- | 1/fopdrv.c | 76 | ||||
-rw-r--r-- | 1/fopdrv.h | 11 | ||||
-rw-r--r-- | 1/main.c | 110 | ||||
-rw-r--r-- | 1/test/.gitignore | 1 | ||||
-rw-r--r-- | 1/test/main.c | 56 | ||||
-rw-r--r-- | 1/test/makefile | 2 | ||||
-rwxr-xr-x | 1/test/test.sh | 24 |
9 files changed, 0 insertions, 327 deletions
diff --git a/1/Makefile b/1/Makefile deleted file mode 100644 index d968e31..0000000 --- a/1/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -RELEASE := $(shell uname -r) -KERNEL := /lib/modules/$(RELEASE)/build -# PWD doesn't have to be defined as it's inherited from the current environment -# MAKE shouldn't be defined as it's special in GNU make - -# the names of these variables are required by the kernel's (imo weird) build -# system, see [kbuild-obj-var] and [kbuild-module-makefile] in ../readme.md -obj-m += lork.o -lork-y += main.o -lork-y += fopdrv.o - -all: - $(MAKE) -C $(KERNEL) M=$(PWD) modules - -# the generated compile_commands.json needs to be edited to point to the kernel -# folder as working directory because the include paths are relative -compile_commands.json: - compiledb -o $@.tmp make -Bn - jq --arg dir $(KERNEL) '.[].directory = $$dir' $@.tmp > $@ - $(RM) $@.tmp - diff --git a/1/config.h b/1/config.h deleted file mode 100644 index dbe3a86..0000000 --- a/1/config.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#define DRV_NAME "lork" - -#include <linux/types.h> - -// values from <https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf> - -typedef uint32_t ti_am335x_word_t; - -// p. 180: "Control Module" -#define TI_AM335X_CM_ADDR 0x44E10000 -// p. 182: "GPIO1" -#define TI_AM335X_GPIO1_ADDR 0x4804C000 -// p. 1459: "conf_gpmc_a3" -#define TI_AM335X_CM_GPMC_A3_ADDR (TI_AM335X_CM_ADDR + 0x84C) - -// p. 4990, variable names copied as-is -#define GPIO_OE (0x134 / (sizeof(ti_am335x_word_t))) -#define GPIO_DATAIN (0x138 / (sizeof(ti_am335x_word_t))) -#define GPIO_CLEARDATAOUT (0x190 / (sizeof(ti_am335x_word_t))) -#define GPIO_SETDATAOUT (0x194 / (sizeof(ti_am335x_word_t))) -// total size of GPIO registers from p. 4990 (in bytes) -#define GPIO_REG_SIZE 0x198 - -#define PIN 19 diff --git a/1/fopdrv.c b/1/fopdrv.c deleted file mode 100644 index 18a1d35..0000000 --- a/1/fopdrv.c +++ /dev/null @@ -1,76 +0,0 @@ -#include <linux/io.h> - -#include "fopdrv.h" -#include "config.h" - -bool printed = false; - -// driver/char/mem.c read_null (/dev/null) -ssize_t fop_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - printk("%s(<file>, <buf>, %u, <ppos>)\n", __PRETTY_FUNCTION__, count); - - if (count < 2) return 0; - if (printed) return 0; - - ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE); - barrier(); - - ti_am335x_word_t gpio = ioread32(gpio1 + GPIO_DATAIN); rmb(); - bool on = (gpio & (1<<PIN)) > 0; - - char output[10]; - snprintf(output, 10, "%d\n", on); - - if (copy_to_user(buf, output + *ppos, 2)) - return -EFAULT; - *ppos += 2; - printed = true; - return 2; -} - -ssize_t fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - printk("%s(<file>, <buf>, %u, <ppos>)\n", __PRETTY_FUNCTION__, count); - - // only allow single character as input - if (count < 1) return count; - if (count > 2) return count; - - // copy buffer for reading (see [kernel-labs-chrdev] in ../readme.md) - char input_buf[10]; - if (copy_from_user(input_buf + *ppos, buf, count)) - return -EFAULT; - - ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE); - barrier(); - - if (input_buf[0] == '0') { - printk("TODO: TURN OFF OUTPUT\n"); - iowrite32((1<<PIN), gpio1 + GPIO_CLEARDATAOUT); wmb(); - } - if (input_buf[0] == '1') { - printk("TODO: TURN ON OUTPUT\n"); - iowrite32((1<<PIN), gpio1 + GPIO_SETDATAOUT); wmb(); - } - - iounmap(gpio1); - - return count; -} - -int fop_open(struct inode * inode, struct file * file) { - printk("%s(<inode>, <file>)\n", __PRETTY_FUNCTION__); - printed = false; - return 0; - // 0 seems to be a safe return value as it's used in driver/char/mem.c. The - // manual page for open(2) says that the system call returns a nonnegative - // integer representing the file descriptor on success, but it does not - // appears to be required. -} - -int fop_release(struct inode * inode, struct file * file) { - printk("%s(<inode>, <file>)\n", __PRETTY_FUNCTION__); - return 0; - // same as above, but found in driver/char/lp.c -} - - diff --git a/1/fopdrv.h b/1/fopdrv.h deleted file mode 100644 index f2ca18c..0000000 --- a/1/fopdrv.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include <linux/fs.h> -#include <linux/types.h> - -// declarations copied from linux/fs.h -ssize_t fop_read(struct file *, char __user *, size_t, loff_t *); -ssize_t fop_write(struct file *, const char __user *, size_t, loff_t *); -int fop_open(struct inode *, struct file *); -int fop_release(struct inode *, struct file *); - diff --git a/1/main.c b/1/main.c deleted file mode 100644 index d8ea7fc..0000000 --- a/1/main.c +++ /dev/null @@ -1,110 +0,0 @@ -#include <linux/cdev.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/io.h> - -#include "fopdrv.h" -#include "config.h" - -int one = 0; -module_param(one, int, 0400); -MODULE_PARM_DESC(one, "first parameter, only printed on init"); - -int not_named_two = 0; -module_param_named(two, not_named_two, int, 0400); -MODULE_PARM_DESC(not_named_two, "second parameter, only printed on init"); - -struct cdev *cdev; -struct device *dev; -struct class *class; -dev_t node; -struct file_operations fops = { - .read = fop_read, - .write = fop_write, - .open = fop_open, - .release = fop_release, -}; - -static int mod_init(void) { - int err; - - err = alloc_chrdev_region(&node, 0, 1, DRV_NAME); - if (err < 0) { - printk(KERN_ERR "alloc_chrdev_region error %d\n", err); - goto return_err; - } - - class = class_create(DRV_NAME); - if (IS_ERR_OR_NULL(class)) { - err = PTR_ERR(class); - printk(KERN_ERR "class_create error %d\n", err); - goto free_class; - } - - cdev = cdev_alloc(); - if (!cdev) { - err = ENOMEM; - goto free_cdev; - } - - cdev->ops = &fops; - cdev_init(cdev, &fops); - err = cdev_add(cdev, node, 1); - if (err < 0) { - printk(KERN_ERR "cdev_add error %d\n", err); - goto free_cdev; - } - - dev = device_create(class, NULL, node, NULL, DRV_NAME); - if (IS_ERR_OR_NULL(dev)) { - err = PTR_ERR(dev); - printk(KERN_ERR "device_create error %d\n", err); - goto free_device; - } - - printk("%s() -> 0 (%d:%d)\n", __PRETTY_FUNCTION__, MAJOR(node), MINOR(node)); - printk("one = %d, two = %d\n", one, not_named_two); - - // configure gpio mux - uint32_t* conf_gpmc_a3 = ioremap(TI_AM335X_CM_GPMC_A3_ADDR, sizeof(ti_am335x_word_t)); - if (conf_gpmc_a3 == NULL) - return -EINVAL; - barrier(); - uint32_t val = ioread32(conf_gpmc_a3); rmb(); - val &= ~0x7; - val |= 0x7; - iowrite32(val, conf_gpmc_a3); wmb(); - iounmap(conf_gpmc_a3); - - // configure output pin - ti_am335x_word_t* gpio1 = ioremap(TI_AM335X_GPIO1_ADDR, GPIO_REG_SIZE); - barrier(); - ti_am335x_word_t oe_reg = ioread32(gpio1 + GPIO_OE); rmb(); - oe_reg &= ~(1<<PIN); // 0=output - iowrite32(oe_reg, gpio1 + GPIO_OE); wmb(); - iounmap(gpio1); - - return 0; - -free_device: - device_destroy(class, node); -free_cdev: - cdev_del(cdev); -free_class: - class_destroy(class); -return_err: - printk("%s() -> %d\n", __PRETTY_FUNCTION__, err); - return err; -} - -static void mod_exit(void) { - device_destroy(class, node); - cdev_del(cdev); - class_destroy(class); - printk("%s()\n", __PRETTY_FUNCTION__); -} - -module_init(mod_init); -module_exit(mod_exit); -MODULE_LICENSE("Dual MIT/GPL"); - diff --git a/1/test/.gitignore b/1/test/.gitignore deleted file mode 100644 index ba2906d..0000000 --- a/1/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -main diff --git a/1/test/main.c b/1/test/main.c deleted file mode 100644 index b87e56c..0000000 --- a/1/test/main.c +++ /dev/null @@ -1,56 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> - -int main(int argc, char** argv) { - if (geteuid() != 0) { - fprintf(stderr, "run me as root!\n"); - return 1; - } - - argc--; // argv[0] is the program name - if (argc == 0) { - fprintf(stderr, "usage: %s /dev/lork\n", argv[0]); - return 1; - } - - char* dev = argv[1]; - const char* input = "test"; - int fd; - ssize_t bytes; - - fd = open(dev, O_RDWR); - if (-1 == fd) { - fprintf(stderr, "open() failed with code %d\n", errno); - return 1; - } - - bytes = write(fd, input, strlen(input)); - if (-1 == bytes) { - fprintf(stderr, "write() failed with code %d\n", errno); - return 1; - } - fprintf(stderr, "input \"%s\" to %s (%ld bytes succesful)\n", input, dev, bytes); - - char buf[80]; - bytes = read(fd, buf, 80); - if (-1 == bytes) { - fprintf(stderr, "read() failed with code %d\n", errno); - return 1; - } - fprintf(stderr, "output from %s: (%ld bytes)\n", dev, bytes); - if (bytes > 0) { - if (bytes < 80) buf[bytes] = '\0'; // null terminate string for printf - printf("%s\n", buf); - } - - if (-1 == close(fd)) { - fprintf(stderr, "close() failed with code %d\n", errno); - return 1; - } - - return 0; -} - diff --git a/1/test/makefile b/1/test/makefile deleted file mode 100644 index 3491973..0000000 --- a/1/test/makefile +++ /dev/null @@ -1,2 +0,0 @@ -main: main.o - diff --git a/1/test/test.sh b/1/test/test.sh deleted file mode 100755 index 7dba005..0000000 --- a/1/test/test.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -if [ $(id -u) -ne 0 ] ; then - echo "run me as root!" >&2 - exit 1 -fi - -if [ $# -eq 0 ] ; then - echo "usage: $0 /dev/lork" >&2 - exit 1 -fi - -DEV="$1" -INPUT="test" - -echo "input \"$INPUT\" to $DEV" >&2 -echo "$INPUT" > "$DEV" -echo "(EC $?)" >&2 - -echo "output from $DEV:" >&2 -cat "$DEV" -echo "(EC $?)" >&2 - -exit 0 |