SlideShare a Scribd company logo
cdev_write() / comwrite()
        スタート低レイヤー #5  #start_printf

                   @kusabanachi
cdev_write()
cdev_write

cdev(キャラクタデバイス)にwriteする関数
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;
  n v plg
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO
 
  DVLC()
  E_OKd;
  r  *­dwie(e,uo lg;
  v=(d>_rt)dv i,fa)
  DVULC()
  E_NOKd;
 
  rtr v
  eunr;
}
cdev_write

引数について
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)

dev: デバイス番号
tpdfun6_  dvt   / eienme /
yee it4t  e_;   *dvc ubr*

uio: writeするデータのアドレス、サイズなど
flag: writeに関するフラグ
(追記、ブロック無し、同期、バッファリング無しなど)
cdev_write

まず、cdevswを取得する
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;
  n v plg
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO

DRIVER(9) より

もしドライバがユーザーランドからアクセスできるキャラクタデバイス・
インタフェースを持つなら、
ドライバはcdev_sw構造体を定義しなければならない。
cdev_write

/
*
  hrce eiesic al
*Caatrdvc wthtbe
 /
*
src dvw{
tutces 
  it    (doe)dvt n,it tutlp*;
  n     *_pn(e_,it n,src w )
  it    (dcoe(e_,it n,src w )
  n     *_ls)dvt n,it tutlp*;
  it    (dra)dvt tutuo* n)
  n     *_ed(e_,src i ,it;
  it    (dwie(e_,src i ,it;
  n     *_rt)dvt tutuo* n)
  it    (dicl(e_,uln,vi ,it tutlp*;
  n     *_ot)dvt _og od* n,src w )
  vi    (dso)src t ,it;
  od    *_tp(tutty* n)
  src t   (dty(e_)
  tutty*  *_t)dvt;
  it    (dpl)dvt n,src w )
  n     *_ol(e_,it tutlp*;
  pdrt  (dma)dvt f_,it;
  ad_   *_mp(e_,oft n)
  it    (dkfle)dvt tutkoe*;
  n     *_qitr(e_,src nt )
  it    dfa;
  n     _lg
}
;

cdevswは、キャラクタデバイスへのアクセス用のテーブル
cdev_write -> cdevsw_lookup

cdevswを取得するため、cdevsw_lookup() を呼ぶ
/
*
  
* 番号からキャラクタデバイスを検索する
 
*
    > 呼出し元はデバイスが接続されていることを確認しなければならない
*= 
 /
*
cntsrc dvw*
os tutces 
ces_okpdvtdv
dvwlou(e_ e)
{
    d v a o _   m j r                 / d v a o _ はi t 2 t y e e
    e m j r t c a o ;               /   e m j r t n 3 _ のt p d f
 
  i dv= OE)        /#eieNDV (e_)1
  f(e =NDV        / dfn OE (dvt­)
    rtr NL)
    eun(UL;
    c a o     a o ( e )               / メジャー番号(デバイスの種類)取得
  mjr=mjrdv;      / 
  i cao   |cao =mxcess
  f(mjr<0| mjr> a_dvw)
    rtr NL)
    eun(UL;
 
    r t r   c e s [ m j r )           / c e s 配列の要素を返す
  eun(dvwcao];    / dvw
}
#eiemjrx  (dvao_)(un3_)x  x0ff0 > )
dfn ao()  (emjrt((it2t()&000f0)> 8)
cdev_write -> cdevsw_lookup

今回の出力先はシリアルコンソール。デバイス名はtty00。
#l l/e  rpty09
 s­ dv|ge t[­]
cw­­­ 1ro ty    8     e 21:8ty0
r­­­­  ot t     ,   0Fb2 31 t0
cw­­­ 1uc wel   8     e 12:8ty1
r­­­­  up he    ,   1Fb  23 t0
cw­­­ 1uc wel   8     u 0 03ty2
r­­­­  up he    ,   2Jn3 21 t0
cw­­­ 1uc wel   8     u 0 03ty3
r­­­­  up he    ,   3Jn3 21 t0

メジャー番号8。マイナー番号0。
cdev_write -> cdevsw_lookup

cntsrc dvw*dvw[  
os tutces ces0]={
  &osces,
  cn_dvw
  &tyces,
  ct_dvw
  &e_dvw
  mmces,
  &dces,
  w_dvw
  &wpces,
  sa_dvw
  &t_dvw
  psces,
  &t_dvw
  pcces,
  &o_dvw
  lgces,
  &o_dvw
  cmces,
  &dces,
  f_dvw
..
.
}
;
 
cntsrc dvw*ces  dvw;
os tutces *dvw=ces0

cdevsw[cmajor]は、cmajorが8なので、&com_cdevswになる。
cdev_write -> cdevsw_lookup

com_cdevswはシリアルポート用のcdevsw
cntsrc dvwcmces  
os tutces o_dvw={
  cmpn ocoe ora,cmrt,cmot,
  ooe,cmls,cmed owie oicl
  cmtp oty opl,nma,tyqitr _T
  oso,cmt,cmol omp tkfle,DTY
}
;

COM(4) より
com — serial communications interface for RS-232C
cdev_write

元の関数に戻って
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;
  n v plg
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO
  /  
    / ↑ シリアルのc e s 取得
dvw
..
.
#eieEXO   6   / eientcniue /
dfn NI        *Dvc o ofgrd*

cdevsw_lookup()は、 devのメジャー番号を元に、シリアルポートのアクセス
用のテーブル(com_cdevsw)を取得する関数でした
cdev_write

取得したcdevswのwrite関数を、ロックしてからコールする。
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;         /mfa 
    n   v   p l g                   /   p l g に注目
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO
  /  
    / ↑ シリアルのc e s 取得
dvw
 
  DVLC()
  E_OKd;
  r  *­dwie(e,uo lg;
  v=(d>_rt)dv i,fa)
  DVULC()
  E_NOKd;
 
  rtr v
  eunr;
}
cdev_write -> DEV_LOCK

デバイス用のロックのマクロ
#eieDVLC()          
dfn E_OKd           
  i (plg=(­dfa  _PAE)= ){    
  f(mfa  d>_lg&DMSF) =0     
    KRE_OK1 UL;       
    ENLLC(,NL)        
  }
  
 
#eieDVULC()           
dfn E_NOKd            
  i mfa =0          
  f(plg= ){         
    KRE_NOKOENL)      
    ENLULC_N(UL;      
  }
  

対象デバイスがmp-safeならロックしない。
ロックしたかどうかは、呼出し元のローカル変数で管理
cdev_write

cdevswのwrite関数をコールする。引数はcdev_writeと同じ。
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;
  n v plg
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO
  /  
    / ↑ シリアルのc e s 取得
dvw
 
  DVLC()
  E_OKd;
    r     * ­ d w i e ( e , u o   l g ;     / c m r t ( が呼ばれる
  v=(d>_rt)dv i,fa)  / owie)
  DVULC()
  E_NOKd;
 
  rtr v
  eunr;
}
cntsrc dvwcmces  
os tutces o_dvw={
  cmpn ocoe ora,cmrt,cmot,
  ooe,cmls,cmed owie oicl
  cmtp oty opl,nma,tyqitr _T
  oso,cmt,cmol omp tkfle,DTY
}
;
comwrite()
comwrite

com(シリアルポート)にwriteする関数
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
  src t t  c>cty
  tutty*p=s­s_t;
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}
comwrite

com_softcの取得
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
..
.
}
comwrite

DRIVER(9) より
softc構造体はドライバ内でのみアクセスされるので、定義はドライバ独自
である。
それでも、softc構造体は標準のNetBSDの構成と命名規則を採用すべき。
たとえば、"foo"ドライバのsoftc構造体は以下のような定義である :
struct foo_softc {
    device_t sc_dev; /* generic device info */
    /* device-specific state */
};
autoconfigurationフレームワークは、softcの最初のメンバはドライバ非依存
のdevice_tにするように命令する。
AUTOCONF(9) より
autoconfigurationはデバイスと適切なドライバを対応させる処理。...
システムのブート時に発生する。
comwrite

つまり、com_softcはシステムのブート時に作られる、
特定のデバイス (tty00) 用のローカルデータ。
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
..
.
}

第1引数の&com_cdは?
comwrite

