diff --git a/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.md b/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.md
index 92adae5cdcccbc715799c49021460fb47549fa77..057bd813ef427499a0de919ebccc67729e240481 100644
--- a/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.md
+++ b/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.md
@@ -73,7 +73,7 @@ Chaque tâche est un programme en cours d'exécution. Chaque programme est compi
 
 Au niveau du code fourni, la gestion des tâches est à implémenter dans `task/task.c`. Une petite partie du code vous est fournie, mais vous devez implémenter l'essentiel des fonctionalités. Les fonctions à implémenter sont décrites ci-dessous.
 
-**`static task_t *task_create(char *name, uint_t addr_space_size)`**
+**`static task_t *task_create(uint_t addr_space_size)`**
 \vspace{-2mm}
 
 Cette fonction créée une nouvelle tâche et la retourne (ou NULL si il n'y a plus de tâche disponible). Comme le nombre de tâches maximum est limité, la fonction doit vérifier qu'il y a encore au moins une tâche de disponible (dans le tableau de tâches). Ensuite, les structures associées à la tâche doivent être initialisées et l'espace d'adressage virtuel de la tâche doit être créé, en n'oubliant pas d'allouer dynamiquement, à l'aide de frames, l'espace mémoire nécessaire pour le code, les données et la pile (taille pile fixée à `TASK_STACK_SIZE_MB` en MB). Cet espace mémoire sera typiquement alloué dynamiquement avec la fonction `paging_alloc` du module `paging.h`. Cette fonction en plus d'allouer les frames pour l'espace mémoire nécessaire, réalise également le mapping à l'adresse virtuelle spécifiée en argument et modifie le répertoire de pages passé en argument en conséquence. A noter que vous devrez libérer les frames allouées lorsque la tâche sera terminée dans la fonction `task_free`.
diff --git a/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.pdf b/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.pdf
index f2e01f87dd95c905549928d5768abb3b348217d6..95417c71df948698bbbed7269a91e1b8a4f38961 100644
Binary files a/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.pdf and b/labs/lab4-tasks_syscalls/lab4-tasks_syscalls.pdf differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/Makefile b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8954b0b1e834124ab03a7313112eef3feea1ea19
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/Makefile
@@ -0,0 +1,20 @@
+include ../common.mk
+ 
+SRC=$(shell find . -iname "*.c")
+OBJ=$(SRC:.c=.o)
+DEP=$(SRC:.c=.d)
+
+all: $(OBJ)
+
+%.o: %.c
+	$(CC) $(CC_FLAGS) $< -o $@
+
+%.o: %.s
+	nasm -f elf32 $< -o $@
+
+clean:
+	/bin/rm -f $(OBJ) $(DEP)
+
+.PHONY: clean
+
+-include $(DEP)
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/colors.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/colors.h
new file mode 100644
index 0000000000000000000000000000000000000000..d98af9affbd28de96ccc81902252f6ae2a75f527
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/colors.h
@@ -0,0 +1,51 @@
+#ifndef _COLORS_H_
+#define _COLORS_H_
+
+// Convert a 8-bit color component to 5 bits
+// by removing the 3 least significant bits
+#define COL8TO5(x)  (x >> 3)
+
+// Convert a 8-bit color component to 6 bits
+// by removing the 2 least significant bits
+#define COL8TO6(x)  (x >> 2)
+
+// Convert a 24-bit color to a 16-bit one (RGB565)
+#define RGB(r,g,b) ((COL8TO5(r))<<11|(COL8TO6(g))<<5|(COL8TO5(b)))
+
+// "Broadcast" a 16-bit color into a 32-bit word
+#define COLTO32(x)  ((x&0xFFFF) << 16|(x&0xFFFF))
+
+#define BLACK        RGB(0,0,0)
+#define WHITE        RGB(255,255,255)
+#define RED          RGB(255,0,0)
+#define BLUE         RGB(0,0,255)
+#define GREEN        RGB(0,255,0)
+#define YELLOW       RGB(255,255,0)
+#define CYAN         RGB(0,255,255)
+#define GREY         RGB(150,150,150)
+#define LIGHT_GREY   RGB(220,220,220)
+#define LIGHT_BLUE   RGB(150,150,220)
+#define LIGHT_GREEN  RGB(150,220,150)
+#define LIGHT_RED    RGB(255,200,200)
+#define LIGHT_YELLOW RGB(220,220,150)
+#define DARK_GREY    RGB(80,80,80)
+#define DARK_BLUE    RGB(0,0,100)
+#define DARK_GREEN   RGB(0,100,0)
+#define DARK_RED     RGB(100,0,0)
+#define DARK_YELLOW  RGB(100,100,0)
+
+/*
+typedef enum {
+    MAGENTA = 5,
+    BROWN = 6,
+    LIGHT_CYAN = 11,
+    LIGHT_MAGENTA = 13,
+} term_colortype_t;
+*/
+
+typedef struct {
+    uint16_t fg;  // foreground color
+    uint16_t bg;  // background color
+} term_colors_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/keycodes.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/keycodes.h
new file mode 100644
index 0000000000000000000000000000000000000000..9522fd658b9dc68bcd9dad69a8c800d76a6e5939
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/keycodes.h
@@ -0,0 +1,47 @@
+#ifndef _KEYCODES_COMMON_H_
+#define _KEYCODES_COMMON_H_
+
+#define KEY_ESC         50000
+#define KEY_HOME        50005
+#define KEY_LEFT        50006
+#define KEY_RIGHT       50007
+#define KEY_UP          50008
+#define KEY_DOWN        50009
+#define KEY_END         50010
+#define KEY_PGUP        50011
+#define KEY_PGDOWN      50012
+#define KEY_INSERT      50013
+#define KEY_DEL         50014
+#define KEY_F1          50015
+#define KEY_F2          50016
+#define KEY_F3          50017
+#define KEY_F4          50018
+#define KEY_F5          50019
+#define KEY_F6          50020
+#define KEY_F7          50021
+#define KEY_F8          50022
+#define KEY_F9          50023
+#define KEY_F10         50024
+#define KEY_F11         50025
+#define KEY_F12         50026
+
+// Hexadecimal values of IBM PC CP437's characters
+// Full table here: http://www.ascii-codes.com/
+#define KEY_A_CIRCUMFLEX   0x83
+#define KEY_A_DIAERESIS    0x84
+#define KEY_A_GRAVE        0x85
+#define KEY_C_CEDILLA      0x87
+#define KEY_E_ACUTE        0x82
+#define KEY_E_CIRCUMFLEX   0x88
+#define KEY_E_DIAERESIS    0x89
+#define KEY_E_GRAVE        0x8A
+#define KEY_I_DIAERESIS    0x8B
+#define KEY_I_CIRCUMFLEX   0x8C
+#define KEY_O_DIAERESIS    0x94
+#define KEY_U_CIRCUMFLEX   0x96
+#define KEY_U_DIAERESIS    0x81
+#define KEY_PARAGRAPH      0x15
+#define KEY_POUND          0x9C
+#define KEY_DEGREE         0xF8
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.c
new file mode 100644
index 0000000000000000000000000000000000000000..b97b055ed1d7eb445d97c3f271b710d1c1093190
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.c
@@ -0,0 +1,28 @@
+#include <stdint.h>
+#include "mem.h"
+
+void memset(void *dst, uint8_t value, uint_t count) {
+    uint8_t *d = dst;
+    while (count--)
+        *d++ = value;
+}
+
+void memsetdw(void *dst, uint32_t value, uint_t count) {
+    uint32_t *d = dst;
+    while (count--)
+        *d++ = value;
+}
+
+void memcpy(void *dst, void *src, uint_t count) {
+    uint8_t *d = dst;
+    uint8_t *s = src;
+    while (count--)
+        *d++ = *s++;
+}
+
+void memcpydw(void *dst, void *src, uint_t count) {
+    uint32_t *d = dst;
+    uint32_t *s = src;
+    while (count--)
+        *d++ = *s++;
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.h
new file mode 100644
index 0000000000000000000000000000000000000000..31ba99a9736f2ec49f0748ec5ab0364b6080c4b9
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/mem.h
@@ -0,0 +1,20 @@
+#ifndef _MEM_COMMON_H_
+#define _MEM_COMMON_H_
+
+#include "types.h"
+
+// Fills count bytes of the memory area pointed to by dst with the byte value.
+extern void memset(void *dst, uint8_t value, uint_t count);
+
+// Fills count dwords of the memory area pointed to by dst with the dword value.
+// NOTE: dword = double word = 32-bit
+extern void memsetdw(void *dst, uint32_t value, uint_t count);
+
+// Copy count bytes from src to dst.
+extern void memcpy(void *dst, void *src, uint_t count);
+
+// Copy count dwords from src to dst.
+// NOTE: dword = double word = 32-bit
+extern void memcpydw(void *dst, void *src, uint_t count);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0adcd7732efb699b1ac56c9f14d1d49486dcbc2
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.c
@@ -0,0 +1,108 @@
+#include <stdbool.h>
+#include "stdio.h"
+#include "types.h"
+
+// Print into buf in reverse, the value val in the given base.
+// The argument sign indicates whether the value is signed (true) or not (false).
+// The number of characters written is returned into length.
+static void printint_rev(char *buf, int *length, int val, int base, bool sign) {
+    static char digits[] = "0123456789ABCDEF";
+    int count = 0;
+    uint_t x;
+
+    if (sign && (sign = val < 0))
+        x = -val;
+    else
+        x = val;
+
+    do {
+        buf[count++] = digits[x % base];
+    } while ((x /= base) != 0);
+
+    if (sign)
+        buf[count++] = '-';
+
+    buf[count] = 0;
+    *length = count;
+}
+
+int snprintf(char *dest, int size, char *fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int count = vsnprintf(dest, size, fmt, args);
+    va_end(args);
+    return count;
+}
+
+// Helper macro used in vsnprintf
+#define putc(c)     \
+    if (size > 0) { \
+        *dest = c;  \
+        dest++;     \
+        size--;     \
+        count++;    \
+    }
+
+int vsnprintf(char *dest, int size, const char *fmt, va_list args) {
+    char buf[size+1];
+    int len;
+    int count = 0;
+    while (*fmt) {
+        if (*fmt == '%') {  // found an argument
+            fmt++;
+            if (*fmt == 0)  // missing value after %
+                break;
+            switch (*fmt) {
+                case 'c':
+                    {
+                        int c = va_arg(args, int);
+                        putc(c)
+                    }
+                    break;
+                case 's':
+                    {
+                        char *s = va_arg(args, char *);
+                        while (*s) {
+                            putc(*s)
+                            s++;
+                        }
+                    }
+                    break;
+                case 'd':
+                    {
+                        int n = va_arg(args, int);
+                        printint_rev(buf, &len, n, 10, true);
+                        while (len) putc(buf[--len]);
+                    }
+                    break;
+                case 'u':
+                    {
+                        uint_t n = va_arg(args, uint_t);
+                        printint_rev(buf, &len, n, 10, false);
+                        while (len) putc(buf[--len]);
+                    }
+                    break;
+                case 'x':
+                    {
+                        int n = va_arg(args, int);
+                        printint_rev(buf, &len, n, 16, false);
+                        while (len) putc(buf[--len]);
+                    }
+                    break;
+                case '%':
+                    putc('%')
+                    break;
+                default:
+                    // unkown argument, ignore it!
+                    break;
+            }
+        }
+        else {
+            putc(*fmt)
+        }
+        fmt++;
+    }
+
+    *dest = 0;
+    return count;
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.h
new file mode 100644
index 0000000000000000000000000000000000000000..63c1638f0cc0dba8ac05676b9cb5bb1a87af71a4
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/stdio.h
@@ -0,0 +1,18 @@
+#ifndef _STDIO_COMMON_H_
+#define _STDIO_COMMON_H_
+
+#include <stdarg.h>
+
+// Writes at most size characters (including terminal 0) of the formatted string fmt
+// into buffer dest.
+// args are the variable length arguments as a va_list.
+// Returns the number of characters written.
+extern int vsnprintf(char *dest, int size, const char *fmt, va_list args);
+
+// Writes at most size characters (including terminal 0) of the formatted string fmt
+// into buffer dest.
+// Any arbitrary number of arguments can be passed after fmt.
+// Returns the number of characters written.
+extern int snprintf(char *dest, int size, char *fmt, ...);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.c
new file mode 100644
index 0000000000000000000000000000000000000000..3053dee6b62deeb83f33f7cd389590df609dd331
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.c
@@ -0,0 +1,62 @@
+#include <stdint.h>
+#include "string.h"
+
+uint_t strlen(const char *s) {
+    int n;
+    for (n = 0; s[n]; n++);
+    return n;
+}
+
+char *strncpy(char *dest, const char *src, uint_t count) {
+    char *p = dest;
+
+    while (count && *src) {
+        *p = *src;
+        src++;
+        p++;
+        count--;
+    }
+    *p = 0;
+    return dest;
+}
+
+// Original FreeBSD implementation
+// Source: https://github.com/freebsd/freebsd/blob/master/lib/libc/string/strcmp.c
+int strcmp(const char *s1, const char *s2) {
+    while (*s1 == *s2++)
+        if (*s1++ == '\0')
+            return (0);
+    return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
+}
+
+// Original FreeBSD implementation
+// Source: https://github.com/freebsd/freebsd/blob/master/lib/libc/string/strncmp.c
+int strncmp(const char *s1, const char *s2, uint_t n) {
+    if (n == 0)
+        return (0);
+    do {
+        if (*s1 != *s2++)
+            return (*(const unsigned char *)s1 -
+                *(const unsigned char *)(s2 - 1));
+        if (*s1++ == '\0')
+            break;
+    } while (--n != 0);
+    return (0);
+}
+
+uint_t atoi(const char *s) {
+    uint_t n = 0;
+    while ('0' <= *s && *s <= '9')
+        n = n*10 + *s++ - '0';
+    return n;
+}
+
+char *tolower(char *s) {
+    for (int n = 0; s[n]; n++) {
+        if (s[n] >= 'A' && s[n] <= 'Z') {
+            // upper case letters differ by 32 from lower case ones (man ascii)
+            s[n] = s[n] + 32;
+        }
+    }
+    return s;
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e2620019f9027d6ed0991dfe7c1cb3b50277b90
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/string.h
@@ -0,0 +1,30 @@
+#ifndef _STRING_COMMON_H_
+#define _STRING_COMMON_H_
+
+#include "types.h"
+
+// Returns the length of string s.
+extern uint_t strlen(const char *s);
+
+// Copy string src into dest, copying at most count characters.
+// Returns the string dest.
+extern char *strncpy(char *dest, const char *src, uint_t count);
+
+// Compare alphanumerically string s1 with s2.
+// Returns:
+// 0 if identical
+// a value > 0 if s1 > s2
+// a value < 0 if s1 < s2
+extern int strcmp(const char *s1, const char *s2);
+
+// Identical to strcmp, except that it compares up to n characters.
+extern int strncmp(const char *s1, const char *s2, uint_t n);
+
+// Returns the integer representation of string s.
+// IMPORTANT: does not perform any validation on the string!
+extern uint_t atoi(const char *s);
+
+// Convert, in-place, string s to its lower case representation.
+extern char *tolower(char *s);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/syscall_nb.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/syscall_nb.h
new file mode 100644
index 0000000000000000000000000000000000000000..07727324760f625fc88dd2e4c8ff1ec67d41979e
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/syscall_nb.h
@@ -0,0 +1,9 @@
+#ifndef _SYSCALL_NB_COMMON_H_
+#define _SYSCALL_NB_COMMON_H_
+
+typedef enum {
+    SYSCALL_xxx = 1,
+    __SYSCALL_END__
+} syscall_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/types.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/types.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed3224bfe9754ae1c9ee88c8d8fc37e7472a1d2d
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/types.h
@@ -0,0 +1,19 @@
+#ifndef _TYPES_COMMON_H_
+#define _TYPES_COMMON_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef unsigned char uchar_t;
+typedef unsigned short ushort_t;
+typedef unsigned int uint_t;
+typedef unsigned long long ulong_t;
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define UNUSED(x) ((void)(x))
+
+#endif
+
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/vbe_fb.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/vbe_fb.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a22f3f90a74c40579dbdb6b9cb4893248a5a0d3
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/common/vbe_fb.h
@@ -0,0 +1,16 @@
+#ifndef _VBE_FB_COMMON_H_
+#define _VBE_FB_COMMON_H_
+
+#include "common/types.h"
+
+typedef struct {
+    uint16_t *addr;
+    uint32_t size;  // in bytes
+    uint32_t pitch_in_bytes;
+    uint32_t pitch_in_pix;
+    uint32_t width;
+    uint32_t height;
+    uint8_t bpp;
+} vbe_fb_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/Makefile b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e60aa73b3dd8a86a088ec15f0646abd53e527131
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/Makefile
@@ -0,0 +1,33 @@
+include ../common.mk
+
+override LD_FLAGS+=-Tkernel.ld $(BAREMETAL_FLAGS) -lgcc
+
+KERNEL_C_SRC=$(shell find . -iname "*.c")
+KERNEL_ASM_SRC=$(shell find . -iname "*.s")
+KERNEL_C_OBJ=$(KERNEL_C_SRC:.c=.o)
+KERNEL_C_DEP=$(KERNEL_C_SRC:.c=.d)
+KERNEL_ASM_OBJ=$(KERNEL_ASM_SRC:.s=.o)
+
+KERNEL_OUT=kernel.elf
+
+DEP=$(KERNEL_C_OBJ:%.o=%.d)
+
+all: $(KERNEL_OUT)
+
+%.o: %.c
+	$(CC) $(CC_FLAGS) $(CC_DEFINES) -I. -I.. $< -o $@
+
+%.o: %.s
+	nasm -f elf32 $< -o $@
+
+$(KERNEL_OUT): $(KERNEL_C_OBJ) $(KERNEL_ASM_OBJ) $(COMMON_OBJ)
+	$(LD) $^ -o $@ $(LD_FLAGS)
+
+clean:
+	$(MAKE) -C $(COMMON_DIR) clean
+	/bin/rm -f $(KERNEL_C_OBJ) $(KERNEL_ASM_OBJ) $(KERNEL_C_DEP)
+	/bin/rm -f $(KERNEL_OUT)
+
+.PHONY: clean
+
+-include $(DEP)
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/bootstrap_asm.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/bootstrap_asm.o
new file mode 100644
index 0000000000000000000000000000000000000000..dad90e8601c1b091b52178c616fbe074841a6375
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/bootstrap_asm.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.h
new file mode 100644
index 0000000000000000000000000000000000000000..2353e5ef987a71dce1f094accadb0cdfaca6711c
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.h
@@ -0,0 +1,44 @@
+#ifndef _MODULE_H_
+#define _MODULE_H_
+
+#include "common/types.h"
+#include "boot/multiboot.h"
+
+// Returns the number of detected modules.
+extern uint_t modules_count();
+
+// Returns modules' last address in use, so we can safely assume addresses above this are free.
+// Returns the kernel's last address in use if no modules are detected.
+extern uint32_t modules_last_address();
+
+// Returns a module's address.
+// Note: first module is at index 0.
+extern void *module_first_address(uint_t index);
+
+// Returns a module's last address in use (inclusive).
+// Note: first module is at index 0.
+extern void *module_last_address(uint_t index);
+
+// Returns a module' size in bytes.
+// Note: first module is at index 0.
+extern uint_t module_size(uint_t index);
+
+// Returns a module's command line.
+// Returns NULL if the module's command line is empty.
+// Note: first module is at index 0.
+extern char* module_cmdline(uint_t index);
+
+// Displays modules' information:
+// - number of detected modules
+// - for each module: address, size (in bytes), command line
+extern void modules_display_info();
+
+// Returns the address of the first module whose argument matches name.
+// Returns NULL if no such module is found.
+extern void *module_addr_by_name(char *name);
+
+// Returns the size in bytes of the first module whose argument matches name.
+// Returns -1 if no such module is found.
+extern int module_size_by_name(char *name);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.o
new file mode 100644
index 0000000000000000000000000000000000000000..cde3fa26da1150259540265f06d1ea66ad5f0168
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module_by_name.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module_by_name.o
new file mode 100644
index 0000000000000000000000000000000000000000..763615d98c1de16bfb7ec498c3613e2b1d96f9fd
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/module_by_name.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.h
new file mode 100644
index 0000000000000000000000000000000000000000..cfd67202cbccf3336c79607e81d0d45b09c0b204
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.h
@@ -0,0 +1,16 @@
+#ifndef _MULTIBOOT_H_
+#define _MULTIBOOT_H_
+
+#include "common/types.h"
+#include "multiboot_structs.h"
+
+// Stores the multiboot info structure.
+extern void multiboot_set_info(multiboot_info_t *_mbi);
+
+// Retrieves the multiboot info structure.
+extern multiboot_info_t* multiboot_get_info();
+
+// Retrieves the amount of available RAM in KB.
+extern uint_t multiboot_get_RAM_in_KB();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.o
new file mode 100644
index 0000000000000000000000000000000000000000..b28722459597754798668a58ec1a98f406b0d36f
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot_structs.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot_structs.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6282025f1259e62a4b5d770adbb8b18a69b76a8
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/boot/multiboot_structs.h
@@ -0,0 +1,118 @@
+#ifndef _MULTIBOOT_STRUCTS_H_
+#define _MULTIBOOT_STRUCTS_H_
+
+// Source: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#multiboot_002eh
+
+typedef unsigned char           multiboot_uint8_t;
+typedef unsigned short          multiboot_uint16_t;
+typedef unsigned int            multiboot_uint32_t;
+typedef unsigned long long      multiboot_uint64_t;
+
+/* The symbol table for a.out. */
+struct multiboot_aout_symbol_table {
+    multiboot_uint32_t tabsize;
+    multiboot_uint32_t strsize;
+    multiboot_uint32_t addr;
+    multiboot_uint32_t reserved;
+};
+typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
+
+/* The section header table for ELF. */
+struct multiboot_elf_section_header_table {
+    multiboot_uint32_t num;
+    multiboot_uint32_t size;
+    multiboot_uint32_t addr;
+    multiboot_uint32_t shndx;
+};
+typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
+
+struct multiboot_info {
+    /* Multiboot info version number */
+    multiboot_uint32_t flags;
+
+    /* Available memory from BIOS (in KB) */
+    multiboot_uint32_t mem_lower;
+    multiboot_uint32_t mem_upper;
+
+    /* "root" partition */
+    multiboot_uint32_t boot_device;
+
+    /* Kernel command line */
+    multiboot_uint32_t cmdline;
+
+    /* Boot-Module list */
+    multiboot_uint32_t mods_count;
+    multiboot_uint32_t mods_addr;
+
+    union {
+        multiboot_aout_symbol_table_t aout_sym;
+        multiboot_elf_section_header_table_t elf_sec;
+    } u;
+
+    /* Memory Mapping buffer */
+    multiboot_uint32_t mmap_length;
+    multiboot_uint32_t mmap_addr;
+
+    /* Drive Info buffer */
+    multiboot_uint32_t drives_length;
+    multiboot_uint32_t drives_addr;
+
+    /* ROM configuration table */
+    multiboot_uint32_t config_table;
+
+    /* Boot Loader Name */
+    multiboot_uint32_t boot_loader_name;
+
+    /* APM table */
+    multiboot_uint32_t apm_table;
+
+    /* Video */
+    multiboot_uint32_t vbe_control_info;
+    multiboot_uint32_t vbe_mode_info;
+    multiboot_uint16_t vbe_mode;
+    multiboot_uint16_t vbe_interface_seg;
+    multiboot_uint16_t vbe_interface_off;
+    multiboot_uint16_t vbe_interface_len;
+
+    multiboot_uint64_t framebuffer_addr;
+    // Pitch is the distance, in bytes, between two memory addresses that represent
+    // the beginning of one bitmap line and the beginning of the next bitmap line.
+    multiboot_uint32_t framebuffer_pitch;
+    multiboot_uint32_t framebuffer_width;
+    multiboot_uint32_t framebuffer_height;
+    multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED   0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB       1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT  2
+    multiboot_uint8_t framebuffer_type;
+    union {
+        struct {
+            multiboot_uint32_t framebuffer_palette_addr;
+            multiboot_uint16_t framebuffer_palette_num_colors;
+        };
+        struct {
+            multiboot_uint8_t framebuffer_red_field_position;
+            multiboot_uint8_t framebuffer_red_mask_size;
+            multiboot_uint8_t framebuffer_green_field_position;
+            multiboot_uint8_t framebuffer_green_mask_size;
+            multiboot_uint8_t framebuffer_blue_field_position;
+            multiboot_uint8_t framebuffer_blue_mask_size;
+        };
+    };
+};
+typedef struct multiboot_info multiboot_info_t;
+
+struct multiboot_mod_list {
+    /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+    multiboot_uint32_t mod_start;
+    multiboot_uint32_t mod_end;
+
+    /* Module command line */
+    multiboot_uint32_t cmdline;
+
+    /* padding to take it to 16 bytes (must be zero) */
+    multiboot_uint32_t pad;
+};
+typedef struct multiboot_mod_list multiboot_module_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/const.inc b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/const.inc
new file mode 100644
index 0000000000000000000000000000000000000000..444e9fdf341a8766d7c3c357f8636581a105e372
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/const.inc
@@ -0,0 +1,3 @@
+; Must match the values of the same constants in gdt.h!
+GDT_KERNEL_CODE_SELECTOR  equ  0x08
+GDT_KERNEL_DATA_SELECTOR  equ  0x10
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/descriptors.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/descriptors.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b2d54c51cf606d9e76e9b91a16f59688bb98e16
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/descriptors.h
@@ -0,0 +1,35 @@
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+// Privilege levels
+#define DPL_USER    0x3
+#define DPL_KERNEL  0x0
+
+// Selectors
+//#define LDT_SELECTOR    0x4
+
+// Descriptor types for code and data segments
+#define TYPE_DATA_RO    1   // read-only
+#define TYPE_DATA_RW    3   // read-write
+
+// Stack segments are data segments which must be read/write segments. Loading the
+// SS register with a segment selector for a nonwritable data segment generates a
+// general-protection exception (#GP). If the size of a stack segment needs to be
+// changed dynamically, the stack segment can be an expand-down data segment
+// (expansion-direction flag set). Here, dynamically changing the segment limit causes
+// stack space to be added to the bottom of the stack. If the size of a stack segment is
+// intended to remain static, the stack segment may be either an expand-up or expand-down type.
+#define TYPE_DATA_RW_EXPAND_DOWN  6  // stack segment type
+
+#define TYPE_CODE_EXECONLY     9
+#define TYPE_CODE_EXECREAD    11
+
+// Descriptor types for system segments and gates
+#define TYPE_LDT               2
+#define TYPE_TASK_GATE         5
+#define TYPE_TSS               9
+#define TYPE_CALL_GATE         12
+#define TYPE_TRAP_GATE         15
+#define TYPE_INTERRUPT_GATE    14
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.c
new file mode 100644
index 0000000000000000000000000000000000000000..37c3c2bea6714eaaf2617abca7c1d00e4576bb8f
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.c
@@ -0,0 +1,261 @@
+#include "common/types.h"
+#include "font.h"
+
+uint8_t font_8x16[CHARS_COUNT*FONT_HEIGHT] = {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x99, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xD6, 0xD6, 0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x0E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00,
+        0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38, 0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
+        0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00,
+        0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00,
+        0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00,
+        0x00, 0x00, 0xCC, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xCC, 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xC6, 0xC6, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36, 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00,
+        0x00, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xC6, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE, 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00,
+        0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+        0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x60, 0xCE, 0x93, 0x06, 0x0C, 0x1F, 0x00, 0x00,
+        0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00,
+        0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+        0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+        0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+        0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
+        0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x80, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xCF, 0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x70, 0x98, 0x30, 0x60, 0xC8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.h
new file mode 100644
index 0000000000000000000000000000000000000000..602120a9ccbdf65dfc5b985a6f0d40e8588f0cf3
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/font.h
@@ -0,0 +1,12 @@
+#ifndef _FONT_H_
+#define _FONT_H_
+
+#include "common/types.h"
+
+#define FONT_HEIGHT      16
+#define FONT_WIDTH        8
+#define CHARS_COUNT     256
+
+extern uint8_t font_8x16[CHARS_COUNT*FONT_HEIGHT];
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.h
new file mode 100644
index 0000000000000000000000000000000000000000..4122acb31e24767742b798644653aa66d194c2bf
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.h
@@ -0,0 +1,10 @@
+#ifndef _KEYBOARD_H_
+#define _KEYBOARD_H_
+
+void keyb_init();
+
+// Returns the key that was pressed or 0 if no key is present in the internal buffer.
+// This function never blocks.
+int keyb_get_key();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.o
new file mode 100644
index 0000000000000000000000000000000000000000..dfc6ceeccef24cd7821bba496dddb0e1a2687fcd
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/keyboard.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.c
new file mode 100644
index 0000000000000000000000000000000000000000..1154d92bb4faf60a70fc869d2a9c78bf05d3d9aa
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.c
@@ -0,0 +1,45 @@
+#include "pmio/pmio.h"
+#include "term.h"
+
+#define PIC1_CMD        0x20
+#define PIC1_DATA       0x21
+#define PIC2_CMD        0xA0
+#define PIC2_DATA       0xA1
+
+// End Of Interrupt (reactivate the specified PIC)
+#define PIC_EOI         0x20
+
+// More details here: http://wiki.osdev.org/8259_PIC
+void pic_init() {
+    // By default IRQs 0-7 (master PIC) are mapped to interrupts 0x8-0xF (8-15)
+    // and IRQs 8-15 (slave PIC) are mapped to interrupts 0x70-0x77 (112-119).
+    // In protected mode, this scheme conflicts with CPU exceptions wich are
+    // reserved by the CPU and mapped to interrupts 0 to 31.
+    // Consequently, we map IRQs 0-7 to interrupts 32-39 and IRQs 8-15 to interrupts 40-47.
+
+    // Restart both PICs
+    outb(PIC1_CMD, 0x11);
+    outb(PIC2_CMD, 0x11);
+
+    // Map IRQs 0-7 to interrupts 32-39
+    outb(PIC1_DATA, 32);
+
+    // Map IRQs 8-15 to interrupts 40-47
+    outb(PIC2_DATA, 40);
+
+    // Setup PICs cascading
+    outb(PIC1_DATA, 0x04);
+    outb(PIC2_DATA, 0x02);
+    outb(PIC1_DATA, 0x01);
+    outb(PIC2_DATA, 0x01);
+
+    term_puts("PIC initialized.\n");
+}
+
+void pic_eoi(int irq) {
+    // An EOI must also be sent to the slave for IRQs > 7
+    if (irq > 7)
+        outb(PIC2_CMD, PIC_EOI);
+    // Send an EOI to the master
+    outb(PIC1_CMD, PIC_EOI);
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.h
new file mode 100644
index 0000000000000000000000000000000000000000..be4e1bc6876c1cc1967ef8e2255dd51a15dd2d72
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/pic.h
@@ -0,0 +1,10 @@
+#ifndef _PIC_H_
+#define _PIC_H_
+
+// Initialize both PICs by mapping IRQs 0-15 to interrupts 32-47.
+void pic_init();
+
+// Send an EOI to the PICs given which IRQ was handled.
+void pic_eoi(int irq);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.h
new file mode 100644
index 0000000000000000000000000000000000000000..f4098b25621a05194a4f0eb36564164b31b18d60
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.h
@@ -0,0 +1,23 @@
+#ifndef _TERM_H_
+#define _TERM_H_
+
+#include "common/types.h"
+#include "common/colors.h"
+
+extern void term_init();
+extern void term_clear();
+
+extern term_colors_t term_getcolors();
+extern void term_setcolors(term_colors_t colors);
+extern void term_setfgcolor(uint16_t foreground);
+extern void term_setbgcolor(uint16_t background);
+
+extern void term_setchar(char c, int x, int y, term_colors_t color);
+extern void term_putc(char c);
+extern void term_puts(char *s);
+extern void term_printf(char *fmt, ...);
+
+extern void term_getcursor(int *x, int *y);
+extern void term_setcursor(int x, int y);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.o
new file mode 100644
index 0000000000000000000000000000000000000000..8d1885aa5b4d5f479e72d05597414785defbf531
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/term.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..b257fef7c3e832d0138e39e038ac7039569e4687
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.h
@@ -0,0 +1,18 @@
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+// Initializes the timer with the specified frequency in Hz.
+// Note that the effective frequency might be different than the desired one.
+// Use timer_get_freq() to obtain the effective frequency.
+void timer_init(uint_t freq_hz);
+
+// Returns the number of ticks since boot.
+uint_t timer_get_ticks();
+
+// Sleeps (actively) the specified time in milliseconds.
+void timer_sleep(uint_t ms);
+
+// Returns the timer frequency in Hz.
+uint_t timer_get_freq();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.o
new file mode 100644
index 0000000000000000000000000000000000000000..7d13685fdec15505b78b1fbd81943028f22732ea
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/timer.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.h
new file mode 100644
index 0000000000000000000000000000000000000000..393abca054087564a150146108dceb48825c2ec1
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.h
@@ -0,0 +1,13 @@
+#ifndef _VBE_H_
+#define _VBE_H_
+
+#include "common/types.h"
+#include "common/vbe_fb.h"
+
+extern void vbe_init();
+extern vbe_fb_t *vbe_get_fb();
+extern void vbe_setpixel(int x, int y, uint16_t color);
+extern uint16_t vbe_getpixel(int x, int y);
+extern void vbe_clear(uint16_t color);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.o
new file mode 100644
index 0000000000000000000000000000000000000000..24ba0297790ee46ee8cf154d9ddb6cabb66cc1fd
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/drivers/vbe.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.c
new file mode 100644
index 0000000000000000000000000000000000000000..6aad730ac84c1be5fa5bec9293b2e5d3f149f886
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.c
@@ -0,0 +1,54 @@
+#include "common/types.h"
+#include "common/mem.h"
+#include "drivers/term.h"
+#include "mem/gdt.h"
+#include "descriptors.h"
+#include "idt.h"
+#include "x86.h"
+
+#define INTERRUPT_COUNT   256
+
+// Structure describing a pointer to the IDT gate table.
+// This format is required by the lidt instruction.
+typedef struct {
+    uint16_t limit;   // Limit of the table (ie. its size)
+    uint32_t base;    // Address of the first entry
+} __attribute__((packed)) idt_ptr_t;
+
+// Gates table
+static idt_entry_t idt[INTERRUPT_COUNT];
+
+// Loads the IDT specified in argument.
+// Defined in idt_asm.s
+void idt_load(idt_ptr_t *idt_ptr);
+
+// Builds and returns an IDT entry.
+// selector is the code segment selector to access the ISR
+// offset is the address of the ISR (for task gates, offset must be 0)
+// type indicates the IDT entry type
+// dpl is the privilege level required to call the associated ISR
+idt_entry_t idt_build_entry(uint16_t selector, uint32_t offset, uint8_t type, uint8_t dpl) {
+    idt_entry_t entry;
+    entry.offset15_0 = offset & 0xffff;
+    entry.selector = selector;
+    entry.reserved = 0;
+    entry.type = type;
+    entry.dpl = dpl;
+    entry.p = 1;
+    entry.offset31_16 = (offset >> 16) & 0xffff;
+    return entry;
+}
+
+// High-level ISR for processor exceptions.
+void exception_handler(regs_t *regs) {
+    // TODO
+}
+
+void idt_init() {
+    idt_init_base(idt, INTERRUPT_COUNT);
+
+    // TODO
+    // Add system call
+
+    term_puts("IDT initialized.\n");
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.h
new file mode 100644
index 0000000000000000000000000000000000000000..7da36846344027576ad92395b8a778f5e54c4431
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt.h
@@ -0,0 +1,37 @@
+#ifndef _IDT_H_
+#define _IDT_H_
+
+// Processor exceptions are located in this range of entries in the IVT
+#define FIRST_EXCEPTION   0
+#define LAST_EXCEPTION    20
+#define EXCEPTION_COUNT   (LAST_EXCEPTION-FIRST_EXCEPTION+1)
+
+// CPU context used when saving/restoring context from an interrupt
+typedef struct {
+    uint32_t gs, fs, es, ds;
+    uint32_t ebp, edi, esi;
+    uint32_t edx, ecx, ebx, eax;
+    uint32_t number, error_code;
+    uint32_t eip, cs, eflags, esp, ss;
+} regs_t;
+
+// Structure of an IDT descriptor. There are 3 types of descriptors:
+// task-gates, interrupt-gates, trap-gates.
+// See 5.11 of Intel 64 & IA32 architectures software developer's manual for more details.
+// For task gates, offset must be 0.
+typedef struct {
+    uint16_t offset15_0;   // only used by trap and interrupt gates
+    uint16_t selector;     // segment selector for trap and interrupt gates; TSS segment
+                           // selector for task gates
+    uint16_t reserved : 8;
+    uint16_t type : 5;
+    uint16_t dpl : 2;
+    uint16_t p : 1;
+    uint16_t offset31_16;  // only used by trap and interrupt gates
+} __attribute__((packed)) idt_entry_t;
+
+void idt_init();
+void idt_init_base(idt_entry_t *idt, uint_t interrupts_count);
+idt_entry_t idt_build_entry(uint16_t selector, uint32_t offset, uint8_t type, uint8_t dpl);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_asm.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_asm.o
new file mode 100644
index 0000000000000000000000000000000000000000..bfceb57155c9039ca47e6b145a637d3902d90b3e
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_asm.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_base.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_base.o
new file mode 100644
index 0000000000000000000000000000000000000000..59ae4676a2b7bc93b708468d70eb4b597069dc8a
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/idt_base.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.c
new file mode 100644
index 0000000000000000000000000000000000000000..d701a6cc8818f146df0627ed9cf97bd65d9ef6fe
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.c
@@ -0,0 +1,19 @@
+#include "irq.h"
+#include "common/mem.h"
+
+#define IRQ_COUNT    (IRQ_LAST-IRQ_FIRST+1)
+
+static handler_t irq_handlers[IRQ_COUNT];
+
+void irq_init() {
+    memset(irq_handlers, 0, sizeof(irq_handlers));
+}
+
+void irq_install_handler(uint_t irq, handler_t handler) {
+    irq_handlers[irq] = handler;
+}
+
+handler_t *irq_get_handler(uint_t irq) {
+    return &irq_handlers[irq];
+}
+
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.h
new file mode 100644
index 0000000000000000000000000000000000000000..0fdbdf91bdd7288cb38f2c07645d53286bf6ebc7
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq.h
@@ -0,0 +1,26 @@
+#ifndef _IRQ_H_
+#define _IRQ_H_
+
+#include "common/types.h"
+
+#define IRQ_FIRST    0
+#define IRQ_LAST     15
+
+typedef struct {
+    void (*func)(void);  // pointer to handler function
+    char name[64];  // associate a name to the function (for debugging purposes)
+} handler_t;
+
+// Initializes the array of IRQ handlers.
+void irq_init();
+
+// Installs a handler for the given IRQ.
+// The irq parameter must be in the range [0,15] inclusive.
+void irq_install_handler(uint_t irq, handler_t handler);
+
+// Retrieves the handler for a given IRQ.
+// The irq parameter must be in the range [0,15] inclusive.
+// Returns NULL if there is no handler for the given IRQ.
+handler_t *irq_get_handler(uint_t irq);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq_handler.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq_handler.o
new file mode 100644
index 0000000000000000000000000000000000000000..7ea57ad7fbfa4e12c8e972732fb77ada2609f2db
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/interrupt/irq_handler.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.c
new file mode 100644
index 0000000000000000000000000000000000000000..99016d280be0215790027851f2b395e9806f612c
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.c
@@ -0,0 +1,67 @@
+#include "common/string.h"
+#include "common/stdio.h"
+#include "common/mem.h"
+#include "common/keycodes.h"
+#include "boot/module.h"
+#include "boot/multiboot.h"
+#include "drivers/vbe.h"
+#include "drivers/term.h"
+#include "drivers/pic.h"
+#include "drivers/timer.h"
+#include "drivers/keyboard.h"
+#include "interrupt/idt.h"
+#include "mem/paging.h"
+#include "mem/frame.h"
+#include "mem/gdt.h"
+#include "task/task.h"
+#include "x86.h"
+
+// These are defined in the linker script: kernel.ld
+extern void ld_kernel_start();
+extern void ld_kernel_end();
+uint_t kernel_start = (uint_t)&ld_kernel_start;
+uint_t kernel_end = (uint_t)&ld_kernel_end;
+
+void kernel_main(multiboot_info_t *mbi) {
+    multiboot_set_info(mbi);
+    uint_t RAM_in_KB = multiboot_get_RAM_in_KB();
+
+    gdt_init();
+
+    // This function must be initialized first! (before using any term_xxx functions!)
+    vbe_init();
+    vbe_fb_t *fb = vbe_get_fb();
+
+    paging_init(RAM_in_KB);  // must be called AFTER vbe_init()!
+
+    term_init();
+    term_printf("YoctOS started\n");
+    term_printf("VBE mode %dx%d %dbpp initialized (addr=0x%x, pitch=%d).\n", fb->width, fb->height, fb->bpp, fb->addr, fb->pitch_in_bytes);
+    term_printf("Detected %dKB of RAM.\n", RAM_in_KB);
+    term_printf("%dKB of RAM available.\n", frame_total_free()*FRAME_SIZE/1024);
+    term_printf("Kernel loaded at [0x%x-0x%x], size=%dKB\n", kernel_start, kernel_end, (kernel_end-kernel_start)/1024);
+
+    modules_display_info();
+
+    pic_init();
+    idt_init();
+    keyb_init();
+
+    // IMPORTANT: timer frequency must be >= 50
+    int timer_freq = 500;
+    timer_init(timer_freq);
+
+    tasks_init();
+
+    // Unmask hardware interrupts
+    sti();
+    term_puts("Interrupts enabled.\n");
+
+    char *init = "shell.exe";
+    if (!task_exec(init)) {
+        term_printf("FAILED executing %s!", init);
+    }
+
+    term_printf("\nSystem halted.");
+    halt();
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.ld b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.ld
new file mode 100644
index 0000000000000000000000000000000000000000..73677fc5f0577d5eb309d2d704711192569e635c
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/kernel.ld
@@ -0,0 +1,26 @@
+ENTRY(entrypoint)            /* the entry point */
+
+SECTIONS {
+    /* All sections located above 1MB */
+    . = 0x100000;
+
+    /* Code sections */
+    ld_kernel_start = .;
+
+    /* multiboot section first (must reside in the first 8KB otherwise GRUB won't find it!) */
+    .multiboot ALIGN(4): { *(.multiboot) }
+    .text ALIGN(4): { *(.text) }
+
+    /* Read-only data section */
+    .rodata ALIGN(4): { *(.rodata) }
+
+    /* Read-write data sections (initialized and unitialized) */
+    .data ALIGN(4): { *(.data) }
+    .bss ALIGN(4): { *(.bss) }
+
+    /* Stack section (4KB-aligned to be at a page boundary */
+    .stack ALIGN(4096): { *(.stack) }
+    ld_stack_end = .;
+    
+    ld_kernel_end = .;
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.c
new file mode 100644
index 0000000000000000000000000000000000000000..efdedc79a01a763659f494835d6edfe78f9b6366
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.c
@@ -0,0 +1,5 @@
+#include "keymap.h"
+
+extern keymap_t keymap_fr_CH;
+
+keymap_t *keymap = &keymap_fr_CH;
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.h
new file mode 100644
index 0000000000000000000000000000000000000000..af6a84c84a382b855ca728395f00d0c4577506dd
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap.h
@@ -0,0 +1,18 @@
+#ifndef _KEYMAP_H_
+#define _KEYMAP_H_
+
+#include "common/types.h"
+
+#define MAP_SIZE 128
+
+// Indicate the entry must be ignored
+#define KEY_IGNORE 0x0
+
+typedef struct {
+    uint16_t normal[MAP_SIZE];
+    uint16_t shift[MAP_SIZE];
+    uint16_t ctrl[MAP_SIZE];
+    uint16_t alt[MAP_SIZE];
+} keymap_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap_fr_CH.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap_fr_CH.c
new file mode 100644
index 0000000000000000000000000000000000000000..0cc29aa76de6229fbd9eb3d5aa026d98fc3c34bb
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/keymaps/keymap_fr_CH.c
@@ -0,0 +1,194 @@
+#include "common/types.h"
+#include "common/keycodes.h"
+#include "keymap.h"
+
+keymap_t keymap_fr_CH = {
+    // Normal mapping
+    {
+        KEY_IGNORE,     // 0
+        KEY_ESC,        // 1    ESC
+        '1',            // 2
+        '2',            // 3
+        '3',            // 4
+        '4',            // 5
+        '5',            // 6
+        '6',            // 7
+        '7',            // 8
+        '8',            // 9
+        '9',            // 10
+        '0',            // 11
+        '\'',           // 12
+        '^',            // 13
+        '\b',           // 14   BACKSPACE
+        '\t',           // 15   TAB
+        'q',            // 16
+        'w',            // 17
+        'e',            // 18
+        'r',            // 19
+        't',            // 20
+        'z',            // 21
+        'u',            // 22
+        'i',            // 23
+        'o',            // 24
+        'p',            // 25
+        KEY_E_GRAVE,    // 26
+        '"',            // 27
+        '\n',           // 28  ENTER
+        KEY_IGNORE,     // 29  LEFT/RIGHT CTRL
+        'a',            // 30
+        's',            // 31
+        'd',            // 32
+        'f',            // 33
+        'g',            // 34
+        'h',            // 35
+        'j',            // 36
+        'k',            // 37
+        'l',            // 38
+        KEY_E_ACUTE,    // 39
+        KEY_A_GRAVE,    // 40
+        KEY_PARAGRAPH,  // 41
+        KEY_IGNORE,     // 42  LEFT SHIFT
+        '$',            // 43
+        'y',            // 44
+        'x',            // 45
+        'c',            // 46
+        'v',            // 47
+        'b',            // 48
+        'n',            // 49
+        'm',            // 50
+        ',',            // 51
+        '.',            // 52
+        '-',            // 53
+        KEY_IGNORE,     // 54   RIGHT SHIFT
+        KEY_IGNORE,     // 55   ?
+        KEY_IGNORE,     // 56   LEFT/RIGHT ALT
+        ' ',            // 57
+        KEY_IGNORE,     // 58   ?
+        KEY_F1,         // 59   F1
+        KEY_F2,         // 60   F2
+        KEY_F3,         // 61   F3
+        KEY_F4,         // 62   F4
+        KEY_F5,         // 63   F5
+        KEY_F6,         // 64   F6
+        KEY_F7,         // 65   F7
+        KEY_F8,         // 66   F8
+        KEY_F9,         // 67   F9
+        KEY_F10,        // 68   F10
+        KEY_IGNORE,     // 69   ?
+        KEY_IGNORE,     // 70   ?
+        KEY_HOME,       // 71   HOME
+        KEY_UP,         // 72   UP ARROW
+        KEY_PGUP,       // 73   PAGE UP
+        KEY_IGNORE,     // 74   ?
+        KEY_LEFT,       // 75   LEFT ARROW
+        KEY_IGNORE,     // 76   ?
+        KEY_RIGHT,      // 77   RIGHT ARROW
+        KEY_IGNORE,     // 78   ?
+        KEY_END,        // 79   END
+        KEY_DOWN,       // 80   DOWN ARROW
+        KEY_PGDOWN,     // 81   PAGE DOWN
+        KEY_INSERT,     // 82   INSERT
+        KEY_DEL,        // 83   DELETE
+        KEY_IGNORE,     // 84   ?
+        KEY_IGNORE,     // 85   ?
+        '<',            // 86
+        KEY_F11,        // 87   F11
+        KEY_F12,        // 88   F12
+    },
+    // SHIFT mapping
+    {
+        KEY_IGNORE,     // 0    ?
+        KEY_ESC,        // 1    ESC
+        '+',            // 2
+        '"',            // 3
+        '*',            // 4
+        KEY_C_CEDILLA,  // 5
+        '%',            // 6
+        '&',            // 7
+        '/',            // 8
+        '(',            // 9
+        ')',            // 10
+        '=',            // 11
+        '?',            // 12
+        '`',            // 13
+        '\b',           // 14   BACKSPACE
+        '\t',           // 15   TAB
+        'Q',            // 16
+        'W',            // 17
+        'E',            // 18
+        'R',            // 19
+        'T',            // 20
+        'Z',            // 21
+        'U',            // 22
+        'I',            // 23
+        'O',            // 24
+        'P',            // 25
+        KEY_U_DIAERESIS,// 26
+        '!',            // 27
+        '\n',           // 28  ENTER
+        KEY_IGNORE,     // 29  LEFT/RIGHT CTRL
+        'A',            // 30
+        'S',            // 31
+        'D',            // 32
+        'F',            // 33
+        'G',            // 34
+        'H',            // 35
+        'J',            // 36
+        'K',            // 37
+        'L',            // 38
+        KEY_O_DIAERESIS,// 39
+        KEY_A_DIAERESIS,// 40
+        KEY_DEGREE,     // 41
+        KEY_IGNORE,     // 42  LEFT SHIFT
+        KEY_POUND,      // 43
+        'Y',            // 44
+        'X',            // 45
+        'C',            // 46
+        'V',            // 47
+        'B',            // 48
+        'N',            // 49
+        'M',            // 50
+        ';',            // 51
+        ':',            // 52
+        '_',            // 53
+        KEY_IGNORE,     // 54   RIGHT SHIFT
+        KEY_IGNORE,     // 55   ?
+        KEY_IGNORE,     // 56   LEFT/RIGHT ALT
+        ' ',            // 57
+        KEY_IGNORE,     // 58   ?
+        KEY_F1,         // 59   F1
+        KEY_F2,         // 60   F2
+        KEY_F3,         // 61   F3
+        KEY_F4,         // 62   F4
+        KEY_F5,         // 63   F5
+        KEY_F6,         // 64   F6
+        KEY_F7,         // 65   F7
+        KEY_F8,         // 66   F8
+        KEY_F9,         // 67   F9
+        KEY_F10,        // 68   F10
+        KEY_IGNORE,     // 69   ?
+        KEY_IGNORE,     // 70   ?
+        KEY_HOME,       // 71   HOME
+        KEY_UP,         // 72   UP ARROW
+        KEY_PGUP,       // 73   PAGE UP
+        KEY_IGNORE,     // 74   ?
+        KEY_LEFT,       // 75   LEFT ARROW
+        KEY_IGNORE,     // 76   ?
+        KEY_RIGHT,      // 77   RIGHT ARROW
+        KEY_IGNORE,     // 78   ?
+        KEY_END,        // 79   END
+        KEY_DOWN,       // 80   DOWN ARROW
+        KEY_PGDOWN,     // 81   PAGE DOWN
+        KEY_INSERT,     // 82   INSERT
+        KEY_DEL,        // 83   DELETE
+        KEY_IGNORE,     // 84   ?
+        KEY_IGNORE,     // 85   ?
+        '>',            // 86
+        KEY_F11,        // 87   F11
+        KEY_F12,        // 88   F12
+    },
+    // CTRL mapping
+    {},
+    // ALT mapping
+    {}
+};
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.h
new file mode 100644
index 0000000000000000000000000000000000000000..e7f398015c38966a872400bdcbb6a169670da11a
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.h
@@ -0,0 +1,7 @@
+#ifndef _LOGO_H_
+#define _LOGO_H_
+
+void logo_init();
+void logo_render();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.o
new file mode 100644
index 0000000000000000000000000000000000000000..1262bb6f7fbf148f242fd3a4efe4b9e47dcba9ae
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/logo.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ceba10d4a490e21f5616a81bda36b0c6e90c519
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.h
@@ -0,0 +1,38 @@
+#ifndef _FRAME_H_
+#define _FRAME_H_
+
+#include "common/types.h"
+
+// The hardware supports 3 frame sizes: 4KB, 4MB and 2MB (when PAE is enabled)
+// Our kernel only uses 4KB frames.
+#define FRAME_SIZE  4096
+
+// Converts a 32-bit address into a frame number
+#define ADDR_TO_FRAME_NB(addr) (((uint32_t)addr)/FRAME_SIZE)
+
+// Converts a frame number into a 32-bit address
+#define FRAME_NB_TO_ADDR(n) (((uint32_t)n)*FRAME_SIZE)
+
+// Returns the number of frames required to store the given number of bytes
+#define FRAME_COUNT(size) ((size + FRAME_SIZE - 1)/FRAME_SIZE)
+
+// Initializes the physical frame subsystem, using the specified amount of physical memory.
+extern void frame_init(uint_t RAM_in_KB);
+
+// Allocates a frame (4KB) and returns its physical address.
+// Returns the physical address of the frame or
+// 0xFFFFFFFF if no more frames are available.
+// REMARKS:
+// The physical address is always aligned to a 4KB boundary.
+// The frame's content is always zeroed.
+extern void *frame_alloc();
+
+// Frees a frame.
+// REMARK: doesn't check whether the frame was previously allocated or not.
+extern void frame_free(void *frame_addr);
+
+// Returns the total number of free frames.
+// This can typically be used by a syscall to retrieve the amount of free RAM.
+extern uint_t frame_total_free();
+
+ #endif
\ No newline at end of file
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.o
new file mode 100644
index 0000000000000000000000000000000000000000..69cd64f456deb0771f3dc23c6d98a1a60a3260fc
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/frame.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.c
new file mode 100644
index 0000000000000000000000000000000000000000..b50bd39876e91111029df00efc7f280926c69158
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.c
@@ -0,0 +1,113 @@
+#include "common/types.h"
+#include "common/mem.h"
+#include "gdt.h"
+#include "descriptors.h"
+
+// Descriptor system bit (S)
+// For code or data segments
+#define S_CODE_OR_DATA   1
+// For TSS segment, LDT, call gate, interrupt gate, trap gate, task gate
+#define S_SYSTEM   0
+
+// D/B bit
+#define DB_SEG  1
+#define DB_SYS  0
+
+// Structure describing a pointer to the GDT descriptor table.
+// This format is required by the lgdt instruction.
+typedef struct gdt_ptr_st {
+    uint16_t limit;    // Limit of the table (ie. its size)
+    uint32_t base;     // Address of the first entry
+} __attribute__((packed)) gdt_ptr_t;
+
+// Macro used to convert the index of a segment descriptor in the GDT into a segment selector.
+#define GDT_INDEX_TO_SELECTOR(idx) ((idx) << 3)
+
+// Implemented in gdt_asm.s
+extern void gdt_load(gdt_ptr_t *gdt_ptr);
+
+// 6 because of these first 6 descriptors:
+//   0: NULL
+//   1: kernel code
+//   2: kernel data
+//   3: user code
+//   4: user data
+//   5: initial tss
+static gdt_entry_t gdt[6];
+static gdt_ptr_t gdt_ptr;
+
+// Used in future task code
+gdt_entry_t *gdt_initial_tss = &gdt[5];
+gdt_entry_t *gdt_first_free_entry = &gdt[6];
+
+// Build and return a GDT entry.
+// base is the base of the segment
+// limit is the limit of the segment (NOTE: it's a 20-bit value)
+// type is the type of segment
+// s indicates whether it's a system segment
+// db indicates whether it's a code/data segment or TSS, LDT or gate
+// granularity indicates 1 byte or 4KB granularity
+// dpl is the privilege level
+static gdt_entry_t build_entry(uint32_t base, uint32_t limit, uint8_t type, uint8_t s, uint8_t db, uint8_t granularity, uint8_t dpl) {
+    gdt_entry_t entry;
+    // For a TSS and LDT, base is the addresse of the TSS/LDT structure
+    // and limit is the size of the structure.
+    entry.lim15_0 = limit & 0xffff;
+    entry.base15_0 = base & 0xffff;
+    entry.base23_16 = (base >> 16) & 0xff;
+    entry.type = type;  // See TYPE_xxx flags
+    entry.s = s;        // 1 for segments; 0 for system (TSS, LDT, gates)
+    entry.dpl = dpl;    // privilege level
+    entry.present = 1;  // present in memory
+    entry.lim19_16 = (limit >> 16) & 0xf;
+    entry.avl = 0;      // available for use
+    entry.l = 0;        // should be 0 (64-bit code segment)
+    entry.db = db;      // 1 for 32-bit code and data segments; 0 for system (TSS, LDT, gate)
+    entry.granularity = granularity;  // granularity of the limit value: 0 = 1 byte; 1 = 4096 bytes
+    entry.base31_24 = (base >> 24) & 0xff;
+    return entry;
+}
+
+// Return a NULL entry.
+static gdt_entry_t gdt_make_null_segment() {
+    gdt_entry_t entry;
+    memset(&entry, 0, sizeof(gdt_entry_t));
+    return entry;
+}
+
+// Return a code segment specified by the base, limit and privilege level passed in arguments.
+static gdt_entry_t gdt_make_code_segment(uint32_t base, uint32_t limit, uint8_t dpl) {
+    return build_entry(base, limit, TYPE_CODE_EXECONLY, S_CODE_OR_DATA, DB_SEG, 1, dpl);
+}
+
+// Return a read-write data segment specified by the base, limit and privilege level passed in arguments.
+static gdt_entry_t gdt_make_data_segment(uint32_t base, uint32_t limit, uint8_t dpl) {
+    return build_entry(base, limit, TYPE_DATA_RW, S_CODE_OR_DATA, DB_SEG, 1, dpl);
+}
+
+// Return a TSS entry  specified by the TSS structure and privilege level passed in arguments.
+// NOTE: a TSS entry can only reside in the GDT!
+gdt_entry_t gdt_make_tss(tss_t *tss, uint8_t dpl) {
+    return build_entry((uint32_t)tss, sizeof(tss_t)-1, TYPE_TSS, S_SYSTEM, DB_SYS, 0, dpl);
+}
+
+// Return the selector of an entry in the GDT
+uint_t gdt_entry_to_selector(gdt_entry_t *entry) {
+    return GDT_INDEX_TO_SELECTOR(entry - gdt);
+}
+
+// Initialize the GDT
+void gdt_init() {
+    gdt_ptr.limit = sizeof(gdt)-1;
+    gdt_ptr.base  = (uint32_t)&gdt;
+
+    // Entries for null segment, kernel code and kernel data segments
+    gdt[0] = gdt_make_null_segment();  // null segment
+    gdt[1] = gdt_make_code_segment(0x0, 0xFFFFF, DPL_KERNEL);  // kernel code segment: 4GB limit
+    gdt[2] = gdt_make_data_segment(0x0, 0xFFFFF, DPL_KERNEL);  // kernel data (+stack) segment: 4GB limit
+    gdt[3] = gdt_make_code_segment(0x0, 0xFFFFF, DPL_USER);    // user code segment: 4GB limit
+    gdt[4] = gdt_make_data_segment(0x0, 0xFFFFF, DPL_USER);    // user data (+stack) segment: 4GB limit
+
+    // Load the GDT
+    gdt_load(&gdt_ptr);
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.h
new file mode 100644
index 0000000000000000000000000000000000000000..990f21cce88baa394cd98c1d4cfcac65d16d64a9
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt.h
@@ -0,0 +1,43 @@
+#ifndef _GDT_H_
+#define _GDT_H_
+
+#include "task/tss.h"
+
+#define KERNEL_TSS_INDEX (5)
+#define KERNEL_TSS_SEL (KERNEL_TSS_INDEX*8)
+
+// kernel code and data selectors in the GDT
+#define GDT_KERNEL_CODE_SELECTOR   (8 | DPL_KERNEL)
+#define GDT_KERNEL_DATA_SELECTOR  (16 | DPL_KERNEL)
+
+// user code and data selectors in the GDT
+#define GDT_USER_CODE_SELECTOR    (24 | DPL_USER)
+#define GDT_USER_DATA_SELECTOR    (32 | DPL_USER)
+
+// Structure of a GDT descriptor. There are 2 types of descriptors: segments and TSS.
+// Section 3.4.5 of Intel 64 & IA32 architectures software developer's manual describes
+// segment descriptors while section 6.2.2 describes TSS descriptors.
+typedef struct gdt_entry_st {
+    uint16_t lim15_0;
+    uint16_t base15_0;
+    uint8_t base23_16;
+
+    uint8_t type : 4;
+    uint8_t s : 1;
+    uint8_t dpl : 2;
+    uint8_t present : 1;
+
+    uint8_t lim19_16 : 4;
+    uint8_t avl : 1;
+    uint8_t l : 1;
+    uint8_t db : 1;
+    uint8_t granularity : 1;
+
+    uint8_t base31_24;
+} __attribute__((packed)) gdt_entry_t;
+
+extern void gdt_init();
+extern uint_t gdt_entry_to_selector(gdt_entry_t *entry);
+extern gdt_entry_t gdt_make_tss(tss_t *tss, uint8_t dpl);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..4f0eccd65eed64981fe596eef4ef6e3cb0330490
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/gdt_asm.s
@@ -0,0 +1,19 @@
+%include "const.inc"
+
+global gdt_load
+
+section .text:           ; start of the text (code) section
+align 4                  ; the code must be 4 byte aligned
+
+gdt_load:
+    mov     eax,[esp+4]  ; Get the pointer to the GDT, passed as a parameter.
+    lgdt    [eax]        ; Load the new GDT pointer
+    mov     ax,GDT_KERNEL_DATA_SELECTOR   ; offset in the GDT of the kernel data segment
+    mov     ds,ax        ; Load all data segment selectors
+    mov     es,ax
+    mov     fs,ax
+    mov     gs,ax
+    mov     ss,ax
+    jmp     GDT_KERNEL_CODE_SELECTOR:.flush  ; far jump [selector:offset]
+.flush:
+	ret
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.h
new file mode 100644
index 0000000000000000000000000000000000000000..89b158a440456a0f33716765cbca16d62d20ab65
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.h
@@ -0,0 +1,131 @@
+#ifndef _PAGING_H_
+#define _PAGING_H_
+
+#include "common/types.h"
+
+// The hardware supports 3 page sizes: 4KB, 4MB and 2MB (when PAE is enabled)
+// Our kernel only uses 4KB pages.
+#define PAGE_SIZE  4096
+
+// The maximum number of pages in total on a IA-32 architecture is 2^20 (= 1048576 pages).
+// 1048576 * 4096KB = 4GB
+
+// Number of pages in a page table
+#define PAGES_IN_PT 1024
+
+// Number of page tables in a page directory
+// (number of page directory entries in a page directory)
+#define PAGETABLES_IN_PD 1024
+
+// Returns the index of the PDE (page directory entry) for a given virtual address
+#define ADDR_TO_PDE(addr) (((uint32_t)addr) >> 22)
+
+// Converts a 32-bit address into a page number
+#define ADDR_TO_PAGE_NB(addr) (((uint32_t)addr)/PAGE_SIZE)
+
+// Converts a page number into a 32-bit address
+#define PAGE_NB_TO_ADDR(n) (((uint32_t)n)*PAGE_SIZE)
+
+// Returns the number of pages required to store the given number of bytes
+#define PAGE_COUNT(size) ((size + PAGE_SIZE - 1)/PAGE_SIZE)
+
+// For details about a page directories and a page tables, see Vol. 3A System Programming Guide Part 1
+// of the Intel 64 and IA-32 Architecture Software Dev's Manual.
+// In particular, section 3.7.6 Page-Directory and Page-Table Entries
+
+enum privilege_t {
+    PRIVILEGE_KERNEL = 0,
+    PRIVILEGE_USER = 1
+};
+
+enum access_t {
+    ACCESS_READONLY = 0,
+    ACCESS_READWRITE = 1
+};
+
+// Structure of a page directory entry (PDE). A page directory is an array of page directory
+// entries.
+// A page table can hold 1024 pages which means addressing up to 4MB of RAM (using 4KB pages).
+// Using 1024 page tables, we can address 4GB of RAM.
+typedef struct {
+    // The bit below is the least significant
+    uint32_t present : 1;        // page table currently loaded in memory (used for swapping)
+    uint32_t rw : 1;             // specifies read-write privileges
+    uint32_t user : 1;           // specifies user or supervisor privilege
+    uint32_t write_through : 1;  // enable/disable write-through caching for the associated
+                                 // page table
+    uint32_t cache_disable : 1;  // enable/disable caching of the associated page table
+                                 // (useful for MMIO)
+    uint32_t accessed : 1;       // page table has been accessed by read or write (set by cpu)
+    uint32_t reserved : 1;       // reserved (0)
+    uint32_t page_sz : 1;        // page size: 0 = 4KB, 1 = 4MB
+    uint32_t gp : 1;             // indicates a global page (ignored)
+    uint32_t available : 3;      // unused, freely available for kernel use
+    // Frame number of the PT this PDE points to.
+    // To get the PT's physical address, simply multiply this by page size
+	uint32_t pagetable_frame_number : 20;
+    // The 20 bits above are the most significant
+} __attribute__((packed)) PDE_t;
+
+// Structure of a page table entry (PTE). A page table is an array of page table entries.
+// A page can hold 2^12 bytes = 4096 bytes = 4KB.
+typedef struct {
+    // The bit below is the least significant
+    uint32_t present : 1;        // page currently loaded in memory (used for swapping)
+    uint32_t rw : 1;             // specifies read-write privileges
+    uint32_t user : 1;           // specifies user or supervisor privilege
+    uint32_t write_through : 1;  // enable/disable write-through caching for the associated page
+    uint32_t cache_disable : 1;  // enable/disable caching of the associated page
+                                 // (useful for MMIO)
+    uint32_t accessed : 1;       // page has been accessed by read or write (set by cpu)
+    uint32_t dirty : 1;          // page has been written to (set by cpu)
+    uint32_t pat : 1;            // only used when using "Page Attribute Table" (PAT),
+                                 // 0 otherwise
+    uint32_t gp : 1;             // indicates a global page
+    uint32_t available : 3;      // unused, freely available for kernel use
+    uint32_t frame_number : 20;  // frame number the page points to
+    // The 20 bits above are the most significant
+} __attribute__((packed)) PTE_t;
+
+// Setup the kernel page directory with the following two mappings:
+// - Identity map the available RAM so that the kernel can access it as if there was no paging.
+// - Identity map the VBE framebuffer.
+// Then, loads the page directory and activate paging.
+void paging_init(uint_t RAM_in_KB);
+
+// Map, in the specified page directory, the page starting at virt_addr into
+// the physical address (frame) phys_addr.
+// This function dynamically allocates the necessary memory (frames) to store the
+// page table (if not previously allocated).
+// Return the new allocated page table if one was just allocated, otherwise returns 0.
+PTE_t *mmap_page(PDE_t *pagedir, uint32_t virt_addr, uint32_t phys_addr, enum privilege_t privilege, enum access_t access);
+
+// Maps, in the specified page directory, size bytes starting at virtual address virt_addr
+// into physical address phys_addr. Both virtual and physical areas are contiguous.
+// This function dynamically allocates the necessary frames to store the page tables.
+// IMPORTANT: virt_addr and phys_addr must be aligned to a page size (4KB).
+void paging_mmap(PDE_t *pagedir, uint32_t virt_addr, uint32_t phys_addr, uint32_t size, enum privilege_t privilege, enum access_t access);
+
+// Enable paging.
+// Assembly function implemented in paging_asm.s
+void paging_enable();
+
+// Load the specified page directory into the CPU and make it active.
+// Assembly function implemented in paging_asm.s
+void paging_load_pagedir(PDE_t *pagedir);
+
+// Return the page directory currently used by the CPU.
+// Assembly function implemented in paging_asm.s
+PDE_t *paging_get_current_pagedir();
+
+// Allocates size bytes of physical memory (as frames, so not necessarily contiguous), then maps these
+// frames at virtual address virt_addr. The area at virt_addr is guaranteed to be contiguous.
+// The mapping is performed in the specified page directory.
+// This function dynamically allocates the necessary frames to store the page tables and stores
+// their addresses into page_tables so that they can be subsequently freed.
+// If NULL is passed in page_tables, then the allocated frames' addresses won't be stored.
+// IMPORTANT: virt_addr and phys_addr must be aligned to a page size (4KB).
+// Returns the number of frames allocated (including frames used to store page tables).
+uint_t paging_alloc(PDE_t *pagedir, PTE_t *page_tables[PAGETABLES_IN_PD], uint32_t virt_addr, uint32_t size, enum privilege_t privilege);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.o b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.o
new file mode 100644
index 0000000000000000000000000000000000000000..7e3540b6383a5a54a8986d558c51688b2f064530
Binary files /dev/null and b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging.o differ
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_alloc.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_alloc.c
new file mode 100644
index 0000000000000000000000000000000000000000..b404e7e64c781fcf0096d921c8d1964f70cd1b9d
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_alloc.c
@@ -0,0 +1,43 @@
+#include "paging.h"
+#include "x86.h"
+
+// Allocates size bytes of physical memory (as frames, so not necessarily contiguous), then maps these
+// frames at virtual address virt_addr. The area at virt_addr is guaranteed to be contiguous.
+// The mapping is performed in the specified page directory.
+// This function dynamically allocates the necessary frames to store the page tables and stores
+// their addresses into page_tables so that they can be subsequently freed.
+// If NULL is passed in page_tables, then the allocated frames' addresses won't be stored.
+// IMPORTANT: virt_addr and phys_addr must be aligned to a page size (4KB).
+// Returns the number of frames allocated (including frames used to store page tables).
+
+uint_t paging_alloc(PDE_t *pagedir, PTE_t *page_tables[PAGETABLES_IN_PD], uint32_t virt_addr, uint32_t size, enum privilege_t privilege) {
+    if (virt_addr % PAGE_SIZE) {
+        // Virtual address must be aligned to PAGE_SIZE!
+        halt();
+    }
+
+    // Skip entries of already allocated pagetables since we'll need to store newly allocated page tables
+    uint_t pt_offset = 0;
+    while (page_tables && page_tables[pt_offset]) {
+        pt_offset++;
+    }
+
+    int pt_count = 0;
+
+    // How many frames do we need?
+    uint_t frame_count = PAGE_COUNT(size);
+    if (frame_count == 0)
+        return 0;
+
+    for (uint_t i = 0; i < frame_count; i++) {
+        uint32_t frame_addr = (uint32_t)frame_alloc();
+        PTE_t *page_table = mmap_page(pagedir, virt_addr, frame_addr, privilege, ACCESS_READWRITE);
+        // A new page table was just allocated, store it into the input page_tables array of pointer to page tables
+        if (page_tables && page_table) {
+            page_tables[pt_offset+pt_count++] = page_table;
+        }
+        virt_addr += PAGE_SIZE;
+    }
+
+    return pt_count+frame_count;
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..b26154919091d95a0831439e3525d8fc9aee103b
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/mem/paging_asm.s
@@ -0,0 +1,29 @@
+%include "const.inc"
+
+global paging_enable
+global paging_load_pagedir
+global paging_get_current_pagedir
+
+section .text:           ; start of the text (code) section
+align 4                  ; the code must be 4 byte aligned
+
+; Enable paging.
+; Paging is enabled by setting bit 31 (PG) of the CR0 register (CR0 = CR0 | 0x80000000)
+; void paging_enable(void)
+paging_enable:
+	mov    eax,cr0
+	or     eax,0x80000000
+	mov    cr0,eax
+	ret
+
+; load the CR3 register with the specified page directory
+; void paging_load_pagedir(uint32_t dir_entry_addr)
+paging_load_pagedir:
+	mov    eax,[esp+4]
+	mov    cr3,eax
+	ret
+
+; pagetable_t *paging_get_current_pagedir();
+paging_get_current_pagedir:
+	mov		eax,cr3
+	ret
\ No newline at end of file
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio.h
new file mode 100644
index 0000000000000000000000000000000000000000..63d09658a21f2d72fef089f3eed80b689ac2c300
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio.h
@@ -0,0 +1,16 @@
+#ifndef _PMIO_H_
+#define _PMIO_H_
+
+#include "common/types.h"
+
+// Write a 8-bit data to the specified port
+void outb(uint16_t port, uint8_t data);
+// Read a 8-bit data from the specified port
+uint8_t inb(uint16_t port);
+
+// Write a 16-bit data to the specified port
+void outw(uint16_t port, uint16_t data);
+// Read a 16-bit data from the specified port
+uint16_t inw(uint16_t port);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..e6d7a2d4a07f5c6f11238820af279f4e4eedb427
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/pmio/pmio_asm.s
@@ -0,0 +1,33 @@
+global outb
+global inb
+global outw
+global inw
+
+section .text    ; start of the text (code) section
+align 4          ; the code must be 4 byte aligned
+
+; void outb(uint16 port, uint8 data)
+outb:
+    mov     dx,word [esp+4]    ; port (2 bytes)
+    mov     al,byte [esp+8]    ; data (1 byte)
+    out     dx,al
+    ret
+
+; uint8 inb(uint16 port)
+inb:
+    mov     dx,word [esp+4]    ; port (2 bytes)
+    in      al,dx
+    ret
+
+; void outw(uint16 port, uint16 data)
+outw:
+    mov     dx,word [esp+4]    ; port (2 bytes)
+    mov     ax,word [esp+8]    ; data (2 bytes)
+    out     dx,ax
+    ret
+
+; uint16 inw(uint16 port)
+inw:
+    mov     dx,word [esp+4]    ; port (2 bytes)
+    in      ax,dx
+    ret
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.c
new file mode 100644
index 0000000000000000000000000000000000000000..bfb3ae8a587e8a4aa7bc8a9428b6c581ffdba3c8
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.c
@@ -0,0 +1,17 @@
+#include "common/types.h"
+#include "syscall.h"
+
+// Dummy syscall
+static int syscall_dummy(uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) {
+    UNUSED(arg1);
+    UNUSED(arg2);
+    UNUSED(arg3);
+    UNUSED(arg4);
+    return 0;
+}
+
+// Called by the assembly function: _syscall_handler
+int syscall_handler(syscall_t nb, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) {
+    // Call the syscall function based on nb.
+    // Make sure to return an error in case of an invalid syscall number.
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fb537dfa80fed7e5a6d25ad6f774d3358bc7961
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall.h
@@ -0,0 +1,11 @@
+#ifndef _SYSCALL_H_
+#define _SYSCALL_H_
+
+#include "common/syscall_nb.h"
+
+int syscall_handler(syscall_t nb, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
+
+// Declared in syscall_asm.s
+void _syscall_handler();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..cc243d161691c0f0c36e29a20a37e6cf2e43f71b
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/syscall/syscall_asm.s
@@ -0,0 +1,49 @@
+%include "const.inc"
+
+section .text                      ; start of the text (code) section
+align 4                            ; the code must be 4 byte aligned
+
+extern syscall_handler
+
+global _syscall_handler
+
+_syscall_handler:
+    ; Save segments registers as they are modified to point to the kernel's data
+    push    ds
+    push    es
+    push    fs
+    push    gs
+    
+    ; Load kernel data descriptor into all segments
+    push    eax
+    mov     ax,GDT_KERNEL_DATA_SELECTOR
+    mov     ds,ax
+    mov     es,ax
+    mov     fs,ax
+    mov     gs,ax
+    pop     eax
+
+    ; Pass the 5 arguments (nb, arg1, ..., arg4) to the syscall_handler
+    ; They are in reverse order to match the cdecl IA-32 ABI.
+    push    esi
+    push    edx
+    push    ecx
+    push    ebx
+    push    eax
+
+    call    syscall_handler
+
+    ; These 5 "pop eax" instructions are only here to balance the pushes
+    ; above used to pass the arguments to the syscall_handler function
+    pop     ebx
+    pop     ebx
+    pop     ebx
+    pop     ebx
+    pop     ebx
+
+    ; Restore segment registers
+    pop     gs
+    pop     fs
+    pop     es
+    pop     ds
+    iret
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.c
new file mode 100644
index 0000000000000000000000000000000000000000..de6a5cbe4586b880d9daac4cf343e4d554ffe0ed
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.c
@@ -0,0 +1,56 @@
+#include "common/mem.h"
+#include "mem/gdt.h"
+#include "descriptors.h"
+#include "task.h"
+
+#define TASK_STACK_SIZE_MB 2
+
+static task_t tasks[MAX_TASK_COUNT];
+static tss_t initial_tss;
+static uint8_t initial_tss_kernel_stack[65536];
+
+// Initializes the task subsystem.
+void tasks_init() {
+    memset(tasks, 0, sizeof(tasks));
+
+    // Allocates and initializes the initial TSS: it is where the CPU state
+    // will be saved before switching from the kernel to the very first user task.
+    extern gdt_entry_t *gdt_initial_tss;
+    *gdt_initial_tss = gdt_make_tss(&initial_tss, DPL_KERNEL);
+    memset(&initial_tss, 0, sizeof(tss_t));
+    initial_tss.ss0 = GDT_KERNEL_DATA_SELECTOR;
+    initial_tss.esp0 = ((uint32_t)initial_tss_kernel_stack) + sizeof(initial_tss_kernel_stack);
+    initial_tss.cr3 = (uint32_t)paging_get_current_pagedir();
+
+    // Loads the task register to point to the initial TSS selector.
+    // IMPORTANT: The GDT must already be loaded before loading the task register!
+    task_ltr(gdt_entry_to_selector(gdt_initial_tss));
+}
+
+// Returns a pointer to the current task.
+// If NULL is returned it means we are in the kernel.
+task_t *task_get_current() {
+    return NULL;
+}
+
+// Creates and returns a task from the fixed pool of tasks.
+// This function dynamically allocates the address space of size "size" (in bytes) for the task.
+// Returns NULL if failed.
+static task_t *task_create(uint_t addr_space_size) {
+}
+
+// Frees a task previously created with task_create().
+// This function frees the task's page frames.
+static void task_free(task_t *t) {
+}
+
+// Creates a new task with the content of the specified binary application.
+// Once loaded, the task is ready to be executed.
+// Returns NULL if failed (ie. reached max number of tasks).
+static task_t *task_load(char *filename) {
+}
+
+// Loads a task and executes it.
+// Returns false if failed.
+bool task_exec(char *filename) {
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.h
new file mode 100644
index 0000000000000000000000000000000000000000..51700bf3ce426a1a5aca146bc39dea1dec96a374
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task.h
@@ -0,0 +1,37 @@
+#ifndef _TASK_H_
+#define _TASK_H_
+
+#include "common/types.h"
+#include "mem/paging.h"
+#include "tss.h"
+
+#define MAX_TASK_COUNT  8
+
+// Virtual address (1GB) where task user code/data is mapped (i.e. application entry point)
+#define TASK_VIRT_ADDR 0x40000000
+
+// Structure of a task.
+typedef struct {
+    PDE_t pagedir[PAGETABLES_IN_PD] __attribute__((aligned(4096)));  // Task page directory
+    tss_t tss __attribute__((aligned(4096)));   // Context of the task (must not cross a page boundary!)
+    PTE_t *page_tables[PAGES_IN_PT];            // Save pointers to page tables in order to deallocate
+                                                // previously allocated frames at task termination
+    uint16_t tss_selector;                      // selector required when switching to the task
+    uint8_t kernel_stack[65536];                // kernel stack
+    uint32_t virt_addr;                         // Start of the task's virtual address space
+    uint32_t addr_space_size;                   // Size of the task's address space in bytes
+    // TODO: add whathever you'd like...
+} task_t;
+
+void tasks_init();
+
+task_t *task_get_current();
+
+bool task_exec(char *filename);
+
+// Implemented in task_asm.s
+void task_ltr(uint16_t tss_selector);
+void task_switch(uint16_t tss_selector);
+uint16_t task_get_current_sel();
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..de7f3fb74432a68f7dd4f86546aa63a6510603fa
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/task_asm.s
@@ -0,0 +1,40 @@
+global task_ltr
+global task_switch
+global task_get_current_sel
+
+section .data
+tss_sel_offs dd 0  ; must always be 0
+tss_sel_seg  dw 0  ; overwritten by the task_switch function
+
+section .text:                     ; start of the text (code) section
+align 4                            ; the code must be 4 byte aligned
+
+; Load the task register with the TSS selector passed in argument.
+; The TSS selector represents the offset of the TSS descriptor in the GDT table.
+; NOTE: The GDT must be loaded before issuing the ltr instruction!
+;
+; void task_ltr(uint16_t tss_selector);
+task_ltr:
+    mov     eax,[esp+4]
+    ltr     ax
+    ret
+
+; Call the task specified by the tss selector in argument.
+; When the CPU switches to the new task, it automatically loads the task register
+; with the new task (ltr instruction) and the LDT from the tss.ldt_selector field.
+;
+; void task_switch(uint16_t tss_selector)
+task_switch:
+    mov     ax,[esp+4]  ; get the TSS selector passed in argument (16 bits)
+    ; rewrite the segment to jump to with the tss selector passed in argument
+	mov		ecx,tss_sel_seg
+    mov     [ecx],ax
+    call    far [ecx-4]
+    ret
+
+; Return the current task's TSS selector
+;
+; uint16_t task_get_current_sel()
+task_get_current_sel:
+    str     ax  ; store the segment selector from the task register (TR) in ax
+    ret
\ No newline at end of file
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/tss.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/tss.h
new file mode 100644
index 0000000000000000000000000000000000000000..391f0d7d6a8d04810bc99ecf1daeba48dcaef300
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/task/tss.h
@@ -0,0 +1,36 @@
+#ifndef _TSS_H_
+#define _TSS_H_
+
+#include "common/types.h"
+
+// IMPORTANT: by default (if IOMAP is 0) all ports are accessibles from ring 3!
+// Set to 1 if iomap is needed (forbid or allow access to IO ports from user mode).
+// It requires an extra 8KB in the TSS to store the ports bitmap.
+#define IOMAP 1
+
+// Task-State Segment (TSS) structure.
+typedef struct {
+    uint16_t previous_task_link, reserved0;
+    uint32_t esp0;
+    uint16_t ss0, reserved1;
+    uint32_t esp1;
+    uint16_t ss1, reserved2;
+    uint32_t esp2;
+    uint16_t ss2, reserved3;
+    uint32_t cr3;
+    uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
+    uint16_t es, reserved4;
+    uint16_t cs, reserved5;
+    uint16_t ss, reserved6;
+    uint16_t ds, reserved7;
+    uint16_t fs, reserved8;
+    uint16_t gs, reserved9;
+    uint16_t ldt_selector, reserved10;
+    uint16_t reserved11;
+    uint16_t iomap_base_addr;  // adress (relative to byte 0 of the TSS) of the IO permission bitmap
+#if IOMAP
+    uint8_t iomap[8192];       // IO permission bitmap for ports 0 to 0xFFFF
+#endif
+} __attribute__ ((packed)) tss_t;
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/x86.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/x86.h
new file mode 100644
index 0000000000000000000000000000000000000000..58260d774f114317d5603b5ee222c4cf345adc36
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/kernel/x86.h
@@ -0,0 +1,20 @@
+#ifndef _X86_H_
+#define _X86_H_
+
+// Disable hardware interrupts.
+static inline void cli() {
+    asm volatile("cli");
+}
+
+// Enable hardware interrupts.
+static inline void sti() {
+    asm volatile("sti");
+}
+
+// Halt the processor.
+// External interrupts wake up the CPU, hence the cli instruction.
+static inline void halt() {
+    while (1) asm volatile("cli\nhlt");
+}
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/Makefile b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e56a8cf1979c434a9538dbc02ee81b3042d21281
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/Makefile
@@ -0,0 +1,39 @@
+include ../common.mk
+
+override LD_FLAGS+=-Tapp.ld $(BAREMETAL_FLAGS) -lgcc
+
+USER_C_SRC=$(shell find . -iname "*.c")
+USER_ASM_SRC=$(shell find . -iname "*.s")
+USER_C_OBJ=$(USER_C_SRC:.c=.o)
+USER_C_DEP=$(USER_C_SRC:.c=.d)
+USER_ASM_OBJ=$(USER_ASM_SRC:.s=.o)
+
+DEP=$(USER_C_OBJ:%.o=%.d)
+
+APP_DEP=entrypoint_asm.o syscall_asm.o ulibc.o $(COMMON_OBJ)
+
+APPS=hello.exe
+
+all: $(APPS)
+
+# Since these obj files are not deps of anything (intermediary files), make deletes them.
+# <HACK>Here we force them to be a dep of something</HACK>
+# There is probably a better way of doing this...
+UNUSED: $(USER_C_OBJ)
+
+%.o: %.c
+	$(CC) $(CC_FLAGS) $(CC_DEFINES) -I.. $< -o $@
+
+%.o: %.s
+	nasm -f elf32 $< -o $@
+
+%.exe: %.o $(APP_DEP)
+	$(LD) $^ -o $@ $(LD_FLAGS)
+
+clean:
+	$(MAKE) -C $(COMMON_DIR) clean
+	/bin/rm -f $(APPS) $(USER_C_OBJ) $(USER_C_DEP) $(USER_ASM_OBJ)
+
+.PHONY: clean
+
+-include $(DEP)
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/app.ld b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/app.ld
new file mode 100644
index 0000000000000000000000000000000000000000..e0e939865b693ca157521983b370cef2df3d25b8
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/app.ld
@@ -0,0 +1,32 @@
+OUTPUT_FORMAT("binary")
+OUTPUT_ARCH(i386)
+
+SECTIONS {
+	. = 0x40000000;         /* first section located at 1GB */
+
+	.entrypoint ALIGN(4):   /* entry point: must be located at 0 */
+	{
+		*(.entrypoint)
+	}
+
+	.text ALIGN(4) :        /* code */
+	{
+		*(.text*)
+	}
+
+	.rodata ALIGN(4) :      /* read-only data */
+	{
+		*(.rodata*)          
+	}
+
+	.data ALIGN(4) :        /* initialized data */
+	{
+		*(.data*)
+	}
+
+	.bss ALIGN(4) :         /* unitialized data */
+	{
+		*(COMMON)
+		*(.bss*)
+	}
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/entrypoint_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/entrypoint_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..033e93e58baa7093e4dd700d7c52784483366c68
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/entrypoint_asm.s
@@ -0,0 +1,7 @@
+extern main
+
+section .entrypoint
+    call  main
+    jmp   exit
+
+section .text
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/hello.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/hello.c
new file mode 100644
index 0000000000000000000000000000000000000000..d73a5692431ea93d3f7c2f73fe773feb7bfb0b93
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/hello.c
@@ -0,0 +1,4 @@
+#include "ulibc.h"
+
+void main() {
+}
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ld.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ld.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ebb0bfcc11835bdab88c55aea441e6285af716d
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ld.h
@@ -0,0 +1,6 @@
+#ifndef _LD_H_
+#define _LD_H_
+
+#define SECTION_DATA __attribute__((section(".data")))
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall.h
new file mode 100644
index 0000000000000000000000000000000000000000..c811d8decaa255b3a7591be324ea3b450ff6ad25
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall.h
@@ -0,0 +1,9 @@
+#ifndef _SYSCALL_H_
+#define _SYSCALL_H_
+
+#include "common/types.h"
+#include "common/syscall_nb.h"
+
+int syscall(syscall_t nb, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
+
+#endif
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall_asm.s b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall_asm.s
new file mode 100644
index 0000000000000000000000000000000000000000..aa3627af69b9894cce3b6ece7a2923bf8476e62b
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/syscall_asm.s
@@ -0,0 +1,40 @@
+global syscall
+
+section .text                      ; start of the text (code) section
+align 4                            ; the code must be 4 byte aligned
+
+; int syscall(uint32_t nb, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
+syscall:
+    ; parameters cannot be passed into the stack because the trap/interrupt gate
+    ; performs a stack switch (from user stack to kernel stack). By the time we're
+    ; in the syscall handler we're accessing the kernel stack (tss.ss/tss.esp).
+    push    ebp
+    mov     ebp,esp
+
+	; save general registers since we modify them below
+	; eax is not saved as it's used to store the syscall's return value 
+    push    ebx
+    push    ecx
+    push    edx
+    push    esi
+    push    edi
+
+    mov     eax,[ebp+8]
+    mov     ebx,[ebp+12]
+    mov     ecx,[ebp+16]
+    mov     edx,[ebp+20]
+    mov     esi,[ebp+24]
+    ; edi could be used to pass an additional argument
+
+    int     48
+   
+	; restore general registers 
+    pop     edi
+    pop     esi
+    pop     edx
+    pop     ecx
+    pop     ebx
+
+    mov     esp,ebp
+    pop     ebp
+    ret
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.c b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.c
new file mode 100644
index 0000000000000000000000000000000000000000..b82bac6712ea069acff175c035251fe6b7db5fb6
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.c
@@ -0,0 +1 @@
+#include "ulibc.h"
diff --git a/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.h b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.h
new file mode 100644
index 0000000000000000000000000000000000000000..22929f58fbba9c24bed0da02c1f262185aeba409
--- /dev/null
+++ b/labs/lab4-tasks_syscalls/skeleton_with_labs1-3/yoctos/user/ulibc.h
@@ -0,0 +1,8 @@
+#ifndef _ULIBC_H_
+#define _ULIBC_H_
+
+#include "common/types.h"
+#include "common/colors.h"
+#include "common/string.h"
+
+#endif