ブートローダの2段目は、C言語とアセンブリ言語で書かれたbootで、そのソースコードは、/usr/src/cmd/standaloneにあります。M.sにあるstartから実行が開始され、MMUの設定とコードの移動が行われたのち、C言語でかかれたmain()に実行が移ります。
/ set kernel I+D to physical 0 and IO page clr r1 ! start from 0x00000 mov $77406,r2 ! 127 blocks R/W mov $KISA0,r3 mov $KISD0,r4 jsr pc,setseg mov $IO,-(r3) clr r1 mov $KDSA0,r3 mov $KDSD0,r4 jsr pc,setseg mov $IO,-(r3) / set user I+D to physical 64K (words) and IO page mov $4000,r1 ! start from 0x20000 mov $UISA0,r3 mov $UISD0,r4 jsr pc,setseg mov $IO,-(r3) mov $4000,r1 mov $UDSA0,r3 mov $UDSD0,r4 jsr pc,setseg mov $IO,-(r3) / enable map mov $65,SSR3 / 22-bit map ! Split I+D for Kernel and User bit $20,SSR3 beq 1f ! Check if 22-bit actived mov $3,MSCR 1: mov $30340,PS inc SSR0 ! Enable MMU
ブートローダは、1-24行でカーネルとユーザのIとD空間用にMMUを設定したのち、MMUを有効にします。この段階ではブートローダは カーネルモードで実行されているので、PSWを現在カーネル、以前をユーザに32行で設定しています。
このままでは、ローダ自身がじゃまでUNIXカーネルを読み込めないので、ユーザ空間に移動させます。
/ copy program to user I space mov $_end,r0 asr r0 clr r1 1: mov (r1),-(sp) mtpi (r1)+ sob r0,1b / continue execution in user space copy mov $140004,sp ! 0xc004 clr *$KDSA6 mov $140340,-(sp) ! PSW:0b1100000011100000 mov $user,-(sp) ! Return address rtt ! Return from trap
7行目のmtpi命令は、以前いたモードのI空間にデータをスタック経由でデータを書き込みます。繰り返し命令を使って、カーネルモードから以前のユーザモードのI空間にローダのコードがコピーされます。
14-16行目は、スタックにカーネルからユーザモードに戻るようなPSWと、userのアドレスを積み、rtt命令でトラップからの復帰を装ってモード切替とジャンプを実行しています。
この後は、C言語で書かれた main()に実行が移ります。
0 件のコメント:
コメントを投稿