&com_cd は struct cfdriver型。
etr tutcdie o_d
xensrc frvrcmc;
src frvr{
tutcdie 
  LS_NR(frvr dls; / iko lcdies*
  ITETYcdie)c_it  *ln nalfrvr /
  src ftahitc_tah / ito l tahet /
  tutcatcls datc; *ls falatcmns*
  dvc_ c_es   / eie on /
  eiet*ddv;   *dvcsfud*
  cntca c_ae    / eienm /
  os hr*dnm;    *dvc ae*
  eu  dvls dcas / eiecasfcto /
  nm  ecasc_ls; *dvc lsiiain*
  itc_dv;   / ieo ddv ra /
  n dnes    *sz fc_esary*
  cntsrc fatdt  os c_tr;/ trbtspoie /
  os tutcitraa*cnt*dats *atiue rvdd*
}
;

autoconfでデバイスに対応付けた、ドライバ情報を格納しているようだ。
comwrite

comドライバのcfdriverである、com_cdはマクロを使って定義されている
/ 
/ 色々なドライバで使う共通マクロ
#eieCDIE_ELnm,cas tr)     
dfn FRVRDC(ae ls,ats      
src frvr_CNA(ae_d         
tutcdie _OCTnm,c)={       
  .dnm    =__TIGnm)   
  c_ae     _SRN(ae,   
  .dcas   =cas      
  c_ls     ls,      
  .dats   =ats      
  c_tr     tr,      
}
/   t u t c d i e   o _ d の定義
/src frvrcmc 
CDIE_ELcm VTY o_tr)
FRVRDC(o,D_T,cmats;
comwrite

戻って、
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
..
.

第2引数のCOMUNIT(dev)について
#eieCMNTx (io()&CMNTMS)
dfn OUI() mnrx  OUI_AK
#eiemnrx  (dvio_)((it2t()&0ff00)> 2  
dfn io()  (emnrt((un3_)x  xf000 >1)|
          (un3_)x  x000f > ))
         ((it2t()&0000f)> 0)
#eieCMNTMS  07ff
dfn OUI_AK  xff

マイナー番号はdevのメジャー番号部分を除いて結合すると取得できる。
COMUNITはマイナー番号の19bit部(最上位1bitを削った)の数
comwrite -> device_lookup_private

device_lookup_private()を見ます
/
*
  eielou_rvt:
*dvc_okppiae
 
*
    与えられたドライバから  o t インスタンスを検索する
* 
sfc
 /
*
vi 
od*
dvc_okppiaecdie_ d n nt
eielou_rvt(frvrtc,itui)
{
 
  rtr eiepiaedvc_okpc,ui);
  eundvc_rvt(eielou(d nt)
}

device_lookup() の結果を device_private() する
comwrite -> device_lookup_private -> device_lookup

/
*
  eielou:
*dvc_okp
 
*
    与えられたドライバから  e i e
* 
d v c インスタンスを検索する
 /
*
dvc_
eiet
dvc_okpcdie_ d n nt
eielou(frvrtc,itui)
{
  dvc_ v
  eietd;
  its
  n ;
 
  s=cni_ldv_ok)      / 
        o f g a l e s l c ( ;             / ロック
  KSETmtxond&ldv_t);
  ASR(ue_we(alesmx)
  i ui   |ui =c­c_dv)
  f(nt<0| nt> d>dnes
    d  UL
    v=NL;
  es f(d  d>ddv[nt)! UL& v>vdlgn! )
  lei (v=c­c_esui] =NL &d­d_e_e =0
    d  UL
    v=NL;
  cni_ldv_noks;      / 
    o f g a l e s u l c ( )               / ロック解除
 
  rtr v
  eund;
}
comwrite -> device_lookup_private -> device_lookup

