読者です 読者をやめる 読者になる 読者になる

tramoplineの本体をみてく。

minix

調べているのはここにあるソース。

http://gsd.unex.es/projects/minixsmp/

ソースにコメントがちゃんと書いてあるのでこれを読めば良いのでうれしい。
trampolineは4段階のステップで行われていますよ。

!*===========================================================================*
!*                              init_ap                                      *
!*===========================================================================*
! This is the entry point for second processor (AP) to start executing 
! (the linux trampoline)
! At this point, we are in 16-bit real mode, with no stack
! ip register is 0
! cs points to something like 000xx000h
! ds is unusable due to code relocation from where assembler links to 
!    somewhere like 000xx000h
!
! Actions:
! 1. Mark data area to tell the BSP we are running in real mode
! 2. Read values of many registers to prepare environment to jump
!    into protected mode in same conditions as BSP
! 3. Change to protected mode
! 4. Jump to protected mode trampoline section
!
! NOTE that this code MUST be assembled as 16-bit
! Using C16 (o16+a16) marks, we force the assember to generate 16-bit
!   instructions, but it introduces operand-size modifiers machine code
!   (bytes 66h and 67h before each instruction) because when in 32-bit 
!   protected mode, 66h & 67h force the cpu to interpret next instruction 
!   as 16-bit. But when in 16-bit real mode, 66h & 67h force the cpu to 
!   execute next instruction as 32-bit. So we need to delete these marks from
!   trampoline code. As trampoline must be relocated to an address 
!   4Kb-page-aligned, then the marks must be replaced by <nop> code (90h)
!

それでは、ソースを見ていくと・・・

.sect .data
.align  16

#define C16             o16 a16

_init_ap:
        C16     jmp     _skip_data
_data_area:                             ! Space for variables
_gdtr_data:     .data2  0x0000          !   gdt limit
                .data4  0x00000000      !       addr
_idtr_data:     .data2  0x0000          !   idt limit
                .data4  0x00000000      !       addr
_esi_data:      .data4  0x00000000      !   esi
_edi_data:      .data4  0x00000000      !   edi
_ebp_data:      .data4  0x00000000      !   ebp
_skip_data:

コードの最初のほうは定数定義していて、jmpの処理は定数定義部分を飛ばしてコードの本体にジャンプするためのもの。

        ! Mark life_flag to tell BSP we are running
        C16     cli                     ! safe from interrupts
        C16     mov     ax,     cs
        C16     mov     ds,     ax      ! ds= cs (_init_ap)

最初のステップは「1. Mark data area to tell the BSP we are running in real mode」の部分で、
cliで割り込みを禁止して、csレジスタの内容をaxレジスタを経由して、dsレジスタにコピー。
そうすると、コメントにあるようにds==csになる。

        ! Prepare environment to jump into protected mode
        C16     lgdt    ( [ TR_GDTR_OFFSET ] )
        C16     lidt    ( [ TR_IDTR_OFFSET ] )

2ステップ目はプロテクトモードに移行する準備としてgdtとidtの設定をする。

/* Offsets from trampoline start to data areas */
#define TR_GDTR_OFFSET          _gdtr_data - _init_ap
#define TR_IDTR_OFFSET          _idtr_data - _init_ap

TR_XXXXはxmp.hで定義しているマクロで、gdtrとかidtrのアドレスを計算。
そして、lgdt、lidt命令でgdt、idtの設定をする。

3ステップ目でcpuのcr0レジスタの最下位ビットを1にしてプロテクトモードに移行する。
この辺はx86アーキテクチャカーネルに興味のある人には馴染みの処理かと・・

        ! Into protected mode
                mov     eax,    cr0
                orb     al,     1
                mov     cr0,    eax

最後の4ステップ目はjmpf命令使ってプロテクトモードで続きの処理を行っていく。

        ! Far jmp to start with 32 bit execution.
        ! Jump to a .text CS-addressed point
        C16     jmpf    CS_SELECTOR:_trampoline_pm
_end_init_ap:
        hlt

jmpfで飛ぶところは_trampoline_pmでこいつも、toramplineと同じくxmp.sに存在。
_trampoline_pmの主要な処理はプロテクトモード下で動くための設定(スタックとかTSSとか)をして、mp.cにいるap_main()を呼び出す。
詳細は次回見ていく。