目次: Zephyr
Zephyrを最新にしたところSDKのバージョンが古いと怒られてしまいました。
Zephyr SDK 0.13にアップデートしたところ「Debian TestingにはPython 3.8が無くてGDBが動かない」問題が再発しました。Python 3.9を使い、不具合を治すパッチを当てないといけません(その1〜3を参照)が、以前と同様の方法ではダメなようです。
調べてみると少し仕組みが変わっています。バージョン0.12まではUpstreamのtarballを参照し、ローカルでパッチを持っていました。バージョン0.13はnewlib-nano, binutils, gcc, gdb, newlibについてはGitHubのZephyrプロジェクト以下にあるフォークされたソースコード(パッチ適用済み)を参照し、tarballを作成するように変更されました。
今まではローカルでパッチを当てる仕組みが動いていたため、パッチファイルを1つ追加するだけで修正を適用できましたが、0.13からローカルでパッチを当てる仕組み自体を使わなくなったため、パッチファイルを置いても修正が適用されなくなりました。困った。
バージョン0.12以前の設定と同じようにsdk-ng/patches/gdbの下にあるパッチファイルを見るようにする方法です。まずローカルパッチ機能を有効にするため、コンフィグを追加します。追加する場所はどこでも良い(順序は特にない)です。私はファイルの最後に追加しています。
# sdk-ng/configs/riscv64.config ... CT_PATCH_BUNDLED_LOCAL=y CT_LOCAL_PATCH_DIR="${CT_TOP_DIR}/../../patches"
注意点としてはGDBのバージョンは9.2ですが、パッチのディレクトリ名はtarballの名前に準じてgit-xxxxxxxxのようにしなければならないことです。ディレクトリ名を9.2にするとパッチが無視されます。例えば今回試した環境ではgit-76b05e96だったので、sdk-ng/patches/gdb/git-76b05e96/0007-gdb-fix-python3.9.patchのように置けば良いです。
もしgit-xxxxxxxxのバージョンがわからないときは、configs/riscv64.configのCT_GDB_DEVEL_REVISIONを見るとリビジョンが書いてありますが、ぶっちゃけ一旦ビルドしてみてビルドログを見た方が早いです。
動きにややクセがあるもののバージョン0.13だとこちらのほうが変更量が少なくスマートです。0.12でも同じ方法が使えると思いますが、未確認です。
Zephyr SDKの配下にあるCrosstool-NGはパッチセットを持っています。パッチセットに追加しておけば初回ビルド時(sdk-ng/share以下にファイルコピーが行われる)にパッチを持っていってくれます。例えばsdk-ng/crosstool-ng/packages/gdb/git-76b05e96/0007-gdb-fix-python3.9.patchのように置けばよいです。
注意点としては、その1同様の点でディレクトリ名(git-xxxxxxxx)に気をつけること、もう1つあって「コピーのタイミング」にクセがあることです。Crosstool-NGのパッチセットはsdk-ng/share配下にコピーされますが、これはgo.shの初回実行時しかコピーされません。
パッチファイルを追加するなど、再びコピーを実行してほしい場合sdk-ng/binとsdk-ng/shareを消してからgo.shを実行すると初回の処理が再実行されるようです。ただgo.shはヘルプが一切なく、私のやり方が正しいかどうか良くわからないのが欠点です……。
Crosstool-NGのパッチ当てを行っているスクリプトfunctionsはsdk-ng/crosstool-ng/scripts/functionsが元のスクリプトですが、Zephyr SDKのビルドでは初回ビルド実行時にsdk-ng/share/crosstool-ng/scripts/functionsにコピーされます。ビルド時はコピーしたスクリプトを実行します。
そのためスクリプトにログなどを入れたい場合、コピーの方(sdk-ng/share/crosstool-ng/scripts/functions)を改変しないと効果がないです。ご注意を。
Facebookは内蔵ブラウザで、Webサイトへのリンクを開きます。私はWebサイトはブラウザで開いてほしい(タブが残せるし、あとで閲覧履歴を確認することもできる)ので、この挙動はぜひとも無効化したいです。
今まで無効化する方法がわからなくて困っていましたが、今日、設定を頭から試していたら、
[設定] - [メディア] - [リンクを外部で開く]
をONにすると外部のブラウザで開いてくれることがわかりました。Webサイトってメディアか……?まあやりたいことはできたから良いか。
LINEも内蔵ブラウザでリンクを開きます。無効化したいですが、設定にそのような項目が見当たりません。うーん、嫌な挙動ですね。
メモ: 技術系の話はFacebookから転記しておくことにした。
目次: Kindle
初代Kindle Fire HDの話。
第七世代Kindle Fire HDもしくはKindle for PCの話。
Kindle用のAndroidタブレットの話。
Amazonそのものの話。
目次: Kindle
第七世代Kindle Fire HDの挙動がどんどんおかしくなってきています。前にも発生した(2018年11月17日の日記参照)、買った本を認識しなくなる病気です。ここのところおかしくなりすぎだぞ?頑張ってくれKindleさん。
前回はスクリーンショットを取り損ねたので、今回はスクリーンショット付きでお届けします。
本を買ったことを認識できていない機能としては、
逆に本を買ったことを認識できている機能としては、
です。そろそろファクトリリセットの時期なんですかね……?
ファクトリリセットは時間かかって嫌なので、なんとか直せないかなと頑張りましたけど、前回の解決策なども通じずじまいで駄目でした。
となりました。どうやっても「役立たずスキルに……」の3巻を読めません。困ったね。
TwitterでKindleの文句ばっかり言ってたせいか、最近Amazonのサポートデスクの人からTwitterでリプライをいただけることがあります。
たぶん世界中に私のようなヤツが一杯いるんでしょう。中の人も相当お疲れなようで、かなり機械的というか、マニュアルかなんかありそうな対応(最初にFAQに案内され、それでも駄目だって言うと、サポートデスクチャットを案内される)ですけど……。いやまあ、声掛けていただけるだけありがたいことですよね、うん……。
サポートデスクの人曰く、Amazonのトラブルシューティング(Amazon.co.jpヘルプ - Kindle本がライブラリに表示されない)を参考に試してみてほしいとのことでした。こんな内容です。
上から順に試してみると、6番目の「コンテンツと端末の管理を使用して、ご希望の端末に本を配信します。」が大当たりでした。スゲエ。この手のFAQ系の手順で直ったことって一切ないんで、これが初めてかも??
未読/既読、どこまで読んだか?情報はキレイさっぱり消えていました。配信したかどうかすら忘れてるんだもん、そりゃそうか。
とまあ、この通りKindleはいつ何が消えるか予想がつかないため、しおり、位置保存、などの機能は一切信用しませんし、使うこともないですね……。
Amazonサポートデスクの人に「なんで勝手に配信解除されたのでしょうか」ってTwitterで聞いたらシカトされました。悲しいよ。
今回に限らないですが、Amazonサポートデスクの人に「どうしたらいいですか?」と聞くと超スピードで答えてくれます(最終奥義は返金です)が、「どうしてこうなるんですか?」って聞くとシカトされる傾向にあります。Amazonは開発部門とサポート部門の距離が遠くて答えを持ってない、機密漏洩等を恐れて意図的に知らせていない、とかかな?
色々事情がありそうなことは察しますが、こちらも人間なのでシカトは辛いよね……。普通に「技術面の質問はわかりませんorお答えできかねます」って言ってくれたら「そうなのか〜」で終わりなんだけど。何か過去にモメごとでもあったのかもね?
目次: Linux
PCIデバイスを使った実験をする際にコンフィグ空間やメモリ空間を読み書きしたいときがあります。メモリ空間の読み書き程度ならば、わざわざPCIデバイスドライバを書かなくても /sys/bus/pci/devices/*/ にあるresourceNファイルにアクセスすれば良いです。
PCIデバイスはコンフィグ空間にBAR (Base Address Register) という32bitレジスタが6個あり、メモリ空間をPC側のアドレスのどこにマッピングするかを指定します。BARがそのままresourceNに対応しています。
最近は64bitアドレスでマッピングするデバイスも多いですが、その際は連続するBARを2つ使ってマッピング先のアドレスを指定します。実際に見たほうが早いと思うので、私の使っているマシンのグラフィックカードNVIDIA GeForce GT 1030を例にしましょう。
# lspci | grep VGA 08:00.0 VGA compatible controller: NVIDIA Corporation GP108 [GeForce GT 1030] (rev a1) # lspci -s 08:00.0 -v 08:00.0 VGA compatible controller: NVIDIA Corporation GP108 [GeForce GT 1030] (rev a1) (prog-if 00 [VGA controller]) Subsystem: Micro-Star International Co., Ltd. [MSI] GP108 [GeForce GT 1030] Flags: bus master, fast devsel, latency 0, IRQ 84, IOMMU group 14 Memory at f6000000 (32-bit, non-prefetchable) [size=16M] ★BAR0: resource0 Memory at e0000000 (64-bit, prefetchable) [size=256M] ★BAR1: resource1(64bitアドレス空間なのでBAR2も使われる) Memory at f0000000 (64-bit, prefetchable) [size=32M] ★BAR3: resource3(64bitアドレス空間なのでBAR4も使われる) I/O ports at d000 [size=128] ★BAR5: resource5 Expansion ROM at 000c0000 [virtual] [disabled] [size=128K] Capabilities: [60] Power Management version 3 Capabilities: [68] MSI: Enable- Count=1/1 Maskable- 64bit+ Capabilities: [78] Express Legacy Endpoint, MSI 00 Capabilities: [100] Virtual Channel Capabilities: [128] Power Budgeting <?> Capabilities: [420] Advanced Error Reporting Capabilities: [600] Vendor Specific Information: ID=0001 Rev=1 Len=024 <?> Capabilities: [900] Secondary PCI Express Kernel driver in use: nvidia Kernel modules: nvidia
デバイスの位置(08:00.0)と、マッピングしているアドレスがBAR0, 1, 3, 5の4つ あることがわかります。/sys/bus/pci/devices経由でPCIデバイスのBAR1でマップされているメモリを読み出します。
# cd /sys/bus/pci/devices/0000\:08\:00.0/ # ma -k resource1 dd 0 00000000 ff000020 ff00082c ff000020 ff00082c 00000010 ff3c0020 ff42082c ff990020 ffa50027 00000020 ffa10020 ffa10027 ffa50020 ff990027 00000030 ff420020 ff3c0027 ff000020 ff000027 00000040 ff000020 ff000027 ff000020 ff000027 00000050 ff000020 ff000027 ff000020 ff000027 00000060 ff000020 ff000027 ff000020 ff000027 00000070 ff000020 ff000027 ff000020 ff000027 00000080 ff000020 ff000027 ff000020 ff000027 00000090 ff3c0020 ff420027 ffb90020 ffa50027 000000a0 ffa50020 ffb90027 ffa90020 ffa50027 000000b0 ff420020 ff3c0027 ff000020 ff000027 000000c0 ff000020 ff000027 ff000020 ff000027 000000d0 ff000020 ff000027 ff000020 ff000027 000000e0 ff000020 ff000027 ff000020 ff000027 000000f0 ff000020 ff000027 ff000020 ff000027 00000100
読み出しツールは何を使っても構いませんが、サイズがめっちゃでかい(256MB)ので「頭から読む系のツール(hexdumpやテキストエディタ)」は使わないほうが無難です。今回は拙作のmemaccess(GitHubへのリンク)を使いました。
ちなみにresourceNを読みだそうとすると怒られるときは、NVIDIAのドライバをロードしていないかチェックしてみてください。
# ma -k resource0 dd 0 mmap: Invalid argument # cat /proc/iomem ... e0000000-fec2ffff : PCI Bus 0000:00 e0000000-f1ffffff : PCI Bus 0000:08 e0000000-efffffff : 0000:08:00.0 f0000000-f1ffffff : 0000:08:00.0 f6000000-f70fffff : PCI Bus 0000:08 f6000000-f6ffffff : 0000:08:00.0 f6000000-f6ffffff : nvidia ★BAR0をnvidiaドライバが使用中なのでmmapできない f7080000-f7083fff : 0000:08:00.1 f7080000-f7083fff : ICH HD audio ... # rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia # cat /proc/iomem ... e0000000-fec2ffff : PCI Bus 0000:00 e0000000-f1ffffff : PCI Bus 0000:08 e0000000-efffffff : 0000:08:00.0 f0000000-f1ffffff : 0000:08:00.0 f6000000-f70fffff : PCI Bus 0000:08 f6000000-f6ffffff : 0000:08:00.0 ★nvidiaドライバがアンロードされた f7080000-f7083fff : 0000:08:00.1 f7080000-f7083fff : ICH HD audio ... # ma -k resource0 dd 0 00000000 138000a1 00000000 00000000 bad00200 00000010 bad00200 bad00200 bad00200 bad00200 00000020 bad00200 bad00200 bad00200 bad00200 00000030 bad00200 bad00200 bad00200 bad00200 00000040 bad00200 bad00200 bad00200 bad00200 00000050 bad00200 bad00200 bad00200 bad00200 00000060 bad00200 bad00200 bad00200 bad00200 00000070 bad00200 bad00200 bad00200 bad00200 00000080 0000008f bad00200 bad00200 bad00200 00000090 bad00200 bad00200 bad00200 bad00200 000000a0 bad00200 bad00200 bad00200 bad00200 000000b0 bad00200 bad00200 bad00200 bad00200 000000c0 bad00200 bad00200 bad00200 bad00200 000000d0 bad00200 bad00200 bad00200 bad00200 000000e0 bad00200 bad00200 bad00200 bad00200 000000f0 bad00200 bad00200 bad00200 bad00200 00000100
ドライバが管理しているメモリを横から読み書きされたらたまったもんじゃないですから、この挙動は当然ですね。え?読み出しなら良いのでは?と思われるかもしれませんが、読み出しをトリガーに動作したり、読み出すと値が変化するレジスタなどは珍しくないので、勝手に読み出すのも実はダメなのです。
先ほど /sys/bus/pci/devices以下のファイルをls -lなどで見た方はお気づきかと思いますが、rootしか読めないようなパーミッションになっています。
# cd /sys/bus/pci/devices/0000\:08\:00.0/ # ls -l resource* -r--r--r-- 1 root root 4096 8月 2 22:08 resource -rw------- 1 root root 16777216 8月 2 22:10 resource0 -rw------- 1 root root 268435456 8月 2 22:10 resource1 -rw------- 1 root root 268435456 8月 2 22:10 resource1_wc -rw------- 1 root root 33554432 8月 2 22:10 resource3 -rw------- 1 root root 33554432 8月 2 22:10 resource3_wc -rw------- 1 root root 128 8月 2 22:10 resource5
誰でもデバイスのメモリにアクセスできるのはマズいですから、セキュリティ上この設定は真っ当です。真っ当ですが、実験に使うときはいちいちsudoするのが面倒なのも事実です。手動でchmodやchownしてパーミッションを変えればsudo不要にできますが、いくつか欠点があります。
どこにいるかわからないデバイスを操作したいときは、udevの出番です。
前置きが長くなりましたが、やっと本題です。/etc/udev/rules.dに99-hogehoge.rulesのようなファイルを作ります。全てのPCIデバイスのパーミッションを全開にする必要はないので、ベンダーIDとデバイスIDでGeForce GT 1030だけ該当するようにフィルタリングしましょう。
# lspci -s 08:00.0 08:00.0 VGA compatible controller: NVIDIA Corporation GP108 [GeForce GT 1030] (rev a1) # lspci -s 08:00.0 -n 08:00.0 0300: 10de:1d01 (rev a1) | `--- Device ID `--- Vendor ID
他の条件をフィルタリングに使いたいときは、udevadm infoを使うと、vendorやdeviceも含んだ全ての属性を見ることができます。
# udevadm info -a -p /sys/bus/pci/devices/0000:08:00.0 | less ... looking at device '/devices/pci0000:00/0000:00:03.1/0000:08:00.0': KERNEL=="0000:08:00.0" SUBSYSTEM=="pci" DRIVER=="" ATTR{ari_enabled}=="0" ... ATTR{revision}=="0xa1" ATTR{subsystem_device}=="0x8c98" ATTR{subsystem_vendor}=="0x1462" ATTR{vendor}=="0x10de" ★ベンダーID ...
IDが判明したらルールファイルを書きます。/sys/bus/pci/devices/* のディレクトリと配下のファイル全てにgroupとotherのRead/Writeパーミッションを付加します。%pは設定中のデバイスのパスが入る変数です。
SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{device}=="0x1d01", RUN+="/bin/chmod -R go+rw /sys%p"
注意点は「RUNはシェルじゃない」ことです。パスの補完、ワイルドカード、パイプ、リダイレクトなどは使えません。私は最初resource* と書いて「そんなファイルはない」と言われたり、/bin/chmodなのに /usr/bin/chmodと書いていて、何も実行されなくて悩みました(Ubuntuは /usr/bin/chmodだったりするので、さらにややこしいです)。
# udevadm trigger # cd /sys/bus/pci/devices/0000\:08\:00.0/ # ls -l resource* -r--rw-rw- 1 root root 4096 8月 2 23:10 resource -rw-rw-rw- 1 root root 16777216 8月 2 23:10 resource0 -rw-rw-rw- 1 root root 268435456 8月 2 23:10 resource1 -rw-rw-rw- 1 root root 268435456 8月 2 23:10 resource1_wc -rw-rw-rw- 1 root root 33554432 8月 2 23:10 resource3 -rw-rw-rw- 1 root root 33554432 8月 2 23:10 resource3_wc -rw-rw-rw- 1 root root 128 8月 2 23:10 resource5
ルールファイルを書いたら設定を反映させると、resourceNファイルのパーミッションが変わっているはずです。変わっていない場合はおそらくルールの書き方が間違っているので、修正が必要です。
むしろこちらが本題かもしれません。udevのRUNルールは「シェルじゃない」ので、普段シェル上で使っているコマンドをコピペしてもまず動かないです。間違っている場合は主に2パターンで、
前者に関してはRUNでログを出すとわかります。例えばRUN+="/usr/bin/logger AAAAAAAA" のようにすると、udevadm triggerを実行した後に /var/log/syslogにメッセージが出ます。
ログが出なければフィルタリングの条件を全部削って試してください。それでもログが出なければおそらくloggerのパスが間違っています。which loggerで出てくるパスとRUNに書いたパスが合っているか確認してください。特に /binと /usr/binは間違えやすいです。
後者に関してはRUNに書いたコマンドが失敗するとsyslogにエラーが記録されるはずですので、間違ってワイルドカードやパイプなどを書いていないかチェックしてみると良いです。
Aug 1 22:56:51 blackbird systemd-udevd[2775846]: 0000:08:00.0: Process '/bin/chmod -R go+rw /sys/devices/pci0000:00/0000:00:03.1/0000:08:00.0*' failed with exit code 1.
ログを見てもすぐにわからないような場合は、地道に「コマンド名だけにして実行されるか?」「引数を1つずつ足していって動くか?」を確認するのが一番良いです。
< | 2021 | > | ||||
<< | < | 08 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | - | - | - | - |
合計:
本日: