はじめに
2017年3月、「Raspberry Pi システム制御コプロセッサのMIDR情報について」調べてみました。
ARMシステム制御コプロセッサのMIDR(Main ID Register)情報は、プロセッサのデバイスの実装コードとパーツID番号を含む識別情報を提供します。前回は、Raspberry Pi2のMIDR情報を読み出しましたが、今回はRaspberry Pi1とPi3についても確認します。
Raspberry Pi1/Pi2/Pi3 のシステム情報
Raspberry Pi1
使用した Raspberry Pi1のシステム情報とバージョンを下記に示します。
$ uname -a Linux pi1 4.9.14+ #977 Mon Mar 13 18:21:04 GMT 2017 armv6l GNU/Linux
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 8.0 (jessie) Release: 8.0 Codename: jessie
Raspberry Pi2
使用した Raspberry Pi2のシステム情報とバージョンを下記に示します。
$ uname -a Linux pi2 4.9.14-v7+ #977 SMP Mon Mar 13 18:25:19 GMT 2017 armv7l GNU/Linux
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 8.0 (jessie) Release: 8.0 Codename: jessie
Raspberry Pi3
使用した Raspberry Pi3のシステム情報とバージョンを下記に示します。
$ uname -a Linux pi3 4.9.14-v7+ #977 SMP Mon Mar 13 18:25:19 GMT 2017 armv7l GNU/Linux
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 8.0 (jessie) Release: 8.0 Codename: jessie
Raspberry Pi3は、ARMv8アーキテクチャの64bit CPUであるARM Cortex-A53を搭載しています。しかし、Raspbian OSはAArch32による32ビットで動作しています。従って、Raspberry Pi2とRaspberry Pi3のシステム情報は同一です。
MIDR情報を参照するカーネルモジュール
「Raspberry Pi システム制御コプロセッサのMIDR情報について」と同じプログラムを使用します。
MIDR参照プログラムコード
MIDR(Main ID Register)を参照する getmainid.c プログラムコードを下記に示します。
$ cat getmainid.c #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("Dual BSD/GPL"); static int getmidr_init(void) { unsigned int reg; printk(KERN_ALERT "Start Get_MainID \n"); asm volatile("mrc p15 ,0 ,%0 ,c0 ,c0 ,0" : "=r" (reg)); printk(KERN_ALERT "MIDR =%08x\n",reg); return 0; } static void getmidr_exit(void) { printk(KERN_ALERT "End.. Get_MainID \n"); } module_init(getmidr_init); module_exit(getmidr_exit);
ビルド
Makefileを作成します。
$ cat Makefile KERNEL_DIR = /lib/modules/$(shell uname -r)/build obj-m := mainidmod.o mainidmod-objs := getmainid.o all: make -C $(KERNEL_DIR) M=$(PWD) modules clean: make -C $(KERNEL_DIR) M=$(PWD) clean
カーネルモジュールをビルドします。ルート権限が必要なのでスーパーユーザーでmakeします。
$ sudo su # make make -C /lib/modules/4.9.14-v7+/build M=/home/pi/myHome/mainid modules make[1]: Entering directory '/root/linux-a599f69212b051db4cd00a02f9312dc897beba70' CC [M] /home/pi/myHome/mainid/getmainid.o LD [M] /home/pi/myHome/mainid/mainidmod.o Building modules, stage 2. MODPOST 1 modules CC /home/pi/myHome/mainid/mainidmod.mod.o LD [M] /home/pi/myHome/mainid/mainidmod.ko make[1]: Leaving directory '/root/linux-a599f69212b051db4cd00a02f9312dc897beba70'
カーネルモジュール mainidmod.ko を生成しました。
カーネルモジュールの情報
生成したカーネルモジュールの情報を調べます。
$ modinfo mainidmod.ko filename: /home/pi/myHome/mainid/mainidmod.ko license: Dual BSD/GPL srcversion: F8B01D2E75DE338550B6DF4 depends: vermagic: 4.9.14-v7+ SMP mod_unload modversions ARMv7 p2v8
カーネルモジュールのバージョン一致について
カーネルモジュールは、ビルドした環境のカーネルバージョンとロードする環境のカーネルバージョンを一致させなければなりません。
- ビルド環境 Pi2 : ARMv7 4.9.14-v7+
- ロード環境 Pi1 : armv6l 4.9.14+
- ロード環境 Pi2 : armv7l 4.9.14-v7+
- ロード環境 Pi3 : armv7l 4.9.14-v7+
Raspberry Pi2でビルドしたカーネルモジュールをRaspberry Pi3で実行してみました。
Pi3のCPUはARMv8アーキテクチャのARM Cortex-A53を搭載していますが、ARMv7互換の32ビットモードで動作しているのでバージョンが一致しており、問題なく動作しました。
Raspberry Pi2でビルドしたカーネルモジュールをRaspberry Pi1で実行してみました。
$ sudo su # insmod mainidmod.ko insmod: ERROR: could not insert module mainidmod.ko: Invalid module format
ビルドした環境のカーネルバージョンとロードする環境のカーネルバージョンが一致しないのでエラーとなりました。
$ modinfo mainidmod.ko filename: /home/pi/myHome/mainidpi2/mainid/mainidmod.ko license: Dual BSD/GPL srcversion: F8B01D2E75DE338550B6DF4 depends: vermagic: 4.9.14-v7+ SMP mod_unload modversions ARMv7 p2v8
# uname -a Linux pi1 4.9.14+ #977 Mon Mar 13 18:21:04 GMT 2017 armv6l GNU/Linux
Raspberry Pi1で実行可能なカーネルモジュールを作成するためには、Raspberry Pi1の環境でビルドしたカーネルモジュールが必要ですので、Pi1でカーネルソースを入手してカーネルモジュールをリビルドしました。
$ modinfo mainidmod.ko filename: /home/pi/myHome/mainid/mainidmod.ko license: Dual BSD/GPL srcversion: F8B01D2E75DE338550B6DF4 depends: vermagic: 4.9.14+ mod_unload modversions ARMv6 p2v8
Raspberry Pi1/Pi2/Pi3 のMIDR情報
システム制御コプロセッサのMIDR(Main ID Register)情報を取得しました。
Raspberry Pi1で実行
$ sudo su # insmod mainidmod.ko # rmmod mainidmod # dmesg | tail -3 [ 144.487678] Start Get_MainID [ 144.490684] MIDR =410fb767 [ 151.636213] End.. Get_MainID
Raspberry Pi2で実行
$ sudo su # insmod mainidmod.ko # rmmod mainidmod # dmesg | tail -3 [ 102.301629] Start Get_MainID [ 102.304637] MIDR =410fc075 [ 113.363000] End.. Get_MainID
Raspberry Pi3で実行
$ sudo su # insmod mainidmod.ko # rmmod mainidmod # dmesg | tail -3 [ 73.403137] Start Get_MainID [ 73.403155] MIDR =410fd034 [ 84.647938] End.. Get_MainID
Pi1 Pi2 Pi3のMIDR
カーネルモジュールのロードで、MIDRの値は下記のようになりました。
Pi1 : MIDR =410FB767
Pi2 : MIDR =410FC075
Pi3 : MIDR =410FD034
MIDR情報の説明
ARMサイトから「Technical Reference Manual」でMIDR情報を参照しました。
Pi1のMIDR情報
Implementer | 0x41 | ARM Limited |
Variant number | 0x0 | Major revision number |
Architecture | 0xF | given in the CPUID reg |
Primary part number | 0xB76 | ARM1176JZF-S |
Revision | 0x7 | r0p7 |
Pi2のMIDR情報
Implementer | 0x41 | ARM Limited |
Variant number | 0x0 | Major revision number |
Architecture | 0xF | ARMv7 |
Primary part number | 0xC07 | Cortex-A7 MPCore part number |
Revision | 0x5 | Minor revision number |
Pi3のMIDR情報
Implementer | 0x41 | ARM Limited |
Variant number | 0x0 | r0p4 |
Architecture | 0xF | Defined CPUID |
Primary part number | 0xD03 | Cortex-A53 processor |
Revision | 0x4 | r0p4 |
最後に
Raspberry Pi1,Pi2,Pi3のシステム制御コプロセッサ Main ID Register情報を読み出すことができました。デバイスドライバで、Pi1,Pi2,Pi3により異なる処理をする場合にMIDR情報は訳に立つかもしれません。