diff --git a/20220512/ad-20220512.txt b/20220512/ad-20220512.txt
new file mode 100644
index 0000000000000000000000000000000000000000..926dc0b57bb3fbed6d4e15db69988b48e1322c6d
--- /dev/null
+++ b/20220512/ad-20220512.txt
@@ -0,0 +1,126 @@
+Buch zu Steganographie:
+https://link.springer.com/content/pdf/10.1007/978-981-15-0751-9.pdf
+Steganographie-Software:
+https://github.com/DominicBreuker/stego-toolkit
+
+Diffie-Hellman-Schlüsselaustausch:
+https://de.wikipedia.org/wiki/Diffie-Hellman-Schl%C3%BCsselaustausch
+
+Prior art für Anwendung in der Steganographie:
+https://www.researchgate.net/publication/325206752_Diffie-Hellman_Key_Exchange_through_Steganographied_Images
+
+Diffie-Hellman-Schlüsselaustausch, 12.05.2022, 12:48:11
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Situation: Kommunikation ist nur öffentlich möglich.
+Ziel: Sich auf einen gemeinsamen geheimen Schlüssel einigen.
+Lösungsidee: asymmetrische Verschlüsselung, öffentliche Schlüssel
+
+Grundprinzip: Irgendetwas ist mathematisch schwieriger als etwas anderes.
+Hier: Der Logarithmus ist schwieriger zu berechnen als die Potenz.
+Beispiel: 7^5 = 16807 kann ich mit Papier und Bleistift berechnen.
+          Für den Logarithmus von 16807 zur Basis 7 hätte ich lieber
+          einen Computer.
+Im Computer: 100stellige Zahlen; wir rechnen modulo einer Primzahl p.
+
+Alice denkt sich eine Zahl a aus --> ihr geheimer Schlüssel.
+Bob denkt sich eine Zahl b aus --> sein geheimer Schlüssel.
+Beide einigen sich auf eine - öffentliche - gemeinsame Zahl g
+(und auf dieselbe Primzahl p).
+(Achtung: g ist nicht zufällig, sondern < p und idealerweise
+ein Erzeuger (Generator) der zyklischen Gruppe Z_p.)
+
+  Alice schickt g^a (mod p) an Bob.
+  Bob schickt g^b (mod p) an Alice.
+
+  Beide berechnen g^(a · b) = (g^a)^b = (g^b)^a --> gemeinsamer geheimer Schlüssel
+
+Praktische Umsetzung in der Steganographie:
+Alice schickt an Bob ein Katzenbild, das die unverschlüsselten Zahlen g, p und g^a (mod p) enthält.
+Dies sind einfach nur drei zufällig wirkende Zahlen.
+Ein Geheimdienst kann daraus nicht erkennen, daß ein Schlüsselaustausch stattfindet.
+
+Hauptproblem: Die Gesprächspartner müssen sich vorher auf die Software einigen.
+Dabei kann im Prinzip auch bereits der Schlüsselaustausch stattfinden.
+
+OT: https://www.proforhobo.com/
+    https://phdcomics.com/comics/archive.php?comicid=1446
+
+Lösungsideen für Hauptproblem:
+ - Ein Flüchtling nimmt eine Brieftaube mit.
+   Falls die Brieftaube abgefangen wird, ist weder Sender noch Empfänger bekannt.
+   OT: https://de.wikipedia.org/wiki/Internet_Protocol_over_Avian_Carriers
+       https://de.wikipedia.org/wiki/Brieftaube
+       https://en.wikipedia.org/wiki/War_pigeon
+ - Gemeinsame Erinnerungen
+ - Einfach versuchen, Kontakt aufzunehmen. Die Software merkt, ob eine Antwort kommt.
+
+Verbergen der Steganographie-Software:
+ - Easter-Egg in bekannter Software, z.B. Schachprogramm, Wetter-App, Terminkalender
+   wird vom Benutzer selbst konfiguriert, z.B. spezielle Schachzüge,
+     spezielle Stadt eingeben oder auf Wolken klicken, speziellen Namen eingeben
+ - Dies hilft gegen einen flüchtigen Blick, aber nicht gegen eine gezielte Suche
+   OT: https://embeddedsw.net/OpenPuff_Steganography_Home.html
+       https://xkcd.com/538/
+
+Man-in-the-middle-Angriff:
+
+  Alice schickt g^a (mod p) an Bob. Mallory fängt die Nachricht ab.
+  Mallory überlegt sich ein eigenes a --> a' und schickt g^a' an Bob.
+
+  Bob schickt g^b (mod p) an Alice. Mallory fängt die Nachricht ab.
+  Mallory überlegt sich ein eigenes b --> b' und schickt g^b' an Alice.
+
+  Alle berechnen g^(a · b) = (g^a)^b = (g^b)^a --> gemeinsamer geheimer Schlüssel
+
+  Bob schickt eine Nachricht - vermeintlich - an Alice; diese landet aber in
+  Wirklichkeit bei Mallory. Mallory entschlüsselt die Nachricht, verschlüsselt
+  sie neu für Alice und schickt sie danach erst weiter.
+
+  Die muß zum Zeitpunkt des (ersten) Schlüsselaustausches passieren.
+
+  Unwirksame Maßnahme gegen Man-in-the-middle-Angriff:
+  Im Inhalt der Nachricht persönliche Fragen stellen.
+  Damit kann man leider weder das Mitlesen noch das Manipulieren aufdecken.
+  --> unwirksam
+
+  Wirksame Maßnahme gegen Man-in-the-middle-Angriff:
+  Superöffentlicher Schlüsselaustausch:
+  Den öffentlichen Schlüssel (hier: g^a) so weit wie möglich verbreiten.
+  Beispiel: Der Heise-Verlag veröffentlicht in jeder gedruckten c't
+            seinen öffentlichen Schlüssel.
+
+Problem: Der Schlüsselaustausch wird abgefangen.
+         Wie kann man verbergen, daß überhaupt ein Schlüsselaustausch stattfindet?
+
+Idee: Wir schicken eine Zufallsfolge von Zahlen.
+      Wieviele Bits müssen wir versenden?
+      z.B. Schlüssel mit 2048 Bits, 3 Zahlen --> 3 Zahlen à 2048 Bit
+      1. Versuch:
+       - Sende 12 Bit (Zahl von 0 bis 4095): Länge der Zahl.
+       - Sende die Zahl selbst.
+       - Nächste Zahl.
+      Problem: Das fällt auf.
+      2. Versuch:
+       - Wie oben, aber wir senden zusätzlich "zu kurze" Zufallszahlen,
+         z.B. 13 Bit, 700 Bit, 2039 Bit, 3 Bit, 3048 Bit, 3770 Bit, 12 Bit
+         Der Algorithmus extrahiert diejenigen, die passende Größen haben.
+      Problem: Die 12-Bit-Zahlen könnten auffallen (viele 0-Bits).
+      3. Versuch:
+       - Die 12-Bit-Zahlen komprimieren, z.B.:
+         zuerst 4 Bit mit der Länge der Längen-Zahl (z.B. 3 für 8-Bit-Länge),
+         danach erst die eigentliche Länge.
+         Beispiel: Ich möchte eine 15-Bit-Zufallszahl versenden.
+         Die Zahl 15 selbst hat 4 Bit.
+         Kodierung:
+          0 1 0 0  1 1 1 1  x x x x x x x x x x x x x x x
+          `--v--'  `--v--'  `-------------v-------------'
+          4 (fest)   15              Zufallszahl
+      Problem: 3 etwa gleich lange Zahlen könnten auffallen,
+               insbesondere dann, wenn die ersten zwei Primzahlen sind
+               und die dritte nicht.
+
+      Problem: Wenn unser Zufall "zu gut" ist, fällt er auf,
+               da die LSBs in Bildern nicht 100% zufällig sind.
+      5. Versuch: ...
+
+https://en.wikipedia.org/wiki/Steganalysis
diff --git a/20220512/break-01.c b/20220512/break-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..418effae677a3abd1d5947cabd4825d240b4c41a
--- /dev/null
+++ b/20220512/break-01.c
@@ -0,0 +1,9 @@
+    for (int i = 0; i < m; i++)
+      {
+        if (x[i] == 42)
+          {
+            do_something_with (i);
+            break;
+          }
+      }
+    do_whatever ();
diff --git a/20220512/break-02.c b/20220512/break-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..f2cbdab47b2d90986bb1531c28289e86f0837351
--- /dev/null
+++ b/20220512/break-02.c
@@ -0,0 +1,9 @@
+    int i;
+    for (i = 0; i < m; i++)
+      {
+        if (x[i] == 42)
+          break;
+      }
+    if (x[i] == 42)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-03.c b/20220512/break-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c3cf584f26197c4d2570ad02484eea390c59df2
--- /dev/null
+++ b/20220512/break-03.c
@@ -0,0 +1,10 @@
+    int i = 0;
+    while (i < m)
+      {
+        if (x[i] == 42)
+          break;
+        i++;
+      }
+    if (x[i] == 42)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-04.c b/20220512/break-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..a43fbe1971f0839665ca8bd2c48ae168c529db1d
--- /dev/null
+++ b/20220512/break-04.c
@@ -0,0 +1,6 @@
+    int i = 0;
+    while (i < m && x[i] != 42)
+      i++;
+    if (i < m)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-05.c b/20220512/break-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e4d5293a1ad7064b75f93682bd0dfca4b938642
--- /dev/null
+++ b/20220512/break-05.c
@@ -0,0 +1,7 @@
+    int i = 0;
+    int found = 0;
+    while (i < m && !(found = x[i] == 42))
+      i++;
+    if (found)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-06.c b/20220512/break-06.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc74b9ef90b35bd12335c0f0e8b35e73e74d7388
--- /dev/null
+++ b/20220512/break-06.c
@@ -0,0 +1,10 @@
+    int i = 0;
+    int found = i < m && x[i] == 42;
+    while (i < m && !found)
+      {
+        i++;
+        found = x[i] == 42;
+      }
+    if (found)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-07.c b/20220512/break-07.c
new file mode 100644
index 0000000000000000000000000000000000000000..f7f9f17dcc1b96d2820cf1eac6c8874ace37d5cd
--- /dev/null
+++ b/20220512/break-07.c
@@ -0,0 +1,11 @@
+    int i = 0;
+    int found = 0;
+    while (i < m && !found)
+      {
+        found = x[i] == 42;
+        if (!found)
+          i++;
+      }
+    if (found)
+      do_something_with (i);
+    do_whatever ();
diff --git a/20220512/break-08.c b/20220512/break-08.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5067ebc62fe5d9064bdd9c6848480c29b5678b6
--- /dev/null
+++ b/20220512/break-08.c
@@ -0,0 +1,11 @@
+    int i = 0;
+    int found = -1;
+    while (i < m && found < 0)
+      {
+        if (x[i] == 42)
+          found = i;
+        i++;
+      }
+    if (found >= 0)
+      do_something_with (found);
+    do_whatever ();
diff --git a/20220512/break-09.c b/20220512/break-09.c
new file mode 100644
index 0000000000000000000000000000000000000000..51adac9f5ff4955229f1505b0ef21c5c7f252a92
--- /dev/null
+++ b/20220512/break-09.c
@@ -0,0 +1,11 @@
+    int i = 0;
+    foo *found = NULL;
+    while (i < m && !found)
+      {
+        if (x[i] == 42)
+          found = y[i];
+        i++;
+      }
+    if (found)
+      do_something_with (found);
+    do_whatever ();
diff --git a/20220512/good-code-01.c b/20220512/good-code-01.c
new file mode 100644
index 0000000000000000000000000000000000000000..b151f53228f61d51cb7a573a77ce4a3e17673cbb
--- /dev/null
+++ b/20220512/good-code-01.c
@@ -0,0 +1,18 @@
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (!*--p)
+				continue;
+			if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
+				c = (*p)->counter, next = i;
+		}
+		if (c) break;
+		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+			if (*p)
+				(*p)->counter = ((*p)->counter >> 1) +
+						(*p)->priority;
+	}
+	switch_to(next);
diff --git a/20220512/good-code-02.c b/20220512/good-code-02.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e717e7d62cde5e6c451c748cde798d6f9d1bff1
--- /dev/null
+++ b/20220512/good-code-02.c
@@ -0,0 +1,18 @@
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (*--p) {
+                                if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
+                                        c = (*p)->counter, next = i;
+                        }
+		}
+		if (c) break;
+		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+			if (*p)
+				(*p)->counter = ((*p)->counter >> 1) +
+						(*p)->priority;
+	}
+	switch_to(next);
diff --git a/20220512/good-code-03.c b/20220512/good-code-03.c
new file mode 100644
index 0000000000000000000000000000000000000000..da9d70b19b0bbf7acd679eb2dd6be888d1a35281
--- /dev/null
+++ b/20220512/good-code-03.c
@@ -0,0 +1,16 @@
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (*--p && (*p)->state == TASK_RUNNING && (*p)->counter > c)
+                                c = (*p)->counter, next = i;
+		}
+		if (c) break;
+		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+			if (*p)
+				(*p)->counter = ((*p)->counter >> 1) +
+						(*p)->priority;
+	}
+	switch_to(next);
diff --git a/20220512/good-code-04.c b/20220512/good-code-04.c
new file mode 100644
index 0000000000000000000000000000000000000000..e13f8251ae4c84bcb3e77a21dc0b0ed26579426c
--- /dev/null
+++ b/20220512/good-code-04.c
@@ -0,0 +1,17 @@
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (*--p
+                            && (*p)->state == TASK_RUNNING && (*p)->counter > c)
+                                c = (*p)->counter, next = i;
+		}
+		if (c) break;
+		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+			if (*p)
+				(*p)->counter = ((*p)->counter >> 1) +
+						(*p)->priority;
+	}
+	switch_to(next);
diff --git a/20220512/good-code-05.c b/20220512/good-code-05.c
new file mode 100644
index 0000000000000000000000000000000000000000..c509d503495125a9d8876ad7edb99a5180020179
--- /dev/null
+++ b/20220512/good-code-05.c
@@ -0,0 +1,20 @@
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (*--p
+                            && (*p)->state == TASK_RUNNING && (*p)->counter > c)
+                                c = (*p)->counter, next = i;
+		}
+		if (c)
+                        break;
+                else {
+                        for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+                                if (*p)
+                                        (*p)->counter = ((*p)->counter >> 1) +
+                                                        (*p)->priority;
+                }
+	}
+	switch_to(next);
diff --git a/20220512/mathe-20220512-01-gruppen.png b/20220512/mathe-20220512-01-gruppen.png
new file mode 100644
index 0000000000000000000000000000000000000000..17f4eb73ac374c70800c495bf829aca86a2564ae
Binary files /dev/null and b/20220512/mathe-20220512-01-gruppen.png differ
diff --git a/20220512/mathe-20220512-02-z5.png b/20220512/mathe-20220512-02-z5.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecd56510334466f6f32e5d73d6e6b268917d158a
Binary files /dev/null and b/20220512/mathe-20220512-02-z5.png differ
diff --git a/20220512/mathe-20220512-03-diskreter-logarithmus.png b/20220512/mathe-20220512-03-diskreter-logarithmus.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f1466e8a78055a9703bd6588db9f2b849d8d30d
Binary files /dev/null and b/20220512/mathe-20220512-03-diskreter-logarithmus.png differ
diff --git a/20220512/mathe-20220512-04-rsa.png b/20220512/mathe-20220512-04-rsa.png
new file mode 100644
index 0000000000000000000000000000000000000000..f93455c175267402b531667d6f5eb3c6b833561e
Binary files /dev/null and b/20220512/mathe-20220512-04-rsa.png differ
diff --git a/20220512/mathe-20220512-05-rsa-knacken.png b/20220512/mathe-20220512-05-rsa-knacken.png
new file mode 100644
index 0000000000000000000000000000000000000000..997ff6a2a77899a56346bfd2d762a551ec86985f
Binary files /dev/null and b/20220512/mathe-20220512-05-rsa-knacken.png differ
diff --git a/20220512/mathe-20220512.xcf.gz b/20220512/mathe-20220512.xcf.gz
new file mode 100644
index 0000000000000000000000000000000000000000..ef0a6c46737e58295f835eb33b817698590043ea
Binary files /dev/null and b/20220512/mathe-20220512.xcf.gz differ
diff --git a/20220512/sched.c b/20220512/sched.c
new file mode 100644
index 0000000000000000000000000000000000000000..03399faa2a77570c0ad25fafa66cefb89b3659c0
--- /dev/null
+++ b/20220512/sched.c
@@ -0,0 +1,254 @@
+/*
+ * 'sched.c' is the main kernel file. It contains scheduling primitives
+ * (sleep_on, wakeup, schedule etc) as well as a number of simple system
+ * call functions (type getpid(), which just extracts a field from
+ * current-task
+ */
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <signal.h>
+#include <linux/sys.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+
+#define LATCH (1193180/HZ)
+
+extern void mem_use(void);
+
+extern int timer_interrupt(void);
+extern int system_call(void);
+
+union task_union {
+	struct task_struct task;
+	char stack[PAGE_SIZE];
+};
+
+static union task_union init_task = {INIT_TASK,};
+
+long volatile jiffies=0;
+long startup_time=0;
+struct task_struct *current = &(init_task.task), *last_task_used_math = NULL;
+
+struct task_struct * task[NR_TASKS] = {&(init_task.task), };
+
+long user_stack [ PAGE_SIZE>>2 ] ;
+
+struct {
+	long * a;
+	short b;
+	} stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };
+/*
+ *  'math_state_restore()' saves the current math information in the
+ * old math state array, and gets the new ones from the current task
+ */
+void math_state_restore()
+{
+	if (last_task_used_math)
+		__asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));
+	if (current->used_math)
+		__asm__("frstor %0"::"m" (current->tss.i387));
+	else {
+		__asm__("fninit"::);
+		current->used_math=1;
+	}
+	last_task_used_math=current;
+}
+
+/*
+ *  'schedule()' is the scheduler function. This is GOOD CODE! There
+ * probably won't be any reason to change this, as it should work well
+ * in all circumstances (ie gives IO-bound processes good response etc).
+ * The one thing you might take a look at is the signal-handler code here.
+ *
+ *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
+ * tasks can run. It can not be killed, and it cannot sleep. The 'state'
+ * information in task[0] is never used.
+ */
+void schedule(void)
+{
+	int i,next,c;
+	struct task_struct ** p;
+
+/* check alarm, wake up any interruptible tasks that have got a signal */
+
+	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+		if (*p) {
+			if ((*p)->alarm && (*p)->alarm < jiffies) {
+					(*p)->signal |= (1<<(SIGALRM-1));
+					(*p)->alarm = 0;
+				}
+			if ((*p)->signal && (*p)->state==TASK_INTERRUPTIBLE)
+				(*p)->state=TASK_RUNNING;
+		}
+
+/* this is the scheduler proper: */
+
+	while (1) {
+		c = -1;
+		next = 0;
+		i = NR_TASKS;
+		p = &task[NR_TASKS];
+		while (--i) {
+			if (!*--p)
+				continue;
+			if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
+				c = (*p)->counter, next = i;
+		}
+		if (c) break;
+		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+			if (*p)
+				(*p)->counter = ((*p)->counter >> 1) +
+						(*p)->priority;
+	}
+	switch_to(next);
+}
+
+int sys_pause(void)
+{
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	return 0;
+}
+
+void sleep_on(struct task_struct **p)
+{
+	struct task_struct *tmp;
+
+	if (!p)
+		return;
+	if (current == &(init_task.task))
+		panic("task[0] trying to sleep");
+	tmp = *p;
+	*p = current;
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule();
+	if (tmp)
+		tmp->state=0;
+}
+
+void interruptible_sleep_on(struct task_struct **p)
+{
+	struct task_struct *tmp;
+
+	if (!p)
+		return;
+	if (current == &(init_task.task))
+		panic("task[0] trying to sleep");
+	tmp=*p;
+	*p=current;
+repeat:	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	if (*p && *p != current) {
+		(**p).state=0;
+		goto repeat;
+	}
+	*p=NULL;
+	if (tmp)
+		tmp->state=0;
+}
+
+void wake_up(struct task_struct **p)
+{
+	if (p && *p) {
+		(**p).state=0;
+		*p=NULL;
+	}
+}
+
+void do_timer(long cpl)
+{
+	if (cpl)
+		current->utime++;
+	else
+		current->stime++;
+	if ((--current->counter)>0) return;
+	current->counter=0;
+	if (!cpl) return;
+	schedule();
+}
+
+int sys_alarm(long seconds)
+{
+	current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
+	return seconds;
+}
+
+int sys_getpid(void)
+{
+	return current->pid;
+}
+
+int sys_getppid(void)
+{
+	return current->father;
+}
+
+int sys_getuid(void)
+{
+	return current->uid;
+}
+
+int sys_geteuid(void)
+{
+	return current->euid;
+}
+
+int sys_getgid(void)
+{
+	return current->gid;
+}
+
+int sys_getegid(void)
+{
+	return current->egid;
+}
+
+int sys_nice(long increment)
+{
+	if (current->priority-increment>0)
+		current->priority -= increment;
+	return 0;
+}
+
+int sys_signal(long signal,long addr,long restorer)
+{
+	long i;
+
+	switch (signal) {
+		case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:
+		case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:
+		case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:
+		case SIGCHLD:
+			i=(long) current->sig_fn[signal-1];
+			current->sig_fn[signal-1] = (fn_ptr) addr;
+			current->sig_restorer = (fn_ptr) restorer;
+			return i;
+		default: return -1;
+	}
+}
+
+void sched_init(void)
+{
+	int i;
+	struct desc_struct * p;
+
+	set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));
+	set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));
+	p = gdt+2+FIRST_TSS_ENTRY;
+	for(i=1;i<NR_TASKS;i++) {
+		task[i] = NULL;
+		p->a=p->b=0;
+		p++;
+		p->a=p->b=0;
+		p++;
+	}
+	ltr(0);
+	lldt(0);
+	outb_p(0x36,0x43);		/* binary, mode 3, LSB/MSB, ch 0 */
+	outb_p(LATCH & 0xff , 0x40);	/* LSB */
+	outb(LATCH >> 8 , 0x40);	/* MSB */
+	set_intr_gate(0x20,&timer_interrupt);
+	outb(inb_p(0x21)&~0x01,0x21);
+	set_system_gate(0x80,&system_call);
+}