i8253 PIT をアクセスするドライバのうち、i8253 の channel 1 を platform device として登録する i8253_ref_setup.c を kernel に組み込み、その結果を確かめることをします。
添付ファイル i8253_ref_setup.diff は kernel source に当てるパッチです。内容は Kconfig と Makefile 修正の詳細、i8253_ref 全体のデータ構造、i8253_ref_setup.c: kernel に platform device を登録する を参照して下さい。このファイルをダウンロードして、kernel source の root directory (linux-stable) にカレント・ディレクトリを移し、次の様にして kernel にパッチを当てます。色々と修正を試みた後、ソースを元に戻すことも考慮し、branch i8253_ref_setup を作る操作も込みで示しています。branch 名は好きに付けても良いです。
linux-stable $ git checkout -b i8253_ref_setup linux-stable $ git patch down_loaded_directory/i8253_ref_setup.diff
続けて新しく追加した configuration 項目 (Kconfig の内容) を .config に反映するため make menuconfig を実行します。
linux-stable $ make menuconfig
menuconfig の中で Processor type and features を選択します。
.config - Linux/x86 4.1.27 Kernel Configuration ────────────────────────────────────────────────────────────────────────────── ┌───────────────── Linux/x86 4.1.27 Kernel Configuration ─────────────────┐ │ Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty │ │ submenus ----). Highlighted letters are hotkeys. Pressing <Y> │ │ includes, <N> excludes, <M> modularizes features. Press <Esc><Esc> to │ │ exit, <?> for Help, </> for Search. Legend: [*] built-in [ ] │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ [*] 64-bit kernel │ │ │ │ General setup ---> │ │ │ │ [*] Enable loadable module support ---> │ │ │ │ [*] Enable the block layer ---> │ │ │ │ Processor type and features ---> │ │ │ │ Power management and ACPI options ---> │ │ │ │ Bus options (PCI etc.) ---> │ │ │ │ Executable file formats / Emulations ---> │ │ │ │ [*] Networking support ---> │ │ │ │ Device Drivers ---> │ │ │ │ Firmware Drivers ---> │ │ │ │ File systems ---> │ │ │ │ Kernel hacking ---> │ │ │ │ Security options ---> │ │ │ │ -*- Cryptographic API ---> │ │ │ │ -*- Virtualization ---> │ │ │ └────┴(+)─────────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────────────┤ │ <Select> < Exit > < Help > < Save > < Load > │ └─────────────────────────────────────────────────────────────────────────┘
項目 I8253 PIT Refresh timer driver に * を付けた状態にします。menuconfig を .config に変更を反映する選択をして終了します。
.config - Linux/x86 4.1.27 Kernel Configuration > Processor type and features; ──────────────────────────────────────────────── ┌────────────────────── Processor type and features ──────────────────────┐ │ Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty │ │ submenus ----). Highlighted letters are hotkeys. Pressing <Y> │ │ includes, <N> excludes, <M> modularizes features. Press <Esc><Esc> to │ │ exit, <?> for Help, </> for Search. Legend: [*] built-in [ ] │ │ ┌────^(-)─────────────────────────────────────────────────────────────┐ │ │ │ [*] Enable IOSF sideband access through debugfs │ │ │ │ [*] Single-depth WCHAN output │ │ │ │ [*] Linux guest support ---> │ │ │ │ Processor family (Generic-x86-64) ---> │ │ │ │ [*] Supported processor vendors ---> │ │ │ │ [*] I8253 PIT Refresh timer driver (NEW) │ │ │ │ [*] Enable DMI scanning │ │ │ │ [*] Old AMD GART IOMMU support │ │ │ │ [*] IBM Calgary IOMMU support │ │ │ │ [*] Should Calgary be enabled by default? │ │ │ │ [ ] Enable Maximum number of SMP Processors and NUMA Nodes │ │ │ │ (256) Maximum number of CPUs │ │ │ │ [*] SMT (Hyperthreading) scheduler support │ │ │ │ [*] Multi-core scheduler support │ │ │ │ Preemption Model (Voluntary Kernel Preemption (Desktop)) ---│ │ │ │ [*] Reroute for broken boot IRQs │ │ │ └────┴(+)─────────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────────────┤ │ <Select> < Exit > < Help > < Save > < Load > │ └─────────────────────────────────────────────────────────────────────────┘
I8253 PIT Refresh timer driver の階層がおかしくないか?
"I8253 PIT Refresh timer driver" のメニュー階層に違和感があるのは確かです。メニュー階層を menu-endmenu で作るか、config 項目を "Device Drivers" の囲みの中に作るかすれば違和感は減ると思います。ソースファイルの位置と Kconfig ファイルの位置関係もなるべく近くにしつつ menuconfig も違和感なく構成するのに難しい題材なのかもしれません。Kconfig についての詳細は /Documentation/kbuild/kconfig-language.txt を見て下さい。
構築と install は チュートリアルページの構築編 を参考にして下さい。このページのパッチを当てる前に # make modules_install; make install が済んでいて、構築済みの kernel 起動を確認できているならば grub の修正と更新手順を省略して下さい。
kernel に組み込んだ i8253_ref_setup.c で platform device を組み込みました。組み込んだ kernel を起動すると kernel (/drivers/base) で管理している device の情報に変化が起きています。変化を見ていきます。
i8253_ref_setup.c の中で resource 構造体の配列で定義した I/O ポートが /proc/ioports に反映されます。ポート名は /include/linux 以下に配置した i8253_ref.h の中で定義されています。
~ $ cd /proc /proc $ cat ioports 0000-0cf7 : PCI Bus 0000:00 0000-001f : dma1 0020-0021 : pic1 0040-0043 : timer0 0041-0041 : refresh_counter 0043-0043 : control_word 0050-0053 : timer1 0060-0060 : keyboard 0061-0061 : PNP0800:00 0064-0064 : keyboard 0070-0071 : rtc0 0080-008f : dma page reg 00a0-00a1 : pic2 00c0-00df : dma2 00f0-00ff : PNP0C04:00 00f0-00ff : fpu 0170-0177 : 0000:00:06.0 0170-0177 : pata_amd -- snip --
i8253_ref_setup.c の中で platform_device_register() で登録したデバイスが i8253_ref.0.auto ディレクトリとして現れます。platform_device 構造体のメンバを id = PLATFORM_DEVID_AUTO, id_auto = true としたので、デバイス名の後ろに ".0.auto" が自動的に付加されています。
/proc $ cd /sys/devices/platform /sys/devices/platform $ ls -la total 0 drwxr-xr-x 13 root root 0 9 9 10:46 . drwxr-xr-x 12 root root 0 9 9 10:46 .. drwxr-xr-x 4 root root 0 9 9 10:46 Fixed MDIO bus.0 drwxr-xr-x 3 root root 0 9 9 10:46 PNP0C0B:00 drwxr-xr-x 3 root root 0 9 9 10:46 PNP0C0C:00 drwxr-xr-x 3 root root 0 9 9 10:46 alarmtimer drwxr-xr-x 4 root root 0 9 9 10:46 i8042 drwxr-xr-x 3 root root 0 9 9 10:46 i8253_ref.0.auto drwxr-xr-x 3 root root 0 9 9 10:46 pcspkr drwxr-xr-x 3 root root 0 9 9 10:46 platform-framebuffer.0 drwxr-xr-x 2 root root 0 9 10 16:11 power drwxr-xr-x 4 root root 0 9 9 10:46 reg-dummy drwxr-xr-x 4 root root 0 9 9 10:46 serial8250 -rw-r--r-- 1 root root 4096 9 9 10:46 uevent /sys/devices/platform $ cd i8253_ref.0.auto /sys/devices/platform/i8253_ref.0.auto $ ls -la 0 drwxr-xr-x 3 root root 0 9 10 16:11 . drwxr-xr-x 13 root root 0 9 10 16:11 .. -rw-r--r-- 1 root root 4096 9 10 16:11 driver_override -r--r--r-- 1 root root 4096 9 10 16:11 modalias drwxr-xr-x 2 root root 0 9 10 16:11 power lrwxrwxrwx 1 root root 0 9 9 10:46 subsystem -> ../../../bus/platform -rw-r--r-- 1 root root 4096 9 9 10:46 uevent
ドライバ i8253_ref.c を組み込むと /sys/devices/platform/i8253_ref.0.auto ディレクトリの中に counter, rate ノードが sysfs_create_group() の呼び出しによって作られます。次は i8253_ref.c から構築した i8253_ref.ko を組み込んだ後の様子です。
/sys/devices/platform/i8253_ref.0.auto # ls -la total 0 drwxr-xr-x 3 root root 0 9 10 16:12 . drwxr-xr-x 13 root root 0 9 10 16:11 .. -r--r--r-- 1 root root 4096 9 10 16:13 counter lrwxrwxrwx 1 root root 0 9 10 16:13 driver -> ../../../bus/platform/drivers/i8253_ref -rw-r--r-- 1 root root 4096 9 10 16:11 driver_override -rw-r--r-- 1 root root 4096 9 10 16:13 dump_stack -r--r--r-- 1 root root 4096 9 10 16:11 modalias drwxr-xr-x 2 root root 0 9 10 16:11 power -rw-r--r-- 1 root root 4096 9 10 16:13 rate lrwxrwxrwx 1 root root 0 9 10 16:11 subsystem -> ../../../bus/platform -rw-r--r-- 1 root root 4096 9 10 16:11 uevent /sys/devices/platform/i8253_ref.0.auto # echo 32768 > rate /sys/devices/platform/i8253_ref.0.auto # cat rate 32768 /sys/devices/platform/i8253_ref.0.auto # cat counter 16752 /sys/devices/platform/i8253_ref.0.auto # cat counter 8201
パッチ i8253_ref_setup.diff の中で、新しくソースファイルを用意する、あるいは既存のソースに修正を加えた場合に必要な作業の参考になる部分を見ていきます。
platform device として I8253 PIT を kernel に登録する処理 i8253_ref_setup.c を kernel に静的に結合する(スタティック・リンク)する方法を見ていきます。新しく作ったソース・ファイルを kernel にスタティック・リンクするのに最低限必要なことは次の通りです。
make menuconfig で新しく加えたソース・ファイルをコンパイル対象にするかどうか選択できる様にしておくと、チーム開発をしている状況での問題の切り分け、開発環境の足並みが揃っていない状況で柔軟に対応することができます。
/arch/x86/kernel/Makefile の変更箇所は次の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
obj-$(CONFIG_I8253_REFRESH) += i8253_ref_setup.o は CONFIG_I8253_REFRESH を展開した結果によって obj- += i8253_ref_setup.o または obj-y += i8253_ref_setup.o と解釈されます。ここでは出てきませんが CONFIG_I8253_REFRESH が tristate (モジュール) の場合は obj-m += i8253_ref_setup.o となる場合が有ります。obj-y += i8253_ref_setup.o となった場合、kernel に静的に結合します。
obj-* += file.o | 構築結果 |
obj- += file.o | file.c はコンパイルされない |
obj-y += file.o | file.c は kernel に静的に結合(スタティックリンクされる) |
obj-m += file.o | file.c はモジュールとして構築され file.ko が作られる (このページでは扱いません) |
arch/x86/Kconfig の変更箇所は次の通りです。この Kconfig の位置は例外的に Makefile と ソースファイル i8253_ref_setup.c が有るディレクトリと違っています。この修正で make menuconfig で i8253_ref_setup.c を kernel に組み込むかどうか前節の Makefile の修正と併せ選択することができる様になります。詳細な書き方は /Documentation/kbuild/kconfig-language.txt を参照して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
config I8253_REFRESH で選択項目を宣言します。ここでは接頭辞 CONFIG_ を付けずに書くことに注意して下さい。bool は y か n (定義しない)の選択だと言う意味です。default は n (定義しない)、 depends on X86 は X86(CONFIG_X86) が定義されれば選択項目に現れることを意味します。help は make menuconfig で help を要求したときに表示されるテキストです。他の項目で ---help--- と書かれているところもあります。どちらも同様に解釈されます。help の部分はインデントに意味があります。他の部分のインデントも慣例的に合わせて書くことをお勧めします。
追加した config 項目は make menuconfig のどこに現れるの?
make menuconfig を実行して追加した項目がどこに行ったか分からなくなるかもしれません。丁寧に Kconfig の menu-endmenu のネスティングを追って十分に理解する方法と、手っ取り早く知るために make menuconfig で対話的設定を開始したところで / を押してマクロ名を検索する方法があります。このページの例では I8253_REFRESH を探す文字列とします。Location: 以下に場所のパスが示されます。丁寧に Kconfig の階層構造を探すより早いです。
他の architecture や platform の場合、どこにソース・コードを追加して、どこの Makefile や Kconfig の修正をしたら良いの?
開発ターゲットの基板に実装されたテバイスを追加するために /arch/processor 以下に配置されたファイルを修正したり、追加するやり方に迷うかもしれません。ディレクトリ構成はプロセッサ(CPU)毎に大きく違います。見回してみて、しっくりする修正方法を考えてください。似たようなデバイスを見つけて並べるように修正するのが良いでしょう。他のプロセッサに比べて派生品種が多い ARM 系では /arch/arm/plat-platform に SoC 毎に派生するコード、/arch/arm/mach-machine に基板品種毎に派生する(付加した周辺回路によって派生する)コードが含まれることが多いです(SoC 毎に派生するコードもあります)。