川の流れのように‥(Eiji Ota's Weblog)
火曜日 6 14, 2005
祝OpenSolaris:誕生おめでとう!
Solaris Nucleus処理の解説 (SPARC版)
今日はOpenSolarisの誕生日! v(^-^)/ 待ちに待った(?)日です。生まれたばかりのOpenSolarisは、まだまだヨチヨチの赤ん坊。皆さん、暖かいご支援を期待したいです!
さて、いよいよソースコード[1]もどうどうと皆さんの前にさらけ出しても、なんらお叱りを受けることもなくなりましたね。一つ一つ手かせ足かせが取れていくようで、嬉しい限りです。
今日は、これからOpenSolarisをやろうという人のため、今までとはうって変わって、真面目に実装の解説をすることにしました。(といっても、今までも、それなりに真面目のつもりだったんですが‥ (^^;)
そして今日の解説は、迷いもなく(^-^;)、Solarisの心臓部Nucleus[2]。(じゃじゃーーん)
どのOSもException/Interruptを処理して初めてOSと呼べると思うのですが、(←単に持論です、無視して頂いてかまいませんです。はい^-^) Solaris Operating Systemでは、Exception/Interruptを処理するtrapレベルのコードをnucleusと呼んだりします。このnucleusというのは、SPARC v9アーキテクチャ[3]で定義されている言葉なんですが、ちょっと説明しますね。
SPARC V9では、MMUのコンテキストとして、次の3つをサポートできることになっています。
- Primaryコンテキスト
- Secondaryコンテキスト
- Nucleusコンテキスト
このうち、最初のPrimaryコンテキストとSecondaryコンテキストは必須です。幸い(?)なことに、SunのUltraSPARCシリーズと富士通のSPARC64[4]では、Nucleusコンテキストをサポートしていますので、ここで解説するお話は、双方のSPARC V9アーキのCPUに当てはまりますね!。
Solaris Operating System(面倒なので、以下は、Solaris OSと略記しちゃいます)では、trapを処理する部分[5]はusr/src/uts/sun4u/ml/trap_table.sです。
でもちょっと待って下さいね。SPARC用のtrap_table.sを読む前に、SPARC V9特有のNested Trapについて知っておかないといけませんよぉ。
Nested Trapというのは、Exception/Interruptを処理している最中でも、trap、Exceptionなどの処理をできる仕組みをいいます。
つまり、trap処理であっても、trapがdisableされていない - enable状態になっているということなんですね。これを処理するために、CPUでは、trap stackを実装する必要がありますが、何段まで実装するかというのは、CPUの実装依存になっています。
では、UltraSPARCではどうなっているんでしょう?
1222 /* 1223 * ======================================================================= 1224 * SPARC V9 TRAP TABLE 1225 * 1226 * The trap table is divided into two halves: the first half is used when 1227 * taking traps when TL=0; the second half is used when taking traps from 1228 * TL>0. Note that handlers in the second half of the table might not be able 1229 * to make the same assumptions as handlers in the first half of the table. 1230 * 1231 * Worst case trap nesting so far: 1232 * 1233 * at TL=0 client issues software trap requesting service 1234 * at TL=1 nucleus wants a register window 1235 * at TL=2 register window clean/spill/fill takes a TLB miss 1236 * at TL=3 processing TLB miss 1237 * at TL=4 handle asynchronous error 1238 * 1239 * Note that a trap from TL=4 to TL=5 places Spitfire in "RED mode". 1240 * 1241 * ======================================================================= 1242 */上のコメントを読みますと、UltraSPARCは5段の深さを持っていることが分かりますね。何段であるかはCPUの実装依存なんですけれど、カーネルを移植するためには重要な意味を持っています。
ここで、TL=0というのが通常のカーネル/ユーザモードです。そして、例外や割り込みが発生すると、TLレベルが1つあがって、TL=1となります。そして、この時にコンテキストがNucleusコンテキストに切り替わります。Nested Trapの場合は、この状態でも更に例外などを受け付けることができ、上のコメントにありますように、window fill/spillトラップ、MMUトラップなどを受け付けることができます。
ですけれど、stackには限りがありますよね。永遠にtrapを受け付けることはできませんので、上限にぶつかってしまった場合は、REDモード[6]と呼ばれる特別なモードに入ります。REDモードは、異常処理を扱うモードで、通常はここに入ることはありませんけれど。(でも、バグっていると、すんなり(^-^;)入ります)
さて、SPARC V9用のtrap tableですが、実装では、TL = 0の時と、TL > 0の時の2つの表に分割されます。TL = 0用(通常のtrap処理用)は、trap_table0でスタートする表で、TL > 0用 (nested trap用)は、trap_table1でスタートする表です。ソースでは、次のようになっています。
TL = 0用(通常のtrap処理用)
1250 trap_table0: 1251 /* hardware traps */ 1252 NOT; /* 000 reserved */ 1253 RED; /* 001 power on reset */ 1254 RED; /* 002 watchdog reset */ 1255 RED; /* 003 externally initiated reset */ 1256 RED; /* 004 software initiated reset */ 1257 RED; /* 005 red mode exception */ 1258 NOT; NOT; /* 006 - 007 reserved */ 1259 IMMU_EXCEPTION; /* 008 instruction access exception */ 1260 NOT; /* 009 instruction access MMU miss */ 1261 ASYNC_TRAP(T_INSTR_ERROR, trace_gen); 1262 /* 00A instruction access error */ 1263 NOT; NOT4; /* 00B - 00F reserved */ 1264 ILLTRAP_INSTR; /* 010 illegal instruction */ 1265 TRAP(T_PRIV_INSTR); /* 011 privileged opcode */ 1266 NOT; /* 012 unimplemented LDD */
TL > 0用 (nested trap用)
1412 trap_table1: 1413 NOT4; NOT4; NOT; NOT; /* 000 - 009 unused */ 1414 ASYNC_TRAP(T_INSTR_ERROR + T_TL1, trace_gen); 1415 /* 00A instruction access error */ 1416 NOT; NOT4; /* 00B - 00F unused */ 1417 NOT4; NOT4; NOT4; NOT4; /* 010 - 01F unused */ 1418 NOT4; /* 020 - 023 unused */ 1419 CLEAN_WINDOW; /* 024 - 027 clean window */ 1420 NOT4; NOT4; /* 028 - 02F unused */ 1421 DMMU_EXCEPTION_TL1; /* 030 data access exception */ 1422 NOT; /* 031 unused */ 1423 ASYNC_TRAP(T_DATA_ERROR + T_TL1, trace_gen); 1424 /* 032 data access error */ 1425 NOT; /* 033 unused */ 1426 MISALIGN_ADDR_TL1; /* 034 mem address not aligned */ 1427 NOT; NOT; NOT; NOT4; NOT4 /* 035 - 03F unused */ 1428 NOT4; NOT4; NOT4; NOT4; /* 040 - 04F unused */ 1429 NOT4; NOT4; NOT4; NOT4; /* 050 - 05F unused */ 1430 NOT; /* 060 unused */
同じような表が2つあることが見て取れますね。右に書かれている数字がトラップ番号で、該当するトラップが発生した時に処理するルーチンがこの表で定義されているわけですね。例えば、TL = 0の表でトラップ番号008を見ますとinstruction access exceptionが発生した時に、IMMU_EXCEPTIONが実行される、というように分かりますよね。
Solaris OSのTrap処理を理解するには、まずこのtrap_table.sを理解するのが第一歩ですけれど、これからポツリポツリとSolarisの実装について(つまみ食い)解説していくつもり(今のところ‥^.^;)ですのでお楽しみに!
1. 一応、ライセンスがついているようです。(^-^;)
2. サンに来る前に働いていた富士通のプライムパワー用のSolarisで最初にいじったところです。その時はプライムパワー用のSolaris RAS処理を実装しました。
3. The SPARC Architecture manual (SPARC International, Inc) ISBN: 0-13-099227-5を参照して下さいね。
4. SPARC64-III, -IV, -V(Vはちょっとだけ)知っています。しっかりした、いいCPUだと個人的には思っています。サンも富士通も好きなので、サンと富士通が仲良くできてとても嬉しいです。APL、可愛がってね。
5. 個人的な好みでは、trap処理のようなlowレベルのコードが大好きです。
6. REDモードは、SPARCv9のスペック策定の時、富士通側の要望により入ったものだと、当時一緒に働いていた富士通のHWのエンジニアの方から教わりました。
Technorati Tag: OpenSolaris
Technorati Tag: Solaris
Posted at 01:23午後 6 14, 2005 by eota in kernel | Comments[0]
Comments: