From 1d7d3e37ec3fa31047786d29a5b778d0ef57e881 Mon Sep 17 00:00:00 2001
From: Peter Gerwinski <peter.gerwinski@hs-bochum.de>
Date: Fri, 7 May 2021 15:45:45 +0200
Subject: [PATCH] Notizen und Beispiele 7.5.2021

---
 20210507/Makefile           |   1 +
 20210507/Makefile-modules-2 |   9 ++
 20210507/attributes-1.txt   |  43 ++++++++
 20210507/bs-20210507.txt    |  11 ++
 20210507/chardev-1a.c       | 166 ++++++++++++++++++++++++++++++
 20210507/chardev-1b.c       | 169 ++++++++++++++++++++++++++++++
 20210507/chardev-2.c        | 183 +++++++++++++++++++++++++++++++++
 20210507/chardev-3.c        | 198 ++++++++++++++++++++++++++++++++++++
 20210507/hello-1.c          |   7 ++
 20210507/hello-1.s          |  24 +++++
 20210507/hello-2.c          |   7 ++
 20210507/hello-2.s          |  24 +++++
 20210507/hello-3.c          |  12 +++
 20210507/modules-5.txt      |   8 ++
 20210507/modules-6.txt      |  40 ++++++++
 20210507/modules-7.txt      |  37 +++++++
 20210507/os-layers-1.jpg    |   1 +
 20210507/os-layers-2.jpg    |   1 +
 20210507/os-layers-3.jpg    |   1 +
 20210507/os-layers-4.jpg    |   1 +
 20210507/os-layers-5.jpg    |   1 +
 projekte.txt                |   1 +
 22 files changed, 945 insertions(+)
 create mode 120000 20210507/Makefile
 create mode 100644 20210507/Makefile-modules-2
 create mode 100644 20210507/attributes-1.txt
 create mode 100644 20210507/bs-20210507.txt
 create mode 100644 20210507/chardev-1a.c
 create mode 100644 20210507/chardev-1b.c
 create mode 100644 20210507/chardev-2.c
 create mode 100644 20210507/chardev-3.c
 create mode 100644 20210507/hello-1.c
 create mode 100644 20210507/hello-1.s
 create mode 100644 20210507/hello-2.c
 create mode 100644 20210507/hello-2.s
 create mode 100644 20210507/hello-3.c
 create mode 100644 20210507/modules-5.txt
 create mode 100644 20210507/modules-6.txt
 create mode 100644 20210507/modules-7.txt
 create mode 120000 20210507/os-layers-1.jpg
 create mode 120000 20210507/os-layers-2.jpg
 create mode 120000 20210507/os-layers-3.jpg
 create mode 120000 20210507/os-layers-4.jpg
 create mode 120000 20210507/os-layers-5.jpg

