kernel-helloworld-test

changeset 0:dbbd63da261f tip

helloworld kernel module and program that reads the /dev/ktest
author Eleni Maria Stea <eleni@mutantstargoat.com>
date Wed, 10 May 2017 13:11:31 +0300
parents
children
files .hgignore ktestmodule/Makefile ktestmodule/ktest.c ktestprogram/Makefile ktestprogram/kprog.c
diffstat 5 files changed, 146 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Wed May 10 13:11:31 2017 +0300
     1.3 @@ -0,0 +1,9 @@
     1.4 +syntax:glob
     1.5 +*.swp
     1.6 +*.o
     1.7 +*.cmd
     1.8 +*.ko
     1.9 +*.symvers
    1.10 +*.order
    1.11 +*.mod
    1.12 +*.mod.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/ktestmodule/Makefile	Wed May 10 13:11:31 2017 +0300
     2.3 @@ -0,0 +1,9 @@
     2.4 +obj-m += ktest.o
     2.5 +
     2.6 +.PHONY: all
     2.7 +all:
     2.8 +	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
     2.9 +
    2.10 +.PHONY: clean
    2.11 +clean:
    2.12 +	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/ktestmodule/ktest.c	Wed May 10 13:11:31 2017 +0300
     3.3 @@ -0,0 +1,91 @@
     3.4 +#include <asm/uaccess.h>
     3.5 +#include <linux/fs.h>
     3.6 +#include <linux/kernel.h>
     3.7 +#include <linux/module.h>
     3.8 +#include <linux/slab.h>
     3.9 +
    3.10 +#define DEV_NAME "ktest"
    3.11 +
    3.12 +static int ktest_init(void);
    3.13 +static void ktest_fini(void);
    3.14 +
    3.15 +static int ktest_open(struct inode *inode, struct file *file);
    3.16 +static int ktest_release(struct inode *inode, struct file *file);
    3.17 +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size,
    3.18 +		loff_t *offset);
    3.19 +
    3.20 +static int dev_num;
    3.21 +static struct file_operations ops = {
    3.22 +	.open = ktest_open,
    3.23 +	.release = ktest_release,
    3.24 +	.read = ktest_read
    3.25 +};
    3.26 +static int hello_counter;
    3.27 +
    3.28 +/* macros */
    3.29 +
    3.30 +MODULE_LICENSE("GPL");
    3.31 +MODULE_AUTHOR("hikiko");
    3.32 +MODULE_DESCRIPTION("my kernel helloworld");
    3.33 +
    3.34 +module_init(ktest_init);
    3.35 +module_exit(ktest_fini);
    3.36 +
    3.37 +static int ktest_init(void)
    3.38 +{
    3.39 +	hello_counter = 0;
    3.40 +
    3.41 +	/* register character device */
    3.42 +	if((dev_num = register_chrdev(0, DEV_NAME, &ops)) < 0) {
    3.43 +		printk(KERN_ALERT "Failed to register character device.\n");
    3.44 +		return -1;
    3.45 +	}
    3.46 +	printk(KERN_INFO "Registered character device. Name: %s number: %d.\n", DEV_NAME, dev_num);
    3.47 +	return 0;
    3.48 +}
    3.49 +
    3.50 +static void ktest_fini(void)
    3.51 +{
    3.52 +	unregister_chrdev(dev_num, DEV_NAME);
    3.53 +	printk(KERN_INFO "Unregistered character device. Name: %s number: %d.\n", DEV_NAME, dev_num);
    3.54 +}
    3.55 +
    3.56 +static int ktest_open(struct inode *inode, struct file *file)
    3.57 +{
    3.58 +	/* 1 device file only => we ignore the params ^ */
    3.59 +	try_module_get(THIS_MODULE);
    3.60 +	return 0;
    3.61 +}
    3.62 +
    3.63 +static int ktest_release(struct inode *inode, struct file *file)
    3.64 +{
    3.65 +	module_put(THIS_MODULE);
    3.66 +	return 0;
    3.67 +}
    3.68 +
    3.69 +static ssize_t ktest_read(struct file *file, char *buf, size_t buf_size,
    3.70 +		loff_t *offset)
    3.71 +{
    3.72 +	/* buf = userspace buffer,
    3.73 +	 * kbuf = kernel buffer */
    3.74 +
    3.75 +	char *kbuf;
    3.76 +	int bytes;
    3.77 +
    3.78 +	if(!(kbuf = kmalloc(buf_size, GFP_KERNEL))) {
    3.79 +		printk(KERN_ALERT "Failed to allocate memory.\n");
    3.80 +		return -ENOMEM;
    3.81 +	}
    3.82 +
    3.83 +	/* fill kbuf and copy to userspace buf */
    3.84 +	bytes = snprintf(kbuf, buf_size, "Hello world, num: %d.\n", ++hello_counter);
    3.85 +
    3.86 +	if(copy_to_user(buf, kbuf, bytes))
    3.87 +	{
    3.88 +		kfree(kbuf);
    3.89 +		return -EFAULT;
    3.90 +	}
    3.91 +
    3.92 +	kfree(kbuf);
    3.93 +	return bytes;
    3.94 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/ktestprogram/Makefile	Wed May 10 13:11:31 2017 +0300
     4.3 @@ -0,0 +1,9 @@
     4.4 +obj = kprog.o
     4.5 +CFLAGS = -pedantic -Wall -g
     4.6 +
     4.7 +kprog: $(obj)
     4.8 +	$(CC) -o $@ $^ $(LDFLAGS)
     4.9 +
    4.10 +.PHONY: clean
    4.11 +clean:
    4.12 +	rm -f $(obj) kprog
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/ktestprogram/kprog.c	Wed May 10 13:11:31 2017 +0300
     5.3 @@ -0,0 +1,28 @@
     5.4 +#include <fcntl.h>
     5.5 +#include <stdio.h>
     5.6 +#include <unistd.h>
     5.7 +
     5.8 +int main(void)
     5.9 +{
    5.10 +	char buf[512];
    5.11 +	size_t size;
    5.12 +	int fd;
    5.13 +
    5.14 +	if((fd = open("/dev/ktest", O_RDONLY)) == -1) {
    5.15 +		fprintf(stderr, "Failed to open device ktest.\n");
    5.16 +		return 1;
    5.17 +	}
    5.18 +
    5.19 +	if((size = read(fd, buf, sizeof buf)) == -1) {
    5.20 +		fprintf(stderr, "Failed to read from device ktest.\n");
    5.21 +
    5.22 +		close(fd);
    5.23 +		return 1;
    5.24 +	}
    5.25 +	printf("num char: %d\n", (int)size);
    5.26 +
    5.27 +	buf[size] = 0;
    5.28 +	printf("quoting kernel: %s", buf);
    5.29 +	close(fd);
    5.30 +	return 0;
    5.31 +}