[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 ;-)