dvc_okpcdie_ d n nt
eielou(frvrtc,itui)
{
..
.
  s=cni_ldv_ok)      / 
        o f g a l e s l c ( ;             / ロック
  KSETmtxond&ldv_t);
  ASR(ue_we(alesmx)
..
.
  cni_ldv_noks;      / 
    o f g a l e s u l c ( )               / ロック解除
sai n
ttcit
cni_ldv_okvi)
ofgaleslc(od
{
  mtxetr&ldv_t)
  ue_ne(alesmx;
  rtr ;
  eun0
}
..
.
/AGUE*
*RSSD/
sai od
ttcvi
cni_ldv_nokits
ofgalesulc(n )
{
  mtxei(alesmx;
  ue_xt&ldv_t)
}

ロックは、mutexを使って実装している
comwrite -> device_lookup_private -> device_lookup

dvc_okpcdie_ d n nt
eielou(frvrtc,itui)
{
..
.
  i ui   |ui =c­c_dv)/ nt
    f ( n t < 0 |   n t >   d > d n e s   / u i の範囲チェック
    d  UL
    v=NL;
  es f(d  d>ddv[nt)! UL& v>vdlgn! )
  lei (v=c­c_esui] =NL &d­d_e_e =0
    d  UL
    v=NL;
src frvr{
tutcdie 
..
.
  dvc_ c_es   / eie on /
  eiet*ddv;   *dvcsfud*
..
.
  itc_dv;   / ieo ddv ra /
  n dnes    *sz fc_esary*
..
.
}
;

unitの値をチェックしてからcd_devsのunit番目のdevice_tを取得する。
取得したdeviceのdv_del_genが0でないなら取得失敗。
comwrite -> device_lookup_private -> device_lookup

dv->dv_del_genとは何か
dvc_okpcdie_ d n nt
eielou(frvrtc,itui)
..
.
  es f(d  d>ddv[nt)! UL& v>vdlgn! )
  lei (v=c­c_esui] =NL &d­d_e_e =0
    d  UL
    v=NL;

detach 関数で値を入れられている
it
n
cni_eahdvc_ e,itfas
ofgdtc(eietdv n lg)
..
.
    i alesnrt =0& ldv_ra =0
    f(ldv_wie=  &alesned= )
      cni_euln(e,&fa_abg)
      ofgdvnikdv a.fgrae;
    es 
    le{
      dv>vdlgn=alesgn
      e­d_e_e  ldv_e;
      alesgrae=tu;
      ldv_abg  re
    }
    

作成時は0にセットされているメンバ変数で、GCのフラグのようだ。
0でないと回収対象なので、チェックしているのではないか
comwrite -> device_lookup_private -> device_lookup

* 
  与えられたドライバから  e i e
d v c インスタンスを検索する
 /
*
dvc_
eiet
dvc_okpcdie_ d n nt
eielou(frvrtc,itui)
{
  dvc_ v
  eietd;
  its
  n ;
 
  s=cni_ldv_ok)      / 
        o f g a l e s l c ( ;             / ロック
  KSETmtxond&ldv_t);
  ASR(ue_we(alesmx)
  i ui   |ui =c­c_dv)/ nt
    f ( n t < 0 |   n t >   d > d n e s   / u i の範囲チェック
    d  UL
    v=NL;
  es f(d  d>ddv[nt)! UL& v>vdlgn! )
  lei (v=c­c_esui] =NL &d­d_e_e =0
    d  UL
    v=NL;
    /   デバイスが有効かチェック
  /↑
 
  cni_ldv_noks;      / 
    o f g a l e s u l c ( )               / ロック解除
 
  rtr v
  eund;
}

device_lookup() は、
cfdriver(com_cd) と unit番号から、deviceを取得する関数でした
comwrite -> device_lookup_private

呼出し元に1つ戻って、
/
*
  eielou_rvt:
*dvc_okppiae
 
*
    与えられたドライバから  o t インスタンスを検索する
* 
sfc
 /
*
vi 
od*
dvc_okppiaecdie_ d n nt
eielou_rvt(frvrtc,itui)
{
 
  rtr eiepiaedvc_okpc,ui);
  eundvc_rvt(eielou(d nt)
}

取得したdevieを引数に、device_private() を呼ぶ。
comwrite -> device_lookup_private -> device_private

vi 
od*
dvc_rvt(eietdv
eiepiaedvc_ e)
{
 
  /
  *
        e i e p i a e N L ) は多くのユーザスペースの要求ハンドラ
  *dvc_rvt(UL 
        すなわち、c b e ハンドラー)
  *(
/dv
の作業を簡略化するために許可されている.
    
    * それらがN L かどうかをテストする必要がなくなり、ただd v c _ r v t を
UL
eiepiae
    
    * 呼ぶだけでよくなる.
   /
  *
  rtr e =NL  UL:dv>vpiae
  eundv= UL?NL  e­d_rvt;
}

引数のdeviceがNULLだったらNULLを返し、そうでなければdv_privateを返す
関数でした。
comwrite -> device_lookup_private -> device_private

dev->dv_privateは何か
vi 
od*
dvc_rvt(eietdv
eiepiaedvc_ e)
{
..
.
  rtr e =NL  UL:dv>vpiae
  eundv= UL?NL  e­d_rvt;
}
src eie
tutdvc;
tpdfsrc eie*eiet
yee tutdvc dvc_;
src eie{
tutdvc 
..
.
  vi    *vpiae  / hsdvc' rvt trg /
  od    d_rvt;  *ti eiespiaesoae*
..
.
}

デバイスの private storage
comwrite

戻って、device_lookup_private() について
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
  src t t  c>cty
  tutty*p=s­s_t;
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}

comドライバのデータを持つ com_cd に格納されている
COMUNIT(dev) 番目のデバイスの private storage が返ってくる。
それが、tty00のローカルデータである com_softc である。
comwrite

it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
    /     t 0 のデータ取得
  /↑ty0
  src t t  c>cty
  tutty*p=s­s_t;
  /  
    / ↑ コンソールの端末
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}

