YanaKernel0Aを、C言語(とアセンブリ言語)で実装しています。
とりあえず、MIPSに続いて、ARMについても、サンプルを実行できました。
次のアーカイブ・ファイルは、責任や保証を求めずに、個人的に用いてください。
次のような環境で、サンプルを実行できました。
yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $ CC="arm-elf-gcc -O2" make rm -f *.map *.o echo0 echo1 echo2 echo3 arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o echo 0.o echo0.c arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o star t.o ../common/start.S arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o yk0a _external.o ../common/yk0a_external.S arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o yk0a _core.o ../../../kernel/arm/yk0a_core.c arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o yk0a _glue.o ../../../kernel/arm/yk0a_glue.S ../../../kernel/arm/yk0a_glue.S: Assembler messages: ../../../kernel/arm/yk0a_glue.S:31: Warning: writeback of base register is UNPRE DICTABLE ../../../kernel/arm/yk0a_glue.S:48: Warning: writeback of base register is UNPRE DICTABLE arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o yk0a _internal.o ../../../kernel/arm/yk0a_internal.S arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -Wl,-Map,ech o0.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x00001000 echo0.o start.o yk0a_exter nal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo0 arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o echo 1.o echo1.c arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -Wl,-Map,ech o1.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x00001000 echo1.o start.o yk0a_exter nal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo1 arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o echo 2.o echo2.c arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -Wl,-Map,ech o2.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x00001000 echo2.o start.o yk0a_exter nal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo2 arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -c -o echo 3.o echo3.c arm-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-protot ypes -march=armv4 -mabi=aapcs -I. -I../common -I../../../kernel/arm -Wl,-Map,ech o3.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x00001000 echo3.o start.o yk0a_exter nal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo3 yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $ gxemul -q -Etestarm echo0 NOTE: This is a LEGACY emulation mode. console{c0000000 00000001 200000d7} yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $ gxemul -q -Etestarm echo1 NOTE: This is a LEGACY emulation mode. console{c0000000 00000001 200000db} yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $ gxemul -q -Etestarm echo2 NOTE: This is a LEGACY emulation mode. console{c0000000 00000002 00000000} yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $ gxemul -q -Etestarm echo3 NOTE: This is a LEGACY emulation mode. console{c0000000 00000003 00000000} yana@cygwin ~/yanakernel0ainc/sample/arm/portoff $
次のような環境で、サンプルを実行できました。
yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $ CC="mips-elf-gcc -O2" make rm -f *.map *.o echo0 echo1 echo2 echo3 mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o ec ho0.o echo0.c mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o st art.o ../common/start.S mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o yk 0a_external.o ../common/yk0a_external.S mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o yk 0a_core.o ../../../kernel/mips/yk0a_core.c mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o yk 0a_glue.o ../../../kernel/mips/yk0a_glue.S mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o yk 0a_internal.o ../../../kernel/mips/yk0a_internal.S mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -Wl,-Map,e cho0.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x80001000 echo0.o start.o yk0a_ext ernal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo0 mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o ec ho1.o echo1.c mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -Wl,-Map,e cho1.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x80001000 echo1.o start.o yk0a_ext ernal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo1 mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o ec ho2.o echo2.c mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -Wl,-Map,e cho2.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x80001000 echo2.o start.o yk0a_ext ernal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo2 mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -c -o ec ho3.o echo3.c mips-elf-gcc -O2 -g -ffreestanding -std=c89 -Wall -Wpointer-arith -Wstrict-proto types -march=mips32 -mabi=eabi -I. -I../common -I../../../kernel/mips -Wl,-Map,e cho3.map -Wl,--cref -Wl,-e,start -Wl,-Ttext,0x80001000 echo3.o start.o yk0a_ext ernal.o yk0a_core.o yk0a_glue.o yk0a_internal.o -nostdlib -lgcc -o echo3 yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $ gxemul -q -Eoldtestmips -C4kc echo0 NOTE: This is a LEGACY emulation mode. console{c0000000 00000001 00000010} yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $ gxemul -q -Eoldtestmips -C4kc echo1 NOTE: This is a LEGACY emulation mode. console{c0000000 00000001 00000014} yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $ gxemul -q -Eoldtestmips -C4kc echo2 NOTE: This is a LEGACY emulation mode. console{c0000000 00000002 00000000} yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $ gxemul -q -Eoldtestmips -C4kc echo3 NOTE: This is a LEGACY emulation mode. console{c0000000 00000003 00000000} yana@cygwin ~/yanakernel0ainc/sample/mips/portoff $
まず、この実装では、次のような資源をカーネルの内部で使用しています。
次に、カーネルの内部から外部へのインターフェースは、プロセッサの外部のメモリではなく、プロセッサの内部のレジスタを使用しています。
カーネルの外部から内部へのインターフェースは、プロセッサの内部のレジスタと、ルーチン「yk0a_initialize」とルーチン「yk0a_exception_interrupt_procedure」を使用しています。
ここで、プロセッサについてですが、カーネルの内部と外部で1個のプロセッサを使用しています。
ルーチン「yk0a_initialize」を実行すると、カーネルの内部の処理の後で、カーネルの外部に戻ります。
ルーチン「yk0a_exception_interrupt_procedure」を実行すると、カーネルの内部の処理の後で、実行可能状態のTaskがなければ、割り込みを待ち、実行可能状態のTaskがあれば、カーネルの外部に戻ります。
カーネルの内部の処理時間ということでは、ルーチン「yk0a_initialize」には、マクロ「YK0A_SETUP_PORT_SIZE」に比例する部分と、マクロ「YK0A_SETUP_PRIORITY_SIZE」に比例する部分と、マクロ「YK0A_SETUP_TASK_SIZE」に比例する部分があります。
ルーチン「yk0a_exception_interrupt_procedure」には、マクロ「YK0A_SETUP_PRIORITY_SIZE」に比例する部分(関数「yk0a_schedule_update」)があります。
なお、関数「yk0a_schedule_update」については、マクロ「YK0A_SETUP_PRIORITY_SIZE」でループしていますが、ARMとMIPSの命令「CLZ」などのビット処理に変更できそうです。
また、メモリについてですが、カーネルの内部と外部で共有しているのは、ルーチン「yk0a_initialize」とルーチン「yk0a_exception_interrupt_procedure」を実行する部分だけです。
例えば、カーネルのスタックを、例外ハンドラや割り込みハンドラなどが読み書きすることはありませんし、Taskのスタックを、カーネルが読み書きすることもありません。
カーネルの内部のメモリ容量ということでは、コンパイラなどに依存しますが、使用例を整理しました。
なお、カーネルのスタックについては、再帰や再入などで使用するわけではありませんし、逆アセンブルして、上限を確認しました。
|
.text |
.bss - stack |
stack |
---|---|---|---|
yk0a_exception_forward |
|
|
case0: 8 |
yk0a_interrupt_bit_flag |
|
|
case1: 16 |
yk0a_core_initialize |
|
|
case2: 24 |
yk0a_core_exception_interrupt_procedure |
|
|
case3: 32+max(case0, case1) |
yk0a_core.c |
2824 |
yk0a_interrupt_mask: 4 yk0a_port_control: 16 * YK0A_SETUP_PORT_SIZE yk0a_schedule_link: 4 yk0a_schedule_queue: 8 * YK0A_SETUP_PRIORITY_SIZE yk0a_task_control: 92 * YK0A_SETUP_TASK_SIZE |
max(case2, case3)=48 |
yk0a_glue.S |
128 |
0 |
0 |
|
.text + .rodata |
.sbss + .bss - stack |
stack |
---|---|---|---|
yk0a_exception_forward |
|
|
case0: 0 |
yk0a_interrupt_bit_flag |
|
|
case1: 0 |
yk0a_core_initialize |
|
|
case2: 0 |
yk0a_core_exception_interrupt_procedure |
|
|
case3: 8+max(case0, case1) |
yk0a_core.c |
3080 |
yk0a_port_control: 16 * YK0A_SETUP_PORT_SIZE yk0a_schedule_link: 4 yk0a_schedule_queue: 8 * YK0A_SETUP_PRIORITY_SIZE yk0a_task_control: 156 * YK0A_SETUP_TASK_SIZE |
max(case2, case3)=8 |
yk0a_glue.S |
476 |
0 |
0 |
あと、割り込みコントローラについてですが、ARMの場合は、カーネルの内部と外部で1個の割り込みコントローラを使用しています。
MIPSの場合は、割り込みコントローラを使用していませんが、プロセッサのレジスタ「Status」のフィールド「IM」とレジスタ「Cause」のフィールド「IP」を読み書きしています。
割り込みが発生すると、ルーチン「yk0a_exception_interrupt_procedure」を実行して、カーネルの内部で、割り込みの要求ビットを取得してから、取得したビットで割り込みを無効にして、取得したビットでFlagを設定します。
なお、カーネルの内部で割り込みを無効にするのは、割り込みの発生が続かないようにするためですので、発生した割り込みを無効にするような割り込みコントローラでは、カーネルの内部で割り込みコントローラを読み書きしないように変更できそうです。
(C) 2009-2011 Yana
Direction: Yana
HTML: Yana
Program: Yana
2011-03-11 release 4
2010-03-11 release 3
2009-09-11 release 2
2009-07-11 release 1
2009-05-11 release 0