[ :Yana: Index ]

:Yana:YanaKernel: YanaKernel0A in C (2011-03-11)

概要 (2009-07-11)

YanaKernel0Aを、C言語(とアセンブリ言語)で実装しています。

とりあえず、MIPSに続いて、ARMについても、サンプルを実行できました。

ダウンロード (2011-03-11)

次のアーカイブ・ファイルは、責任や保証を求めずに、個人的に用いてください。

ARMの実行例 (2011-03-11)

次のような環境で、サンプルを実行できました。

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
$

MIPSの実行例 (2011-03-11)

次のような環境で、サンプルを実行できました。

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
$

資源限定 (2011-03-11)

まず、この実装では、次のような資源をカーネルの内部で使用しています。

次に、カーネルの内部から外部へのインターフェースは、プロセッサの外部のメモリではなく、プロセッサの内部のレジスタを使用しています。
カーネルの外部から内部へのインターフェースは、プロセッサの内部のレジスタと、ルーチン「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のスタックを、カーネルが読み書きすることもありません。

カーネルの内部のメモリ容量ということでは、コンパイラなどに依存しますが、使用例を整理しました。
なお、カーネルのスタックについては、再帰や再入などで使用するわけではありませんし、逆アセンブルして、上限を確認しました。

ARMの使用例「CC="arm-elf-gcc -O2" make」

.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
MIPSの使用例「CC="mips-elf-gcc -O2" make」

.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を設定します。
なお、カーネルの内部で割り込みを無効にするのは、割り込みの発生が続かないようにするためですので、発生した割り込みを無効にするような割り込みコントローラでは、カーネルの内部で割り込みコントローラを読み書きしないように変更できそうです。

Credit

(C) 2009-2011 Yana

Direction: Yana
HTML: Yana
Program: Yana

ChangeLog

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

[ :Yana: Index ]
(C) 2009-2011 Yana
このサイトについて