次にCOM_ISALIVE()でデバイスが生きているかチェックする
comwrite -> COM_ISALIVE

#eieCMIAIEs)(s)>nbe =0& 
dfn O_SLV(c (c­eald!  &
       eiei_cie(c­s_e)
      dvc_satv(s)>cdv)
src o_ot 
tutcmsfc{
  dvc_ cdv / 
    e i e t s _ e ;   / ドライバ非依存の情報
..
.
    i t e a l d       /   t a h p n が代入。d t c 、s u d w で0
    n   n b e ;       / a t c 、o e で1
e a h h t o n 代入
bo
ol
dvc_satv(eietdv
eiei_ciedvc_ e)
{
  itatv_lg;
  n ciefas
 
  atv_lg  V_CIE
  ciefas=DFATV;
  atv_lg =DFCASSSEDD
  ciefas| V_LS_UPNE;
  atv_lg =DFDIE_UPNE;
  ciefas| V_RVRSSEDD
  atv_lg =DFBSSSEDD
  ciefas| V_U_UPNE;
 
  rtr dv>vfas&atv_lg)= V_CIE
  eun(e­d_lg  ciefas =DFATV;
}

アクティブかつ、各サスペンドフラグが落ちていれば、
device_is_active() は true
comwrite

it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
    /     t 0 のデータ取得
  /↑ty0
  src t t  c>cty
  tutty*p=s­s_t;
  /  
    / ↑ コンソールの端末
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
    /     t 0 がアクティブで使えるかチェック
  /↑ty0
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}
#eieEO  5   / nu/upterr*
dfn I       *Iptotu ro /

アクティブでない場合はエラーを返す
comwrite

最後の行のwriteについて
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
    /     t 0 のデータ取得
  /↑ty0
  src t t  c>cty
  tutty*p=s­s_t;
  /  
    / ↑ コンソールの端末
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
    /     t 0 がアクティブで使えるかチェック
  /↑ty0
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}
src t 
tutty{
..
.
  src lns tlns; / nefc odvc rvr.*
  tut iew*_iew  *Itraet eiedies /
..
.
comwrite -> tty->t_linesw->l_write

/
*
  iedsiln(
* L n   i c p i e 回線制御) s i c   a l
 wthtbe
 /
*
src iew{
tutlns 
  cntca lnm;/ iewnm /
  os hr*_ae *Lns ae*
 
  LS_NR(iew _it
  ITETYlns)lls;
  uit lrfn; / okdb tlicls_lc /
  _n  _ect  *lce ytyds_itsok*
  itln;   / eaydsiln ubr(o ICED /
  n _o    *lgc icpienme frTOGT)*
 
  it(loe) (e_,src t )
  n *_pn  dvt tutty*;
  it(lcoe (tutty* n)
  n *_ls) src t ,it;
  it(lra) (tutty* tutuo* n)
  n *_ed  src t ,src i ,it;
  it(lwie (tutty* tutuo* n)
  n *_rt) src t ,src i ,it;
  it(licl (tutty* _og od* n,
  n *_ot) src t ,uln,vi ,it
          src w )
          tutlp*;
  it(lrn) (n,src t )
  n *_it  it tutty*;
  it(lsat (tutty*;
  n *_tr) src t )
  it(lmdm (tutty* n)
  n *_oe) src t ,it;
  it(lpl) (tutty* n,src w )
  n *_ol  src t ,it tutlp*;
}
;

cdevswのようにアクセス用のテーブルになっている
comwrite -> tty->t_linesw->l_write

ブート時のautoconfで通る場所で、
com_softcのttyのメンバーに値がセットされている
vi
od
cmatc_ursrc o_ot s)
o_tahsb(tutcmsfc*c
{
..
.
  t  t_lo(;
  p=tyalc)
..
.
  s­s_t  p
  c>cty=t;
/
*
  loaeatysrcueadisascae ufr.
*Alct  t tutr n t soitdbfes
 /
*
src t 
tutty*
tyalcvi)
t_lo(od
{
  src t t;
  tutty*p
..
.
  / e eal iedsiln.*
  *Stdfutln icpie /
  t­tlns  tlicdfut)
  p>_iew=tyds_eal(;
..
.
  rtr p
  eunt;
}
comwrite -> tty->t_linesw->l_write

/
*
  euntedfutln icpie
*Rtr h eal iedsiln.
 /
*
src iew*
tutlns 
tyds_eal(od
tlicdfutvi)
{
  rtr &emo_ic;
  eun(trisds)
}
sai tutlns emo_ic={
ttcsrc iewtrisds  
  ._ae="emo"
  lnm  tris,
  ._pn=tyoe,
  loe  tlpn
  ._ls  tlls,
  lcoe=tycoe
  ._ed=tra,
  lra  ted
  ._rt  trt,
  lwie=twie
  ._ot  tnlicl
  licl=tyulot,
  ._it=tynu,
  lrn  tipt
  ._tr  ttr,
  lsat=tsat
  ._oe  tmdm
  lmdm=tyoe,
  ._ol=tpl
  lpl  tol
}
;

ttyのwriteはttwrite() が呼ばれる
comwrite

it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
    /     t 0 のデータ取得
  /↑ty0
  src t t  c>cty
  tutty*p=s­s_t;
  /  
    / ↑ コンソールの端末
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
    /     t 0 がアクティブで使えるかチェック
  /↑ty0
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
  /     t r t ( が呼ばれる
 /↑twie)
}
comwrite おまけ

バックトレースだとcdev_wirte() -> ttwrite() になっていて、
間にあるcomwrite()が見えませんが、
comwrite()はttwrite()をコールした後の処理がないので、
スタックを戻した後、jmp命令でttwrite()に遷移しているからでした。
c2a3 cmrt>
0597<owie:
c2a3:   5           ps  ep
0597    5           uh %b
c2a3:   8 5         mv  ep%b
0598    9e          o  %s,ep
c2a3:   5           ps  ei
059a    7           uh %d
c2a3:   5           ps  ei
059b    6           uh %s
c2a3:   5           ps  ex
059c    3           uh %b
c2a3:   8 c1        sb  01,ep
059d    3e c        u  $xc%s
..
.
c2aa:   8 41        ad  01,ep
059a    3c c        d  $xc%s
c2aa:   5           pp  ex
059d    b           o  %b
c2aa:   5           pp  ei
059e    e           o  %s
c2aa:   5           pp  ei
059f    f           o  %d
c2ab:   5           pp  ep
0590    d           o  %b
c2ab:   f 0         jp  %a  / trtへ
0591    fe          m  *ex  /twie
まとめ
まとめ

cdev_write()について
it
n
ce_rt(e_ e,src i uo n lg
dvwiedvtdv tutuo*i,itfa)
{
  cntsrc dvw*;
  os tutces d
  itr,mfa;
  n v plg
 
  i (  dvwlou(e) =NL)
  f(d=ces_okpdv)= UL
    rtr NI;
    eunEXO
 
  DVLC()
  E_OKd;
  r  *­dwie(e,uo lg;
  v=(d>_rt)dv i,fa)
  DVULC()
  E_NOKd;
 
  rtr v
  eunr;
}

cdev_write()はキャラクタデバイスにwriteする関数
デバイスのメジャー番号ごとのcdevswを取得
tty00はシリアルポート用のcom_cdevになる
com_cdevのwriteをコールしてcomwrite()へ
まとめ

comwrite()について
it
n
cmrt(e_ e,src i uo n lg
owiedvtdv tutuo*i,itfa)
{
  src o_ot s 
  tutcmsfc*c=
    dvc_okppiae&o_d OUI(e);
    eielou_rvt(cmc,CMNTdv)
  src t t  c>cty
  tutty*p=s­s_t;
 
  i CMIAIEs)= )
  f(O_SLV(c =0
    rtr EO;
    eun(I)
 
  rtr (t­tlns­lwie(p i,fa);
  eun(*p>_iew>_rt)t,uo lg)
}

comwrite()はシリアルポートにwriteする関数
comドライバのデータを持つcom_cdからマイナー番号毎のcom_softcを取
得
xxx_softcは特定のデバイス用のローカルデータ
tty00がアクティブかチェック
デバイス用データ→tty→回線制御ドライバのwriteをコール
ブート時のautoconfで設定されているttwrite()が呼ばれる

More Related Content

What's hot

effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
do_aki
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
Tatsuki SHIMIZU
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
Tatsuki SHIMIZU
 
C++でHello worldを書いてみた
C++でHello worldを書いてみたC++でHello worldを書いてみた
C++でHello worldを書いてみた
firewood
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
Kousuke Ebihara
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
Kouji Hosoda
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
Keisuke Fukuda
 
コルーチンの使い方
コルーチンの使い方コルーチンの使い方
コルーチンの使い方
Naohiro Yoshikawa
 
Slide
SlideSlide
Boost9 session
Boost9 sessionBoost9 session
Boost9 sessionfreedom404
 
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519Yasuhiro Ishii
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
Kota Mizushima
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
dynamis
 
core dumpでcode golf
core dumpでcode golfcore dumpでcode golf
core dumpでcode golf
Nomura Yusuke
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
egtra
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
Kazuki Onishi
 

What's hot (20)

effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
C++でHello worldを書いてみた
C++でHello worldを書いてみたC++でHello worldを書いてみた
C++でHello worldを書いてみた
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
 
コルーチンの使い方
コルーチンの使い方コルーチンの使い方
コルーチンの使い方
 
llvm入門
llvm入門llvm入門
llvm入門
 
Slide
SlideSlide
Slide
 
Boost9 session
Boost9 sessionBoost9 session
Boost9 session
 
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
core dumpでcode golf
core dumpでcode golfcore dumpでcode golf
core dumpでcode golf
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 

Similar to cdev_write and_comwrite

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
Satoshi Mimura
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
yak1ex
 
Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Takeshi Arabiki
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another sideKiwamu Okabe
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺちdo_aki
 
4章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 54章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 5
mao999
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
MITSUNARI Shigeo
 
Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perlJiro Nishiguchi
 
○○大学の本当にあった怖い話
○○大学の本当にあった怖い話○○大学の本当にあった怖い話
○○大学の本当にあった怖い話idkqh7 Nishino
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
Kazuki Onishi
 
final int をFINAL しやがれ!
final int をFINAL しやがれ!final int をFINAL しやがれ!
final int をFINAL しやがれ!
Keiichi Nagaoka
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
MITSUNARI Shigeo
 
怪しいWindowsプログラミング
怪しいWindowsプログラミング怪しいWindowsプログラミング
怪しいWindowsプログラミングnagoya313
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブル
kusabanachi
 
VerilatorとSystemCでSoftware Driven Verification
VerilatorとSystemCでSoftware Driven VerificationVerilatorとSystemCでSoftware Driven Verification
VerilatorとSystemCでSoftware Driven Verification
Mr. Vengineer
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
Kohei KaiGai
 

Similar to cdev_write and_comwrite (19)

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理Rのデータ構造とメモリ管理
Rのデータ構造とメモリ管理
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another side
 
Map
MapMap
Map
 
詳説ぺちぺち
詳説ぺちぺち詳説ぺちぺち
詳説ぺちぺち
 
4章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 54章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 5
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perl
 
○○大学の本当にあった怖い話
○○大学の本当にあった怖い話○○大学の本当にあった怖い話
○○大学の本当にあった怖い話
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 
final int をFINAL しやがれ!
final int をFINAL しやがれ!final int をFINAL しやがれ!
final int をFINAL しやがれ!
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
怪しいWindowsプログラミング
怪しいWindowsプログラミング怪しいWindowsプログラミング
怪しいWindowsプログラミング
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブル
 
VerilatorとSystemCでSoftware Driven Verification
VerilatorとSystemCでSoftware Driven VerificationVerilatorとSystemCでSoftware Driven Verification
VerilatorとSystemCでSoftware Driven Verification
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
 

Recently uploaded

JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
Yuuitirou528 default
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
t m
 

Recently uploaded (8)

JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料CS集会#13_なるほどわからん通信技術 発表資料
CS集会#13_なるほどわからん通信技術 発表資料
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
 

cdev_write and_comwrite