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
|