diff --git a/20210507/Makefile b/20210507/Makefile
new file mode 120000
index 0000000..134aa0a
--- /dev/null
+++ b/20210507/Makefile
@@ -0,0 +1 @@
+Makefile-modules-2
\ No newline at end of file
diff --git a/20210507/Makefile-modules-2 b/20210507/Makefile-modules-2
new file mode 100644
index 0000000..f9f3426
--- /dev/null
+++ b/20210507/Makefile-modules-2
@@ -0,0 +1,9 @@
+obj-m += chardev-1a.o
+obj-m += chardev-1b.o
+obj-m += chardev-3.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff --git a/20210507/attributes-1.txt b/20210507/attributes-1.txt
new file mode 100644
index 0000000..e6fe610
--- /dev/null
+++ b/20210507/attributes-1.txt
@@ -0,0 +1,43 @@
+crw-------  1 root  root     10, 137 Apr  6 09:59 vhci
+crw-------  1 root  root     10, 238 Apr  6 09:59 vhost-net
+crw-------  1 root  root     10, 241 Apr  6 09:59 vhost-vsock
+crw-rw----+ 1 root  video    81,   0 Mai  7 10:44 video0
+crw-rw----+ 1 root  video    81,   1 Mai  7 10:44 video1
+crw-rw----+ 1 root  video    81,   2 Apr 28 23:30 video4
+crw-------  1 root  root     10, 130 Apr  6 09:59 watchdog
+crw-------  1 root  root    248,   0 Apr  6 09:59 watchdog0
+crw-rw-rw-  1 root  root      1,   5 Apr  6 09:59 zero
+cassini/home/peter/bo/2021ss/bs/20210507> ls -l /dev/chardev
+crw------- 1 root root 241, 0 Mai  7 14:17 /dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev
+cat: /dev/chardev: Keine Berechtigung
+cassini/home/peter/bo/2021ss/bs/20210507> sudo chmod 666 /dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210507> ls -l /dev/chardev
+crw-rw-rw- 1 root root 241, 0 Mai  7 14:17 /dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev
+I already told you 1 times Hello world!
+cassini/home/peter/bo/2021ss/bs/20210507> cat /dev/chardev
+I already told you 2 times Hello world!
+cassini/home/peter/bo/2021ss/bs/20210507> lsattr /dev/video0
+lsattr: Die Operation wird nicht unterstützt Beim Lesen der Flags von /dev/video0
+cassini/home/peter/bo/2021ss/bs/20210507> getfacl /dev/video0
+getfacl: Entferne führende '/' von absoluten Pfadnamen
+# file: dev/video0
+# owner: root
+# group: video
+user::rw-
+user:peter:rw-
+group::rw-
+mask::rw-
+other::---
+
+cassini/home/peter/bo/2021ss/bs/20210507> getfacl /dev/chardev
+getfacl: Entferne führende '/' von absoluten Pfadnamen
+# file: dev/chardev
+# owner: root
+# group: root
+user::rw-
+group::rw-
+other::rw-
+
+cassini/home/peter/bo/2021ss/bs/20210507>
diff --git a/20210507/bs-20210507.txt b/20210507/bs-20210507.txt
new file mode 100644
index 0000000..cccf426
--- /dev/null
+++ b/20210507/bs-20210507.txt
@@ -0,0 +1,11 @@
+Von der Anwendung bis zum Kernel: libc, 07.05.2021, 15:11:00
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+apt-get source libc6
+Datei: stdio-common/printf.c
+printf() ruft vfprintf() auf.
+Datei: stdio-common/vfprintf.c
+vfprintf() ruft printf_positional() auf.
+printf_positional() ruft outstring() auf.
+outstring() ist ein Präprozessor-Macro.
+outstring() ruft PUT() auf - ebenfalls ein Präprozessor-Macro.
+PUT() ruft _IO_sputn() auf. --> in anderer Datei
diff --git a/20210507/chardev-1a.c b/20210507/chardev-1a.c
new file mode 100644
index 0000000..291b052
--- /dev/null
+++ b/20210507/chardev-1a.c
@@ -0,0 +1,166 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+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 ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+	printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
+	printk(KERN_INFO "the driver, create a dev file with\n");
+	printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
+	printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
+	printk(KERN_INFO "the device file.\n");
+	printk(KERN_INFO "Remove the device file and module when done.\n");
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+	/* 
+	 * Unregister the device 
+	 */
+	unregister_chrdev(Major, DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_INFO "Got user data: %s.\n", buff);
+	return len;
+}
diff --git a/20210507/chardev-1b.c b/20210507/chardev-1b.c
new file mode 100644
index 0000000..574497c
--- /dev/null
+++ b/20210507/chardev-1b.c
@@ -0,0 +1,169 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+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 ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+	printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
+	printk(KERN_INFO "the driver, create a dev file with\n");
+	printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
+	printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
+	printk(KERN_INFO "the device file.\n");
+	printk(KERN_INFO "Remove the device file and module when done.\n");
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+	/* 
+	 * Unregister the device 
+	 */
+	unregister_chrdev(Major, DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+        char b[len + 1];
+        strncpy (b, buff, len);
+        b[len] = 0;
+	printk(KERN_INFO "Got user data: %s.\n", b);
+	return len;
+}
diff --git a/20210507/chardev-2.c b/20210507/chardev-2.c
new file mode 100644
index 0000000..54b8e3f
--- /dev/null
+++ b/20210507/chardev-2.c
@@ -0,0 +1,183 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+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 ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+struct class *dev_Class;
+struct device *chr_dev;
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+        // Create module class
+        printk(KERN_INFO "Creating device class LCD...\n");
+        dev_Class = class_create(THIS_MODULE,DEVICE_NAME);
+        if( dev_Class == NULL)
+        {
+            printk( KERN_ALERT "Error! Class couldn't be created!\n" );
+            return 1 ;
+        }
+        printk( KERN_INFO "Class created!\n" );
+        // Create device in /dev/...
+        printk(KERN_INFO "Creating device\n");
+        chr_dev = device_create(dev_Class, NULL, MKDEV(Major,0), NULL, DEVICE_NAME);
+
+	printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
+	printk(KERN_INFO "the driver, create a dev file with\n");
+	printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
+	printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");
+	printk(KERN_INFO "the device file.\n");
+	printk(KERN_INFO "Remove the device file and module when done.\n");
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+	/* 
+	 * Unregister the device 
+	 */
+	unregister_chrdev(Major, DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20210507/chardev-3.c b/20210507/chardev-3.c
new file mode 100644
index 0000000..516a074
--- /dev/null
+++ b/20210507/chardev-3.c
@@ -0,0 +1,198 @@
+/*
+ *  chardev.c: Creates a read-only char device that says how many times
+ *  you've read from the dev file
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>	/* for put_user */
+
+MODULE_LICENSE("GPL");
+
+/*  
+ *  Prototypes - this would normally go in a .h file
+ */
+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 ssize_t device_write(struct file *, const char *, size_t, loff_t *);
+
+struct class *dev_Class;
+struct device *chr_dev;
+
+#define SUCCESS 0
+#define DEVICE_NAME "chardev"	/* Dev name as it appears in /proc/devices   */
+#define BUF_LEN 80		/* Max length of the message from the device */
+
+/* 
+ * Global variables are declared as static, so are global within the file. 
+ */
+
+static int Major;		/* Major number assigned to our device driver */
+static int Device_Open = 0;	/* Is device open?  
+				 * Used to prevent multiple access to device */
+static char msg[BUF_LEN];	/* The msg the device will give when asked */
+static char *msg_Ptr;
+
+static struct file_operations fops = {
+	.read = device_read,
+	.write = device_write,
+	.open = device_open,
+	.release = device_release
+};
+
+/*
+ * This function is called when the module is loaded
+ */
+int init_module(void)
+{
+        Major = register_chrdev(0, DEVICE_NAME, &fops);
+
+	if (Major < 0) {
+	  printk(KERN_ALERT "Registering char device failed with %d\n", Major);
+	  return Major;
+	}
+
+        // Create module class
+        printk (KERN_INFO "Creating device class \"chardev\" ...\n");
+        dev_Class = class_create (THIS_MODULE,DEVICE_NAME);
+        if( dev_Class == NULL)
+        {
+            printk (KERN_ALERT "Error! Class couldn't be created!\n");
+            return 1;
+        }
+        printk (KERN_INFO "Class created!\n");
+        // Create device in /dev/...
+        printk (KERN_INFO "Creating device\n");
+        chr_dev = device_create (dev_Class, NULL, MKDEV (Major,0), NULL, DEVICE_NAME);
+        if (chr_dev == NULL)
+        {
+            printk( KERN_ALERT "Error! Device couldn't be created!\n" );
+            return 1 ;
+        }
+
+	return SUCCESS;
+}
+
+/*
+ * This function is called when the module is unloaded
+ */
+void cleanup_module(void)
+{
+        printk(KERN_INFO "module chardev-4 cleanup\n");
+        //Unregister the device
+        if (chr_dev)
+          {
+            printk(KERN_INFO "Unregister device ...\n");
+            device_unregister(chr_dev);
+            printk(KERN_INFO "OK\n");
+          }
+
+        if (dev_Class)
+          {
+            printk(KERN_INFO "Unregister class ...\n");
+            class_unregister(dev_Class);
+            printk(KERN_INFO "OK\n");
+          }
+
+        printk(KERN_INFO "Unregister Chardev ...\n");
+        unregister_chrdev(Major, DEVICE_NAME);
+        printk(KERN_INFO "Device %s unregistered!\n", DEVICE_NAME);
+}
+
+/*
+ * Methods
+ */
+
+/* 
+ * Called when a process tries to open the device file, like
+ * "cat /dev/mycharfile"
+ */
+static int device_open(struct inode *inode, struct file *file)
+{
+	static int counter = 0;
+
+	if (Device_Open)
+		return -EBUSY;
+
+	Device_Open++;
+	sprintf(msg, "I already told you %d times Hello world!\n", counter++);
+	msg_Ptr = msg;
+	try_module_get(THIS_MODULE);
+
+	return SUCCESS;
+}
+
+/* 
+ * Called when a process closes the device file.
+ */
+static int device_release(struct inode *inode, struct file *file)
+{
+	Device_Open--;		/* We're now ready for our next caller */
+
+	/* 
+	 * Decrement the usage count, or else once you opened the file, you'll
+	 * never get get rid of the module. 
+	 */
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+/* 
+ * Called when a process, which already opened the dev file, attempts to
+ * read from it.
+ */
+static ssize_t device_read(struct file *filp,	/* see include/linux/fs.h   */
+			   char *buffer,	/* buffer to fill with data */
+			   size_t length,	/* length of the buffer     */
+			   loff_t * offset)
+{
+	/*
+	 * Number of bytes actually written to the buffer 
+	 */
+	int bytes_read = 0;
+
+	/*
+	 * If we're at the end of the message, 
+	 * return 0 signifying end of file 
+	 */
+	if (*msg_Ptr == 0)
+		return 0;
+
+	/* 
+	 * Actually put the data into the buffer 
+	 */
+	while (length && *msg_Ptr) {
+
+		/* 
+		 * The buffer is in the user data segment, not the kernel 
+		 * segment so "*" assignment won't work.  We have to use 
+		 * put_user which copies data from the kernel data segment to
+		 * the user data segment. 
+		 */
+		put_user(*(msg_Ptr++), buffer++);
+
+		length--;
+		bytes_read++;
+	}
+
+	/* 
+	 * Most read functions return the number of bytes put into the buffer
+	 */
+	return bytes_read;
+}
+
+/*  
+ * Called when a process writes to dev file: echo "hi" > /dev/hello 
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+	printk(KERN_ALERT "Sorry, this operation isn't supported.\n");
+	return -EINVAL;
+}
diff --git a/20210507/hello-1.c b/20210507/hello-1.c
new file mode 100644
index 0000000..b19d80e
--- /dev/null
+++ b/20210507/hello-1.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void)
+{
+  printf ("Hello, world!\n");
+  return 0;
+}
diff --git a/20210507/hello-1.s b/20210507/hello-1.s
new file mode 100644
index 0000000..74d6a36
--- /dev/null
+++ b/20210507/hello-1.s
@@ -0,0 +1,24 @@
+	.file	"hello-1.c"
+	.text
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"Hello, world!"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc                     # #include <stdio.h>
+	subq	$8, %rsp                   # 
+	.cfi_def_cfa_offset 16             # int main (void)
+	leaq	.LC0(%rip), %rdi           # {
+	call	puts@PLT                   #   printf ("Hello, world!\n");
+	movl	$0, %eax                   #   return 0;
+	addq	$8, %rsp                   # }
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
+	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/20210507/hello-2.c b/20210507/hello-2.c
new file mode 100644
index 0000000..b767f77
--- /dev/null
+++ b/20210507/hello-2.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main (void)
+{
+  puts ("Hello, world!");
+  return 0;
+}
diff --git a/20210507/hello-2.s b/20210507/hello-2.s
new file mode 100644
index 0000000..272bf70
--- /dev/null
+++ b/20210507/hello-2.s
@@ -0,0 +1,24 @@
+	.file	"hello-2.c"
+	.text
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"Hello, world!"
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc
+	subq	$8, %rsp
+	.cfi_def_cfa_offset 16
+	leaq	.LC0(%rip), %rdi
+	call	puts@PLT
+	movl	$0, %eax
+	addq	$8, %rsp
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
+	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/20210507/hello-3.c b/20210507/hello-3.c
new file mode 100644
index 0000000..e94ca36
--- /dev/null
+++ b/20210507/hello-3.c
@@ -0,0 +1,12 @@
+extern int puts (char *s);
+
+void printf (void)
+{
+  puts ("Hello, world!");
+}
+
+int main (void)
+{
+  printf ();
+  return 0;
+}
diff --git a/20210507/modules-5.txt b/20210507/modules-5.txt
new file mode 100644
index 0000000..c35d087
--- /dev/null
+++ b/20210507/modules-5.txt
@@ -0,0 +1,8 @@
+cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev
+cat: dev/chardev: Kein passendes Gerät bzw. keine passende Adresse gefunden
+cassini/home/peter/bo/2021ss/bs/20210430> ls -l dev/chardev
+crw-rw-rw- 1 root root 241, 0 Apr 30 15:14 dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210430> sudo cat dev/chardev
+cat: dev/chardev: Kein passendes Gerät bzw. keine passende Adresse gefunden
+cassini/home/peter/bo/2021ss/bs/20210430> lsmod | grep chardev
+cassini/home/peter/bo/2021ss/bs/20210430>
diff --git a/20210507/modules-6.txt b/20210507/modules-6.txt
new file mode 100644
index 0000000..e96c840
--- /dev/null
+++ b/20210507/modules-6.txt
@@ -0,0 +1,40 @@
+cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod chardev-1a.ko
+cassini/home/peter/bo/2021ss/bs/20210430> lsmod | grep chardev
+chardev_1a             16384  0
+cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev
+I already told you 0 times Hello world!
+cassini/home/peter/bo/2021ss/bs/20210430> cat dev/chardev
+I already told you 1 times Hello world!
+cassini/home/peter/bo/2021ss/bs/20210430> echo "Dies ist ein Test." > dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210430>
+
+
+Inhalt von /var/log/kern.log:
+
+May  7 12:57:21 cassini kernel: [1601195.178390] I was assigned major number 241. To talk to
+May  7 12:57:21 cassini kernel: [1601195.178391] the driver, create a dev file with
+May  7 12:57:21 cassini kernel: [1601195.178392] 'mknod /dev/chardev c 241 0'.
+May  7 12:57:21 cassini kernel: [1601195.178392] Try various minor numbers. Try to cat and echo to
+May  7 12:57:21 cassini kernel: [1601195.178392] the device file.
+May  7 12:57:21 cassini kernel: [1601195.178393] Remove the device file and module when done.
+May  7 12:57:40 cassini kernel: [1601214.177086] Got user data: Dies ist ein Test.
+May  7 12:57:40 cassini kernel: [1601214.177086] ss/bs/20210430
+May  7 12:57:40 cassini kernel: [1601214.177086] indow -P openmeetings https://www.cvh-server.de/vnc/ &
+May  7 12:57:40 cassini kernel: [1601214.177086]        return
+May  7 12:57:40 cassini kernel: [1601214.177086]         ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]     esac;
+May  7 12:57:40 cassini kernel: [1601214.177086]     local complete_opt="--others --modified --directory --no-empty-directory";
+May  7 12:57:40 cassini kernel: [1601214.177086]     if test -n "$(__git_find_on_cmdline "-u --update")"; then
+May  7 12:57:40 cassini kernel: [1601214.177086]         complete_opt="--modified";
+May  7 12:57:40 cassini kernel: [1601214.177086]     fi;
+May  7 12:57:40 cassini kernel: [1601214.177086]     __git_complete_index_file "$complete_opt"
+May  7 12:57:40 cassini kernel: [1601214.177086]                 exclude=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]             p)
+May  7 12:57:40 cassini kernel: [1601214.177086]                 vprev=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]             w)
+May  7 12:57:40 cassini kernel: [1601214.177086]                 vwords=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]         esac;
+May  7 12:57:40 cassini kernel: [1601214.177086]     done;
diff --git a/20210507/modules-7.txt b/20210507/modules-7.txt
new file mode 100644
index 0000000..43d3062
--- /dev/null
+++ b/20210507/modules-7.txt
@@ -0,0 +1,37 @@
+cassini/home/peter/bo/2021ss/bs/20210430> sudo insmod chardev-1b.ko
+cassini/home/peter/bo/2021ss/bs/20210430> echo "Dies ist ein Test." > dev/chardev
+cassini/home/peter/bo/2021ss/bs/20210430> sudo tail -22 /var/log/kern.log
+May  7 12:57:40 cassini kernel: [1601214.177086]     if test -n "$(__git_find_on_cmdline "-u --update")"; then
+May  7 12:57:40 cassini kernel: [1601214.177086]         complete_opt="--modified";
+May  7 12:57:40 cassini kernel: [1601214.177086]     fi;
+May  7 12:57:40 cassini kernel: [1601214.177086]     __git_complete_index_file "$complete_opt"
+May  7 12:57:40 cassini kernel: [1601214.177086]                 exclude=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]             p)
+May  7 12:57:40 cassini kernel: [1601214.177086]                 vprev=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]             w)
+May  7 12:57:40 cassini kernel: [1601214.177086]                 vwords=$OPTARG
+May  7 12:57:40 cassini kernel: [1601214.177086]             ;;
+May  7 12:57:40 cassini kernel: [1601214.177086]         esac;
+May  7 12:57:40 cassini kernel: [1601214.177086]     done;
+May  7 13:07:49 cassini kernel: [1601823.599104] I was assigned major number 241. To talk to
+May  7 13:07:49 cassini kernel: [1601823.599106] the driver, create a dev file with
+May  7 13:07:49 cassini kernel: [1601823.599108] 'mknod /dev/chardev c 241 0'.
+May  7 13:07:49 cassini kernel: [1601823.599108] Try various minor numbers. Try to cat and echo to
+May  7 13:07:49 cassini kernel: [1601823.599109] the device file.
+May  7 13:07:49 cassini kernel: [1601823.599109] Remove the device file and module when done.
+May  7 13:07:58 cassini kernel: [1601832.651791] Got user data: Dies ist ein Test.
+May  7 13:07:58 cassini kernel: [1601832.651791] .
+cassini/home/peter/bo/2021ss/bs/20210430> tail chardev-1b.c
+ */
+static ssize_t
+device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
+{
+        char b[len + 1];
+        strncpy (b, buff, len);
+        b[len] = 0;
+        printk(KERN_INFO "Got user data: %s.\n", b);
+        return len;
+}
+cassini/home/peter/bo/2021ss/bs/20210430>
diff --git a/20210507/os-layers-1.jpg b/20210507/os-layers-1.jpg
new file mode 120000
index 0000000..6dc99e9
--- /dev/null
+++ b/20210507/os-layers-1.jpg
@@ -0,0 +1 @@
+../common/os-layers-1.jpg
\ No newline at end of file
diff --git a/20210507/os-layers-2.jpg b/20210507/os-layers-2.jpg
new file mode 120000
index 0000000..4da385e
--- /dev/null
+++ b/20210507/os-layers-2.jpg
@@ -0,0 +1 @@
+../common/os-layers-2.jpg
\ No newline at end of file
diff --git a/20210507/os-layers-3.jpg b/20210507/os-layers-3.jpg
new file mode 120000
index 0000000..eaf5b59
--- /dev/null
+++ b/20210507/os-layers-3.jpg
@@ -0,0 +1 @@
+../common/os-layers-3.jpg
\ No newline at end of file
diff --git a/20210507/os-layers-4.jpg b/20210507/os-layers-4.jpg
new file mode 120000
index 0000000..efcbbd1
--- /dev/null
+++ b/20210507/os-layers-4.jpg
@@ -0,0 +1 @@
+../common/os-layers-4.jpg
\ No newline at end of file
diff --git a/20210507/os-layers-5.jpg b/20210507/os-layers-5.jpg
new file mode 120000
index 0000000..91cabe9
--- /dev/null
+++ b/20210507/os-layers-5.jpg
@@ -0,0 +1 @@
+../common/os-layers-5.jpg
\ No newline at end of file
diff --git a/projekte.txt b/projekte.txt
index 21956a5..c76d4d7 100644
--- a/projekte.txt
+++ b/projekte.txt
@@ -28,3 +28,4 @@
    Bsp-Instanz aus Bochum (von dem dortigen Hackspace): https://virtuallab.das-labor.org/
    Doku dazu: https://howto.rc3.world/workadventure.en.html
  - Treiber für freies Smartphone
+ - Echtzeit-Kommunikation mit freiem Smartphone
-- 
GitLab