Weitere ähnliche Inhalte Ähnlich wie NetBSD/i386 割り込みベクタテーブル (20) Kürzlich hochgeladen (10) NetBSD/i386 割り込みベクタテーブル21. IDTの内容を見る (init386内)
cpu_init_idt() の呼出し元の init386() を見る
src/sys/arch/i386/i386/machdep.c 1497
vi
od
ii36pdrtfrtaal
nt8(ad_ is_vi)
{
..
.
pa_etrp(d_ad,itpdr MPO_EDV_RTWIE )
mpkne_aitvdr d_ad,V_RTRA|MPO_RT,0;
pa_paepa_enl);
mpudt(mpkre()
mme(vi )d_ad,0 AESZ)
est(od*itvdr ,PG_IE;
#fdfXN
ine E
itii(;
d_nt)
it=(tutgt_ecitr*itvdr
d src aedsrpo )d_ad;
pa_etrp(etu_d_ad,itpdr MPO_ED )
mpkne_apnimitvdr d_ad,V_RTRA,0;
pa_paepa_enl);
mpudt(mpkre()
pnimit=(no ecitr*pnimitvdr
etu_d uindsrpo )etu_d_ad;
..
.
pmapに関連する関数が呼ばれている
25. IDTの内容を見る (init386内)
src/sys/arch/i386/i386/machdep.c 1501
vi
od
ii36pdrtfrtaal
nt8(ad_ is_vi)
{
..
.
/
/ 前ページの続き
itii(;
d_nt)
/
/ この関数の中身は空
it=(tutgt_ecitr*itvdr
d src aedsrpo )d_ad;
/
/ さっきマッピングしたアドレスを(キャストして)i t
d 変数に割り当てる
pa_etrp(etu_d_ad,itpdr MPO_ED )
mpkne_apnimitvdr d_ad,V_RTRA,0;
/
/ さっきマッピングした物理アドレス d _ a d ( h s c l
i t p d r p y i a ) を、再度マッピング
/
/ 今度はR a O l 属性
edny
pa_paepa_enl);
mpudt(mpkre()
/
/ 遅延されたマッピングを更新する
pnimit=(no ecitr*pnimitvdr
etu_d uindsrpo )etu_d_ad;
/
/ マッピングしたアドレスを(キャストして)
/ it
/ l d 関数の呼出しでI T
D のベースとして扱われる変数に割り当てる
..
.
IDT中身の設定はReadWrite属性のメモリページから行い、
IDTRにはReadOnly属性のメモリページのアドレスを書いている
26. IDTの内容を見る (init386内)
src/sys/arch/i386/i386/machdep.c 1537
vi
od
ii36pdrtfrtaal
nt8(ad_ is_vi)
{
..
.
/ xetos*
*ecpin /
fr( ;x<3;x+
o x=0 2 +){
itvcrsrex;
d_e_eev()
stae&d[] DVCecpin)x,0 D_Y36G,
egt(itx,ITE(xetos[] ,STSS8IT
( =3| =4 E_P E_P,
x= |x= )?SLUL:SLKL
GE(CD_E,SLKL)
SLGOESL E_P);
}
/ ~ 2 番の例外
/↑03
/ etl nerp aefrssal /
*nwsyeitrutgt o ycls*
itvcrsre18;
d_e_eev(2)
stae&d[2] ITE(ycl) ,STSS8IT E_P,
egt(it18,&DVCssal,0 D_Y36G,SLUL
GE(CD_E,SLKL)
SLGOESL E_P);
/ ↑ 1 8 → これが x 0 !
/ 2 番
08 !
itvcrsre0d)
d_e_eev(x2;
stae&d[x2,&DVCsr_atrp,0 D_Y36G,
egt(it0d] ITE(v4fsta) ,STSS8IT
SLUL SLGOESL E_P);
E_P,GE(CD_E,SLKL)
/↑0d番
/ x2
..
.
c u i i _ d ( ; / ← I T にI T
p _ n t i t ) / D R D のアドレスを書く
idt_vec_reserve(ベクタ番号) → setgate() の流れ
29. IDTの0x80番を見る
src/sys/arch/x86/x86/idt.c 83
/
*
* 与えられた範囲内で、I T
D ベクタを1
スロット割り当てる.
* 初期ブート時のシングルスレッドでなければ、c u
p のロックが行われる.
/
*
it
n
itvcalcitlw n ih
d_e_lo(n o,ithg)
{
itvc
n e;
KSETmtxond&p_ok |!poln)
ASR(ue_we(culc)| m_nie;
fr(e o;vc< ih e+){
o vc=lw e =hg;vc+
i italca[e]= ){
f(d_lompvc =0
/ d_e_re)
* i t v c f e ( はロックしないかもしれないので, m m a する. *
ebr
/
mma_yc)
ebrsn(;
italca[e]=1
d_lompvc ;
/ d _ l o m p v c でスロットの割り当てを管理して、
/↑italca[e]
/ 二重の割当てを避ける
/
rtr e;
eunvc
/
/ ↑ 割り当てたベクタ番号を返す
}
}
rtr ;
eun0
}
30. IDTの0x80番を見る
setgate() を見ます
itvcrsre18;
d_e_eev(2)
stae&d[2] ITE(ycl) ,STSS8IT E_P,
egt(it18,&DVCssal,0 D_Y36G,SLUL
GE(CD_E,SLKL)
SLGOESL E_P);
src/sys/arch/x86/x86/idt.c 1082
vi
od
staesrc aedsrpo g,vi fn,itag,ittp,itdl
egt(tutgt_ecitr*d od*uc n rs n ye n p,
itsl
n e)
{
/
/ 第一引数のi t
d のスロット(ゲート)の構造体に値を入れていく
gg_ofst=(n)uc
d>dlofe itfn;
gg_eetr=sl
d>dslco e;
gg_tcy=ag;
d>dskp rs
gg_x=0
d>dx ;
gg_ye=tp;
d>dtp ye
gg_p p;
d>ddl=dl
gg_ ;
d>dp=1
gg_ifst=(n)uc> 6
d>dhofe itfn >1;
}
src/sys/arch/i386/include/segments.h 229
#eieSTSS8IT 1 / ytm36itrutgt /
dfn D_Y36G 4 *sse 8 nerp ae*
type は 14 (interrupt gate) が指定されている
32. IDTの0x80番を見る
itvcrsre18;
d_e_eev(2)
stae&d[2] ITE(ycl) ,STSS8IT E_P,
egt(it18,&DVCssal,0 D_Y36G,SLUL
GE(CD_E,SLKL)
SLGOESL E_P);
src/sys/arch/i386/i386/machdep.c 1121
#eieITE(ae _CNA(,nm)
dfn DVCnm) _OCTX ae
&IDTVEC(syscall) は &Xsyscall
src/sys/arch/i386/include/segments.h 98
#eieSLUL 3 / srpiieelvl*
dfn E_P *ue rvlg ee /
SEL_UPL はユーザー特権レベル
src/sys/arch/i386/include/segments.h 93,109,304
#eieGE(,) (()< )|r / lblslco /
dfn SLsr (s <3 ) *agoa eetr*
#eieGOESL 1 / enlcd ecitr*
dfn CD_E *Kre oedsrpo /
#eieSLKL 0 / enlpiieelvl*
dfn E_P *kre rvlg ee /
GSEL(GCODE_SEL, SEL_KPL)) はセグメント・セレクタ(次ページで説明)
カーネルのコードセグメントに、カーネル特権レベルを指定してアクセスす
る
35. IDTの0x80番を見る (セグメントについて)
GDTもIDTと同様に初期化を行うが、
GDTの初期化に関係するコードは今回詳しく見ません
src/sys/arch/i386/i386/machdep.c 1158
/ aegtgtsadmmr emns*
*mk d ae n eoysget /
stemn(gtGOESL.d ,0fff D_EEA E_P,1 )
esget&d[CD_E]s,0 xff,STMMR,SLKL ,1;
/↑
/ カーネルのコードセグメントのセット。ベースアドレス 。リミット G y e
0
4Bt
stemn(gtGAASL.d ,0fff D_ERA E_P,1 )
esget&d[DT_E]s,0 xff,STMMW,SLKL ,1;
/↑
/ カーネルのデータセグメントのセット。ベースアドレス 。リミット G y e
0
4Bt
セグメントのベースがゼロなので、
アクセス先のアドレスとセグメントの先頭からのオフセットは同じ値
37. IDTの0x80番を見る
itvcrsre18;
d_e_eev(2)
stae&d[2] ITE(ycl) ,STSS8IT E_P,
egt(it18,&DVCssal,0 D_Y36G,SLUL
GE(CD_E,SLKL)
SLGOESL E_P);
src/sys/arch/x86/x86/idt.c 1082 (再度確認)
vi
od
staesrc aedsrpo g,vi fn,itag,ittp,itdl
egt(tutgt_ecitr*d od*uc n rs n ye n p,
itsl
n e)
{
gg_ofst=(n)uc
d>dlofe itfn;
/
/ セグメント内の下位1 b t
6 i オフセット: X y c l
s s a l の下位アドレス
gg_eetr=sl
d>dslco e;
/
/ セグメント・セレクタ: カーネルのコードセグメント
gg_tcy=ag;
d>dskp rs
/
/ 移動前のスタックから移動後のスタックにコピーするデータサイズ: 0
が入る
gg_x=0
d>dx ;
/
/ 使用されない3 i
bt
gg_ye=tp;
d>dtp ye
/
/ ゲートのタイプ: 割り込みゲート
gg_p p;
d>ddl=dl
/
/ 特権レベル: ユーザー特権レベル
gg_ ;
d>dp=1
/
/ このゲートが存在することを示すフラグ
gg_ifst=(n)uc> 6
d>dhofe itfn >1;
/
/ セグメント内の上位1 b t
6 i オフセット: X y c l の上位アドレス
ssal
}
38. IDTの0x80番を見る
0x80番の設定を見たので、戻ります
src/sys/arch/i386/i386/machdep.c 1537
vi
od
ii36pdrtfrtaal
nt8(ad_ is_vi)
{
..
.
/ xetos*
*ecpin /
fr( ;x<3;x+
o x=0 2 +){
itvcrsrex;
d_e_eev()
stae&d[] DVCecpin)x,0 D_Y36G,
egt(itx,ITE(xetos[] ,STSS8IT
( =3| =4 E_P E_P,
x= |x= )?SLUL:SLKL
GE(CD_E,SLKL)
SLGOESL E_P);
}
/ etl nerp aefrssal /
*nwsyeitrutgt o ycls*
itvcrsre18;
d_e_eev(2)
stae&d[2] ITE(ycl) ,STSS8IT E_P,
egt(it18,&DVCssal,0 D_Y36G,SLUL
GE(CD_E,SLKL)
SLGOESL E_P);
itvcrsre0d)
d_e_eev(x2;
stae&d[x2,&DVCsr_atrp,0 D_Y36G,
egt(it0d] ITE(v4fsta) ,STSS8IT
SLUL SLGOESL E_P);
E_P,GE(CD_E,SLKL)
/
/ ↑ ここまでI T ~ 2
D の0 3 番、0 8 番、0 d 番のゲートを設定
x0
x2
..
.
cuii_d(;
p_ntit)
/
/ ↑ この中で設定したI T
D の先頭アドレスとリミットをI T に書き込む
DR