summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJake Mannens <jake72360@gmail.com>2018-07-25 01:17:39 +1000
committerJake Mannens <jake72360@gmail.com>2018-07-25 01:17:39 +1000
commit45819c035d0b92275de68e559f066cbe50996926 (patch)
tree0ae32cffc4567dee891ecca9e5162731b341d1a0 /include
parenta0aa45ea6f4027dd4080cf1456a2fc5d9e94f87b (diff)
Fixed a bug in switch_to() in which the value of EBX was not popped
prior to return. This meant that switching to the same task did not abort properly as the incorrect return address was popped off the stack. Fixed a bug where the task register was not initialized before the scheduler. This meant that on the first task switch, the CPU would dump it's current state to a random address (0 most likely), potentially corrupting important data. This has been corrected by introducing a 'garbage TSS' (and associated descriptor in the GDT) which is selected before the scheduler is initialized as a safe place for the data to be written. Modified the scheduler so that it now waits indefinitely until a task becomes ready to run. This fixes the possible bug where the scheduler won't re-schedule the currently running task if it is the only task on the system. Add signal handling capabilities to the kernel. The bulk of this is present in the subroutine check_signals() defined in traps.s. This function is called on every timer tick and system call prior to userspace return. The subroutine operates by pushing fake state information onto the kernel's stack, then using it to return to userspace. Prior to this, the subroutine pushes the return address 0xFFFFE000 onto the user's stack. This address corresponds to the unmapped page located between the top of the user's stack (lower) and the kernel's stack page (upper). When the user's signal handler tries to return, it will cause a page fault that will be used as a notification mechanism to inform the kernel that the signal handler is done. The kernel will then switch to the originally pushed state information and use it to return the task to the original execution state. Due to it's nature, check_signals() must only be called prior to exiting the kernel since it may not return. Added the header file 'signal.h' which defines (most) of the POSIX signals as well as the prototype for the signal() function. Added the 'signal' element to the task structure. This field is a bitmap of all currently pending signals. Added the 'sig_handlers' element to the task structure. This is an array of all user-defined signal handlers. Currently, a value of 0 indicates the default handler should be used whilst any other value is considered to be the address of a userspace signal handler. The ability to ignore a signal is not yet present but will be added sometime soon. Added the sys_signal system call to register a signal. Added the stub function sighandler_default() to sched.c which handles all signals not caught by the user.
Diffstat (limited to 'include')
-rw-r--r--include/kernel/sched.h9
-rw-r--r--include/kernel/sys.h3
-rw-r--r--include/signal.h35
-rw-r--r--include/unistd.h1
4 files changed, 47 insertions, 1 deletions
diff --git a/include/kernel/sched.h b/include/kernel/sched.h
index 42b5b15..ac508b9 100644
--- a/include/kernel/sched.h
+++ b/include/kernel/sched.h
@@ -1,6 +1,7 @@
#ifndef _SCHED_H
#define _SCHED_H
+#include <signal.h>
#include <stdint.h>
#include <unistd.h>
@@ -39,9 +40,17 @@ struct tss_struct {
uint32_t io_map;
} __attribute__((packed));
+/*
+ * WARNING: do not modify this structure
+ * unless the offsets defined in traps.s
+ * are updated
+ */
+
struct task_struct {
pid_t pid;
int state;
+ uint32_t signal;
+ void *sig_handlers[NRSIG];
struct tss_struct tss;
} __attribute__((packed));
diff --git a/include/kernel/sys.h b/include/kernel/sys.h
index 248a93b..b2c1b3b 100644
--- a/include/kernel/sys.h
+++ b/include/kernel/sys.h
@@ -4,6 +4,7 @@ extern int sys_puts(void);
extern int sys_time(void);
extern int sys_getpid(void);
extern int sys_getpdir(void);
+extern int sys_signal(void);
extern int sys_dummy(void);
syscall_t call_table[256] = {
@@ -11,7 +12,7 @@ syscall_t call_table[256] = {
[1] = &sys_time,
[2] = &sys_getpid,
[3] = &sys_getpdir,
- [4] = &sys_dummy,
+ [4] = &sys_signal,
[5] = &sys_dummy,
[6] = &sys_dummy,
[7] = &sys_dummy,
diff --git a/include/signal.h b/include/signal.h
new file mode 100644
index 0000000..fee6c2b
--- /dev/null
+++ b/include/signal.h
@@ -0,0 +1,35 @@
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#define NRSIG 32
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGPROF 27
+#define SIGSYS 31
+
+void *signal(int, void (*)(int));
+
+#endif
diff --git a/include/unistd.h b/include/unistd.h
index 6925541..3b144f6 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -9,6 +9,7 @@ typedef uint16_t pid_t;
#define __SYS_time 1
#define __SYS_getpid 2
#define __SYS_getpdir 3
+#define __SYS_signal 4
#define _syscall0(type, name) \
type name(void) { \