ブートローダの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 trap7行目のmtpi命令は、以前いたモードのI空間にデータをスタック経由でデータを書き込みます。繰り返し命令を使って、カーネルモードから以前のユーザモードのI空間にローダのコードがコピーされます。
14-16行目は、スタックにカーネルからユーザモードに戻るようなPSWと、userのアドレスを積み、rtt命令でトラップからの復帰を装ってモード切替とジャンプを実行しています。
この後は、C言語で書かれた main()に実行が移ります。
0 件のコメント:
コメントを投稿