[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 4/7] kernel2: SYSCALL_PM_INIT_PROC_PARAM_BLOCK
+ kernel2: Syscall, um einem neuen Kindprozess einen
Prozessparameterblock zu uebergeben. Dazu wird Shared Memory in den
Kindprozess gemappt und Pointer, Größe und SHM-ID in Registern
übergeben.
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/include/syscallno.h | 3 +-
src/kernel2/include/mm.h | 3 ++
src/kernel2/include/syscall.h | 4 +++
src/kernel2/src/arch/i386/cpu.c | 20 +++++++++++++++
src/kernel2/src/mm/shm.c | 14 +++++++++++
src/kernel2/src/syscall.c | 1 +
src/kernel2/src/syscalls/pm.c | 36 ++++++++++++++++++++++++++++
src/modules/include/syscall.h | 1 +
src/modules/lib/syscalls/init_child_page.c | 15 +++++++++++
9 files changed, 96 insertions(+), 1 deletions(-)
create mode 100644 src/kernel2/.ignorenobuild
diff --git a/src/include/syscallno.h b/src/include/syscallno.h
index fe2b693..1e156ca 100644
--- a/src/include/syscallno.h
+++ b/src/include/syscallno.h
@@ -45,6 +45,7 @@
#define SYSCALL_PM_CREATE_PROCESS 3
#define SYSCALL_PM_INIT_PAGE 13
#define SYSCALL_PM_INIT_PAGE_COPY 82
+#define SYSCALL_PM_INIT_PROC_PARAM_BLOCK 84
#define SYSCALL_PM_EXIT_PROCESS 5
#define SYSCALL_PM_SLEEP 6
#define SYSCALL_PM_GET_UID 7
@@ -84,6 +85,6 @@
#define SYSCALL_DEBUG_STACKTRACE 80
//ACHTUNG: Muss eine Zahl groesser als die Groesste Syscall-Nummer sein
-#define SYSCALL_MAX 84
+#define SYSCALL_MAX 85
#endif
diff --git a/src/kernel2/.ignorenobuild b/src/kernel2/.ignorenobuild
new file mode 100644
index 0000000..e69de29
diff --git a/src/kernel2/include/mm.h b/src/kernel2/include/mm.h
index 559733c..e72a6cd 100644
--- a/src/kernel2/include/mm.h
+++ b/src/kernel2/include/mm.h
@@ -182,5 +182,8 @@ void* shm_attach(pm_process_t* process, uint32_t id);
/// Shared Memory schliessen.
void shm_detach(pm_process_t* process, uint32_t id);
+/// Gibt die Groesse des SHM-Bereichs in Bytes zurueck
+size_t shm_size(uint32_t id);
+
#endif
diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h
index 9c5fe77..46c3181 100644
--- a/src/kernel2/include/syscall.h
+++ b/src/kernel2/include/syscall.h
@@ -128,6 +128,10 @@ void* syscall_pm_enumerate_tasks(void);
void syscall_init_child_page(pid_t pid, vaddr_t src, vaddr_t dest,
size_t size);
+/// Initialisiert den Prozessparameterblock eines Kindprozesses
+int syscall_init_ppb(pid_t pid, int shm_id);
+int arch_init_ppb(pm_process_t* process, int shm_id, void* ptr, size_t size);
+
/// IO-Ports anfordern
int syscall_io_request_port(uint32_t port, uint32_t length);
diff --git a/src/kernel2/src/arch/i386/cpu.c b/src/kernel2/src/arch/i386/cpu.c
index 1fea672..102c585 100644
--- a/src/kernel2/src/arch/i386/cpu.c
+++ b/src/kernel2/src/arch/i386/cpu.c
@@ -172,3 +172,23 @@ void cpu_prepare_current_task(void)
cpu_get_current()->tss.io_bit_map_offset = TSS_IO_BITMAP_NOT_LOADED;
}
+
+/*
+ * Setzt die Register des ersten Threads des Prozesses, um ihm seinen
+ * Prozessparameterblock bekannt zu machen.
+ *
+ * eax: ID des SHM
+ * ebx: Pointer auf den gemappten SHM
+ * ecx: Groesse des gemappten SHM
+ */
+int arch_init_ppb(pm_process_t* process, int shm_id, void* ptr, size_t size)
+{
+ pm_thread_t* thread = list_get_element_at(process->threads, 0);
+ interrupt_stack_frame_t* user_isf = thread->user_isf;
+
+ user_isf->eax = shm_id;
+ user_isf->ebx = (uintptr_t) ptr;
+ user_isf->ecx = size;
+
+ return 0;
+}
diff --git a/src/kernel2/src/mm/shm.c b/src/kernel2/src/mm/shm.c
index 2df78d6..6d94c52 100644
--- a/src/kernel2/src/mm/shm.c
+++ b/src/kernel2/src/mm/shm.c
@@ -205,6 +205,20 @@ found:
}
/**
+ * Gibt die Groesse des SHM-Bereichs in Bytes zurueck
+ */
+size_t shm_size(uint32_t id)
+{
+ struct shm_desc* shm = tree_search(shms, id);
+
+ if (shm == NULL) {
+ return 0;
+ }
+
+ return shm->num_pages * PAGE_SIZE;
+}
+
+/**
* Schliesst alle SHM-Bereiche eines Prozesses
*/
static void shm_destroy_task(pm_process_t* process, void* prv)
diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c
index 073fe9b..5a4aad4 100644
--- a/src/kernel2/src/syscall.c
+++ b/src/kernel2/src/syscall.c
@@ -70,6 +70,7 @@ void syscall_init()
syscall_register(SYSCALL_PM_CREATE_PROCESS, &syscall_pm_create_process, 4);
syscall_register(SYSCALL_PM_INIT_PAGE, &syscall_init_child_page, 4);
+ syscall_register(SYSCALL_PM_INIT_PROC_PARAM_BLOCK, &syscall_init_ppb, 2);
syscall_register(SYSCALL_PM_EXIT_PROCESS, &syscall_pm_exit_process, 0);
syscall_register(SYSCALL_PM_ENUMERATE_TASKS,
diff --git a/src/kernel2/src/syscalls/pm.c b/src/kernel2/src/syscalls/pm.c
index 0b36df3..e22246a 100644
--- a/src/kernel2/src/syscalls/pm.c
+++ b/src/kernel2/src/syscalls/pm.c
@@ -36,6 +36,7 @@
#include <types.h>
#include <stdint.h>
#include <string.h>
+#include <errno.h>
#include "syscall.h"
#include "syscall_structs.h"
@@ -204,6 +205,41 @@ void syscall_init_child_page(pid_t pid, vaddr_t dest, vaddr_t src, size_t size)
}
/**
+ * Initialisiert den Prozessparameterblock eines Kindprozesses. Dazu wird der
+ * gegebene Shared Memory in den Kindprozess gemappt und dem Kindprozess in den
+ * Registern eax und edx ein Pointer auf den gemappten Bereich bzw. die Laenge
+ * des gemappten Bereichs in Bytes angegeben.
+ *
+ * Dieser Syscall darf nur benutzt werden, solange der Prozess noch nicht
+ * gestartet wurde.
+ */
+int syscall_init_ppb(pid_t pid, int shm_id)
+{
+ pm_process_t* process;
+ void* ptr;
+ size_t size;
+
+ process = pm_get(pid);
+ if (process == NULL) {
+ return -ESRCH;
+ }
+
+ // FIXME Prüfen, dass der Prozess noch nicht laeuft und dass er von
+ // current_process blockiert wird
+
+ /* SHM in den Kindprozess mappen */
+ ptr = shm_attach(process, shm_id);
+ if (ptr == NULL) {
+ return -EINVAL;
+ }
+
+ size = shm_size(shm_id);
+
+ /* Register eintragen */
+ return arch_init_ppb(process, shm_id, ptr, size);
+}
+
+/**
* Die Kontrolle an einen anderen Task abgeben
*
* FIXME Diesen Code gibt es in genau dieser Form auch in im.c
diff --git a/src/modules/include/syscall.h b/src/modules/include/syscall.h
index 7428c91..74ef0be 100644
--- a/src/modules/include/syscall.h
+++ b/src/modules/include/syscall.h
@@ -90,6 +90,7 @@ pid_t create_process(uint32_t initial_eip, uid_t uid, const char* path,
void destroy_process(void);
void init_child_page (pid_t pid, void* dest, void* src, size_t size);
void init_child_page_copy (pid_t pid, void* dest, void* src, size_t size);
+int init_child_ppb(pid_t pid, int shm);
void unblock_process(pid_t pid);
char* get_cmdline(void);
diff --git a/src/modules/lib/syscalls/init_child_page.c b/src/modules/lib/syscalls/init_child_page.c
index 11497c7..43148ce 100644
--- a/src/modules/lib/syscalls/init_child_page.c
+++ b/src/modules/lib/syscalls/init_child_page.c
@@ -55,3 +55,18 @@ void init_child_page_copy (pid_t pid, void* dest, void* src, size_t size)
: : "i" (SYSCALL_PM_INIT_PAGE_COPY), "r"(pid), "r" (dest), "r" (src), "r" (size));
}
+int init_child_ppb(pid_t pid, int shm)
+{
+ int ret;
+
+ asm(
+ "pushl %3;"
+ "pushl %2;"
+ "mov %1, %%eax;"
+ "int $0x30;"
+ "add $0x08, %%esp;"
+ : "=a" (ret)
+ : "i" (SYSCALL_PM_INIT_PROC_PARAM_BLOCK), "r"(pid), "r" (shm));
+
+ return ret;
+}
--
1.6.0.2