[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Lost] [Patch] kernel2: Multiboot-Module an init uebergeben
+ kernel: Multiboot-Module an init uebergeben
Index: trunk/src/include/arch/i386/page.h
===================================================================
--- trunk.orig/src/include/arch/i386/page.h
+++ trunk/src/include/arch/i386/page.h
@@ -57,7 +57,7 @@
#define USER_MEM_START 0x40000000
#define USER_MEM_END 0xffffffff
-#define USER_STACK_START USER_MEM_END
+#define USER_STACK_START 0
#define USER_STACK_SIZE 0x1000
Index: trunk/src/kernel2/include/arch/i386/mm_arch.h
===================================================================
--- trunk.orig/src/kernel2/include/arch/i386/mm_arch.h
+++ trunk/src/kernel2/include/arch/i386/mm_arch.h
@@ -78,4 +78,7 @@ typedef enum { page_4K, page_4M } page_s
#define MM_FLAGS_NO_CACHE (PTE_PCT)
+#define MM_USER_START 0x40000000
+#define MM_USER_END 0xFFFFFFFF
+
#endif
Index: trunk/src/kernel2/src/tasks/modules.c
===================================================================
--- trunk.orig/src/kernel2/src/tasks/modules.c
+++ trunk/src/kernel2/src/tasks/modules.c
@@ -48,6 +48,8 @@
static void load_module(struct multiboot_module* multiboot_module);
+static pm_process_t* init_process;
+
/**
* Das Init-Modul laden. Dieses Modul ist dafuer verantwortlich, die restlichen
* Module zu laden.
@@ -104,7 +106,7 @@ static void load_module(struct multiboot
multiboot_module_mapped->start, image_size);
//load_module_bin(multiboot_module_mapped, cmdline);
- pm_process_t* init_process = pm_create(cmdline);
+ init_process = pm_create(cmdline);
if (loader_load_image(init_process->pid, (vaddr_t) image_start, image_size)
== FALSE)
{
@@ -116,6 +118,120 @@ static void load_module(struct multiboot
pmm_free((vaddr_t) multiboot_module_mapped->start, NUM_PAGES(image_size));
}
+/**
+ * Hier werden die anderen Module an init weitergeleitet
+ *
+ * @param elf_header Pointer auf den ELF-Header
+ */
+void load_multiboot_modules(struct multiboot_info* multiboot_info)
+{
+ int i;
+ struct multiboot_module* multiboot_module_phys;
+ struct multiboot_module* multiboot_module;
+
+ if (multiboot_info->mi_mods_count == 0)
+ {
+ panic("Keine Multiboot-Module zu laden.");
+ }
+ else
+ {
+ multiboot_module_phys = (void*) multiboot_info->mi_mods_addr;
+
+ // Speicher für die Modulparameter
+ char* mod_cmdline_page = pmm_alloc(1);
+ void* mod_cmdline_task = mmc_automap(
+ &init_process->context, mod_cmdline_page, 1,
+ MM_USER_START, MM_USER_END, MM_FLAGS_USER_DATA);
+
+ mod_cmdline_page = vmm_kernel_automap(mod_cmdline_page, PAGE_SIZE);
+ char* mod_cmdline = mod_cmdline_page;
+ size_t mod_cmdline_free = PAGE_SIZE;
+
+ // Speicher für die Modulliste
+ void* mod_list_phys = pmm_alloc(1);
+ void* mod_list_task = mmc_automap(
+ &init_process->context, mod_list_phys, 1,
+ MM_USER_START, MM_USER_END, MM_FLAGS_USER_DATA);
+
+ dword* modulelist = vmm_kernel_automap(mod_list_phys, PAGE_SIZE);
+
+ // Stack von init mappen und Pointer auf die Modulliste uebergeben
+ dword* stack = vmm_kernel_automap(
+ mmc_resolve(&init_process->context,
+ (vaddr_t) USER_STACK_START - PAGE_SIZE),
+ PAGE_SIZE);
+
+ stack[1023] = (dword) mod_list_task;
+ vmm_kernel_unmap(stack, PAGE_SIZE);
+
+ // esp von init entsprechend anpassen
+ pm_thread_t* init_thread = (pm_thread_t*)
+ list_get_element_at(init_process->threads, 0);
+
+ interrupt_stack_frame_t* init_isf = (interrupt_stack_frame_t*)
+ init_thread->kernel_stack;
+
+ init_isf->esp -= 8;
+
+ // Das unterste dword auf der Page mit der Liste beinhaltet die
+ // Anzahl der Module
+ modulelist[0] = multiboot_info->mi_mods_count;
+
+ // Module in den Adressraum von init mappen
+ for (i = 0; i < multiboot_info->mi_mods_count; i++)
+ {
+ //Die multiboot_module struct des aktuellen Moduls mappen
+ multiboot_module = vmm_kernel_automap(
+ (paddr_t)multiboot_module_phys,
+ sizeof(multiboot_module));
+
+ // Anzahl der benoetigten Pages berechnen
+ size_t pages = NUM_PAGES(
+ PAGE_ALIGN_ROUND_UP((dword) multiboot_module->end)
+ - PAGE_ALIGN_ROUND_DOWN((dword) multiboot_module->start));
+
+ // Freie virtuelle Adresse suchen um das Modul dort hin zu mappen.
+ void* dest = mmc_automap(
+ &init_process->context,
+ (paddr_t) multiboot_module->start, pages,
+ MM_USER_START, MM_USER_END, MM_FLAGS_USER_DATA);
+
+ //first_task->memory_used += pages * 0x1000;
+
+ // TODO: Den Speicher aus dem Kerneladressraum unmappen
+
+ // Die Adresse in die Modulliste von Init schreiben
+ modulelist[1 + (3*i)] = (dword) dest;
+ modulelist[2 + (3*i)] = multiboot_module->end - multiboot_module->start;
+ modulelist[3 + (3*i)] = (dword) mod_cmdline_task + (mod_cmdline - mod_cmdline_page);
+
+ // Modulbefehlszeile kopieren
+ char* cmdline = vmm_kernel_automap(
+ (paddr_t) multiboot_module->cmdline, PAGE_SIZE);
+
+ size_t length = strlen(cmdline);
+ if (mod_cmdline_free > length) {
+ strncpy(mod_cmdline, cmdline, length);
+ mod_cmdline[length] = '\0';
+ mod_cmdline += (length + 1);
+ mod_cmdline_free -= (length + 1);
+ }
+ vmm_kernel_unmap(cmdline, PAGE_SIZE);
+
+ // multiboot_module struct wieder freigeben
+ vmm_kernel_unmap(multiboot_module, sizeof(multiboot_module));
+
+ // Physikalische Adresse der multiboot_module struct auf die naechste setzen
+ multiboot_module_phys++;
+ }
+
+ // Die temporaer gemapte Modulliste wieder freigeben (nur hier im Kernel freigeben)
+ vmm_kernel_unmap(modulelist, PAGE_SIZE);
+ vmm_kernel_unmap(mod_cmdline_page, PAGE_SIZE);
+ }
+
+ //TODO: Muessen noch irgendwelche Multiboot-Structs physikalisch freigegeben werden?
+}
/*##############################
* Hilfsfunktionen => loader.h #
Index: trunk/src/kernel2/include/tasks.h
===================================================================
--- trunk.orig/src/kernel2/include/tasks.h
+++ trunk/src/kernel2/include/tasks.h
@@ -167,5 +167,8 @@ void pm_scheduler_push(pm_thread_t* thre
/// Das Init-Modul laden
void load_init_module(struct multiboot_info* multiboot_info);
+/// Alle weiteren Module an init uebergeben
+void load_multiboot_modules(struct multiboot_info* multiboot_info);
+
#endif //ifndef _TASKS_H_
Index: trunk/src/kernel2/src/init.c
===================================================================
--- trunk.orig/src/kernel2/src/init.c
+++ trunk/src/kernel2/src/init.c
@@ -199,6 +199,9 @@ void init(int multiboot_magic, struct mu
// Init-Modul laden
load_init_module(&multiboot_info);
+ // Alle weiteren Module an init uebergeben
+ load_multiboot_modules(&multiboot_info);
+
// Sobald alle CPUs angekommen sind, gehts los!
// TODO: Timeout?
while (final_cpus_arrived < cpu_count) asm("nop");
Index: trunk/src/kernel2/src/tasks/thread.c
===================================================================
--- trunk.orig/src/kernel2/src/tasks/thread.c
+++ trunk/src/kernel2/src/tasks/thread.c
@@ -106,9 +106,9 @@ pm_thread_t* pm_thread_create(pm_process
// Page fuer den Userspace-Stack allozieren
paddr_t stack_phys = pmm_alloc(NUM_PAGES(USER_STACK_SIZE));
- mmc_map(&process->context, (vaddr_t) (isf->esp - USER_STACK_SIZE +
- 1), stack_phys, MM_FLAGS_USER_DATA, NUM_PAGES(USER_STACK_SIZE));
-
+ mmc_map(&process->context, (vaddr_t) (isf->esp - USER_STACK_SIZE),
+ stack_phys, MM_FLAGS_USER_DATA, NUM_PAGES(USER_STACK_SIZE));
+
// Thread in die Liste aufnehmen, und beim Scheduler regisrieren
list_push(process->threads, thread);