2023年8月3日木曜日

UNIX V7のブート 5

 ブートローダの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()に実行が移ります。