1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FreeBSDのデバイスコンフィグレーション

Last updated at Posted at 2016-03-09

現在のデバイスコンフィグレーションの仕組みは以下の四つがあります。

  • ハードコードからのコンフィグレーション
  • hintsによるコンフィグレーション
  • fdtによるコンフィグレーション
  • kldloadによるロード

ハードコードからのコンフィグレーションは親のデバイスのコードでのBUS_ADD_CHILD()メソッドにより実行されます。

hintsによるコンフィグレーションはbuildkernelでカーネル内に放り込まれたhintsの情報により読み込みが実行されます。BUS_ADD_CHILDで読み込まれているにも関わらずhintsでも指定するとカーネルが落ちます。

hint.spi.0.at="nexus0"
hint.spi.0.maddr=0x1f000000
hint.spi.0.msize=0x10

fdtによるコンフィグレーションはbootから引き渡されたdtbかbuildkernel時にスタティックに放り込まれたdtsをコンパイルしたdtbにより読み込まれます。

                spi0@84000 {
                        compatible = "lpc,spi";
                        reg = <0x84000 0x4000>;
                        interrupts = <20>;
                        interrupt-parent = <&PIC>;
                };

kldloadでのロードはコンフィグレーションではないですが、デバイスがコンフィグレーション同様に読み込まれます。

FreeBSDのブロジェクとの方針としてはfdtが一番推奨で、hintsが次で、おそらハードコードはあまり推奨されていないとおもいます。2016/03現在sys/armはfdtに移行していますがsys/mipsはあまりftdへの移行が進んでいませんが、少しずつコードは入ってきています。

子と親の関係は、ドラーバーコードのDRIVER_MODULEで定義されています。これはhintsベースでもFDTベースでも同じです。EARLY_DRIVER_MODULEで定義された物は先にロードされます。

FreeBSDの現在のデバイスのコンフィグレーションの問題として、デバイスのロードされる順番が明示的に設定できないケースがあります。デバイスがバスの場合、マイナー番号が変わってしまうと子になるデバイスが正しくロードできない可能性があります。

spiバスのmx25lがあるmipsなルータでgpiospiを追加したところgpiospiがspibus0になりhintsでspibus0としたmx25lが見えなくなる事がありました。現在のFreeBSDでは細かい順番が設定できないためmx25lのhintsをspibus1と書き換えるしかないです。

コンソール

コンソールはデバイスがコンフィグレーションされる前に使用されるため上のコンフィグレーションとは別にコンソール用のコンフィグレーションで初期化されます。

コンソールはOSのソース内でCONSOLE_DRIVERで登録されたドライバの中でスコアの高いものをコンソールに選びます。シリアルコンソールの場合dev/uart/uart_tty.cに登録がありこれを使います。実体はuart_cpu_getdev()で取得するようになっています。

uart.png

uart_cpu_fdt.cではdtsファイルの"/chosen"のデバイスか"serial0"なデバイスが選択されるようです。そのデバイスのcompatibleがofw_compat_dataにあるソースのクラスが利用されます。

/sbin/initが起動されるまではコンソールドライバに出力され、init起動後はbusなuartが使われるようになります。コンソールへの出力ではFIFOが空になったという割り込みは使われません。これはシステム起動後には割り込みコントローラが(PIC)を処理するデバイスが登録されていない状態のためです。

リソースと割り込み

FreeBSDでは古来からのprobe(),attach()を使ってデバイスのコンフィグレーションを行いますが、リソースの確保はbus_alloc_resource_any()で行われます。割り込みのハンドラの登録はbus_setup_intr()で行います。FreeBSDの割り込みハンドラは二つあり、filterとithreadと呼ばれています。

freebsd_intr.png

二つに分けているのは割り込みの処理があまり大きくなって、パフォーマンスに影響するのを避けるためではないかと思われます。

INTRNG

armのプロジェクトの成果のINTRNGが他のアーキテクチャでも使えるようになりました。INTRNGの目標はirq処理の整理とPICとBUSの分離またマルチプロセッサー上での最適化と思われます。

bus_setup_intr()は変えずにその中で処理される仕組みを変えています。

armはv4系ではハードウエア割り込みが1本ですが、v6以降では複数あるようです。

armv5tなRT1310の割り込みは以下のようになっています。

arm_intr.png

mipsなar5315の割り込みは以下のようになっています。6本の割り込みはMIPS共通です。PICはそれぞれのSOC毎に違います。INTRNGではMIPS共通の割り込みの登録はcpu_establish_hardintrでおこないます。

mips_intr.png

mips 4KではTimerが固定で用意されています。これ以外はボード毎に違っています。

BCM4712はPICはなくてMIPSの6本の割り込みだけになっている。0-4の割り込みに複数の割り込みをアサイン出来るようだ。

mips/mediatek(RT3050)のkern/subr_intr.cのデバッグログ

intr_pic_register(): PIC 0x805acdc0 registered for cpupic0 <dev 0x80554100, xref 3>
intr_pic_claim_root(): irq root set to cpupic0
intr_pic_register(): PIC 0x805ac080 registered for intc0 <dev 0x80553800, xref 1>
intr_setup_irq(): irq 2 add handler error 0 on intc0
intr_pic_register(): PIC 0x805abdc0 registered for gpio0 <dev 0x80553680, xref 9>
intr_setup_irq(): irq 14 add handler error 0 on gpio0
intr_setup_irq(): irq 20 add handler error 0 on uart0
intr_setup_irq(): irq 5 add handler error 0 on rt0
intr_setup_irq(): irq 7 add handler error 0 on cpupic0

subr_intr.cの中には同じpanicに同じメッセージのところがあり、どこで落ちたのかわかりません。なんともいけてないです。

subr_intr.cのirq_mapは4Kの割り込みは全部登録されていますが、PICは割り込みがあるものだけ登録するようです。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?