[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Lost] [Patch] kernel2: Multiboot-Module an init uebergeben
Am Montag, 9. Juni 2008 23.15:04 schrieb kevin@xxxxxxxxxx:
> + kernel: Multiboot-Module an init uebergeben
> 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;
Hier hätte ich lieber ein PAGESIZE/sizeof(dword) ;-)
Ich fürchte das wird so nicht funktionieren mit AMD64, aus 2 Gründen:
- Die dwords
- Nach dem AMD64-Abi müsste dieser Parameter wohl in rdi übergeben werden,
wenn ich mich richti erinnere.
Aber jo, mit AMD64 ist da eh noch einiges kaputt. ;-)
> + 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 #
Aber das wird wohl nicht das einzige Problem sein, bezüglich Portabilität.
Ausserdem passt das ganze nicht zu unserer imaginären doc/codestyle.txt ;-)