From: Henry N. <Hen...@Ar...> - 2006-09-07 08:16:36
|
Hello Anders, last weeks I have read and grep into Linux kernels, and read all changes between vanilla kernel 2.6.15 and 2.6.17, with my eyes on the file arch/i386/kernel/cpu/common.c I no found a running way behind yours 2.6.15 Please see this boot functions flow, I will comment now: --- view this flow with fixed font --- inside Kernel: c010cde0 <co_start>: call co_start_arch (label for first switch from windows) call co_early_cpu_init (setup a GDT) call co_start_kernel (kernel/cooperative.c) loads Parameters from passage page call co_arch_start_kernel call co_startup_entry (i386/kernel/head.S, skip behind "setup_idt()", loads gdt,lgt,idt ) call start_kernel (init/main.c) boot_cpu_init page_address_init printk(linux_banner) call setup_arch (arch/i386/kernel/setup.c) pre_setup_arch_hook early_cpu_init cpu_init setup_memory paging_init register_memory (!colinux) setup_per_cpu_areas co_terminate(CO_TERMINATE_END) --- end flow --- 1. The main problem is the function "co_early_cpu_init()" (arch/i386/kernel/cooperative.c). This function sets the GDT and some more memory registers to exact the same GTD, that later will be used in function "cpu_init()" (arch/i386/kernel/cpu/common.c). 2. Function "co_early_cpu_init()" has no support for memory alloc, you can not use printk. You can not use alloc_bootmem_pages, and not get_zeroed_page, but kernel >= 2.6.16 needs this. 3. The GDT must be set on this place, because the function "co_start_kernel()" use memory pointers to get the boot parameter values from the passage memory. 4. The ugly thing: On "co_startup_entry" (arch/i386/kernel/head.S) the GDT will be replace with a fixed GDT from unchangable code "cpu_gdt_table" in the assmbler booting steps. 5. Some there, the memory mappings will be configured. 6. Then function "cpu_init()" (arch/i386/kernel/cpu/common.c) sets the GDT to linux variable area and task structs. Memory alloc and printk is usable. With the change on 2.6.16, the memory behind GDT is an allocatable page. We can not alloc it in function "co_early_cpu_init()". Can not give the same GDT in fuction "co_early_cpu_init()" and "cpu_init()". My ideas: Remove the function "co_early_cpu_init()" from C source. Starts colinux (first from boot) directly some there in the head.S, near the label "co_startup_entry". Remove the function "co_start_kernel()" (kernel/cooperative.c), modify directly such values in head.S from dolinux-daemon.exe on loading the kernel. OR: Code parameters directly in some registers. All registers are free. Only one register is used for the passage page number. Variables they needs are co_core_end, co_memory_size, co_initrd, co_initrd_size, and command line. This should be a struct on one label in head.S colinux-daemon should set the values. A sample for using, is the label "cpu_gdt_table". OR: Call "co_start_kernel()" before call "start_kernel()" from head.S OR: Why not inside head.S use "co_passage_page->params[0] ... [10+256]" and copy the value to struct with elements "co_core_end, co_memory_size, ... co_boot_parameters"? See near entry "startup_32" in head.S, it's coping the string "saved_command_line" from a real memory page. "co_passage_page" is a fixed virtual adress (inside kernel). Best way would be, if we can enter "startup_32" as booting. For this all registers should be set as lilo/grub does it. Perhaps, we need some very small patches on this assembler code. The "startup_32" will be jumped from arch/i386/boot/setup.S, this shows some notes about booting. In the end we would have also a more linux boot and perhaps more opened to use more as 1GB memory. -- Henry Nestler |