先週、大阪スバル(高槻店)にレガシィの車検をお願いしていました。今日は納車です。
JR 高槻駅からディーラーまで歩きましたが、もう、とにかく暑い暑い。暑くてやってられません。将来、車を買い替えるとしたら、夏には絶対、車は買わないぞ、絶対だ。心に決めました。
料金は自賠責&税金込みで 13万円くらいでした。特に大きな故障もなかったし、そんなもんでしょう。ね。
先日購入(2018年 6月 14日の日記参照)した ThinkPad E480 ですが、キーボードのカーソルキー、しかも上カーソルキーだけが微妙に壊れています。
キーを押すとキーが傾いてしまい、引っかかって戻ってこないときがあります。
何が引っかかっているのか調べるために分解してみました。キートップをてこなどで外すと、パンタグラフが入っています。パンタグラフは 2つの部品からできています。
2つの部品を組み合わせると、I 字型(畳んでいるとき)もしくは X 字型(開いているとき)になります。
良く見るとこの部品、軸が折れてしまっています。
軸が片側なくなっているため、パンタグラフを開いても綺麗な X 字型にならず、捻じれてしまいます。
キーボードのパンタグラフ、開いた状態、軸が折れているので歪む
これによってキートップが若干傾いてキーボードのフレームに引っかかり、元の位置に戻らなくなるようです。
修理に出そうかどうか迷って、いろいろ押し方を試しているうちに、比較的引っかかりにくい押し方があることを見つけました。今は押し方を工夫することで凌いでいます。
さらに最近は、普通にキーを押しても引っかかりにくくなった気がします。パンタグラフが壊れているのは相変わらずなので、キートップ側が削れたのか、変形したのかな?
久しぶりに自作 ARM エミュレータ ememu を(ソースコードはこちら)動かそうと思い、Linux 4.4 の latest である、Linux 4.4.146 をダウンロードしました。
この ememu では ARM Versatile PB/AP ボードの一部デバイスと、CPU ARM926EJ-S の一部、アーキテクチャで言えば ARMv5T 相当をエミュレーションしています。
巷で手に入るコンパイラは ARMv5T より新しい命令を出力してしまい、エミュレータで実行できませんので、最初に crosstool-ng で、ARMv5T 向けの gcc 8.1.0 を作成しました。
いざ Linux 4.4.146 をクロスビルドしましたが、エラーになり、コンパイルできませんでした。
エラーの意味が良く分からなかったので、さっくり諦めまして crostool-ng で gcc 7.3 を作成しなおし、ビルドをやり直したところ、無事コンパイルが通りました。
Linux 4.4.146 は起動しませんでした。偶然持っていた少し古いバージョン(Linux 4.4.77)に戻したりもしましたが、結果は同じで全く起動しません。
デバッグすると、ドライバの作りが変わったのか AACI と MMCI というハードウェアに対して、今まで叩いていなかったはずのレジスタをガンガン叩いていました。ememu は存在しない I/O レジスタを叩くと、エミュレータが例外で落ちてしまい、動かなくなるんです…。
とりあえずレジスタ定義だけ適当に追加したところ、エラーが出まくりますが、起動はしました。適当でも動いてくれる Linux は強い子です。
しかし今度は buildroot で作成した busybox と愉快な仲間たちが起動しません。/dev/null が無いよ?と永遠にエラーが出続けます。
調べてみると Linux 4.4.146 の defconfig だと CONFIG_DEVTMPFS が n つまり無効なんですね。最近の感覚で devtmpfs はあって当然くらいに思っていたので、盲点でした。コンフィグで devtmpfs を有効にしてカーネル再ビルドしたところ、やっと buildroot が動きました。
対応していない制御文字を送ってきているらしく、ememu の端末(独自実装です)の色がおかしくなります。
これはすぐ直せそうになかったので、しばらくは変な表示と付き合うことになりそうです。
誰しもお気に入りのエディタがあると思いますが、私は割とメチャクチャです。
C 言語系は読むときは Vim + GNU Global、書くときはサクラエディタを使うことが多いです。
Vim はタグジャンプやヒストリが優秀で、検索もしやすいので、コードを読む際にはとても便利だと思います。ログを差し込んだり、コードを多少書き換える程度であれば Vim で済ませます。
しかし 1から全て書くような場合は、サクラエディタが多いです。何ででしょうね?関数表示が便利なのかな?そんなサクラエディタも C++ を書くときはイマイチで、ラムダがまともに表示されず不便です。
GVim で tab と :Tlist を使うとサクラエディタの関数表示に近くて、個人的には良い感じですが、常用には至っていません。何が悪いのかわからない…。
Java は読むことはあまり無いけど Vim ですかね、書くときは IntelliJ IDEA です。スクリプト系は Vim で読むし、書きます。
こうして並べてみると、かなり支離滅裂です。どうしてこうなった…??
Vim も Emacs も初めて使ったとき「は?何だこれ……??」と思いました。どちらも終了方法がわからず、まともに使えませんでした。今は IDE も Vim も適度に使っています。
でも Emacs は完全に使い方を忘れてしまった。ごめんね Emacs…。
AIG 損害保険から「大阪北部地震で被害を受けた方はご連絡ください」という手紙が来て、地震保険に加入していたことを知りました。ずっと火災保険だと思ってたよ……。
人生初の地震保険です。
保険会社に被害を申請(電話、Web でも可能)すると、調査員さんが家に来てくれます。調査員の方は、かなり積極的に被害としてカウントしてくれます。むしろ、こちらが「いやー、そこは特に被害無かったですね…」と断るような形になるくらいでした。
家財の場合、壊れなくても、地震で倒れたりズレたら被害としてカウントされるそうです。あと、地震保険で特徴的なのは、被害を受けた「種類」が大事なことです。本が 1冊でも 100冊でも、カウントは「本」の 1種類のみですが、棚とテレビと冷蔵庫が地震でズレたり倒れたりすれば 3種類としてカウントされ、被害が大きいとみなされるようです。
地震保険は火災保険と違い損害額ではなく、保険金額(契約時に決めている額面)の何割という形で支払われます(地震保険 | 個人のお客さま | AIG 損保へのリンク)。
我が家の場合、家財の「一部損」判定でした。この場合、地震保険金額の 5%が支払われることになります。契約していた保険金額は 100万円くらいだった(それも知らなかった…)ので、支払われる額は大体 5万円です。
大阪北部在住で、地震保険に加入している人は、とりあえず被害申請をしてみるといいですね。判定結果が一部損(一番低い)でも、地震でグチャグチャにされた部屋の片づけ手間賃くらいにはなると思います。
査定は結構面白いです。馬のフィギュアがテーブルから落ちてたら「被害です」、お皿が落ちたり転げたら割れてなくても「被害です」。逆に言うと、壊れた物の金額は勘案しないので、被害の受け方によっては被害額と保険の査定額が全く合いません。
しかし元々そういう保険なんです。火災保険や自動車保険とは仕組みが違うのですね。
AIG 損害保険の調査員の方曰く、大阪北部地震と 7月豪雨の被害調査を迅速に行うため、全国の調査員が応援に駆けつけているのだとか。今日来ていただいた方も北海道から応援に来ていると言っていました。
最近は特に暑いし、特に豪雨の地域では道路がやられていて、被災地を駆け回るにもとても大変らしいです。頭が下がる思いです。
最近の ARM 搭載 SoC はかなり速くなっています。もしかして x86 PC の代わりに使えるのではないでしょうか?開発に使うことを想定して、コンパイル速度を比較してみたいと思います。
比較に使うのは Linux Kernel の開発ツリー(linux-next)です。コンフィグはデフォルトを使い、ビルドターゲットは all を指定します。ビルドしているアーキテクチャが違う(ROCK64: arm64, AMD A10: x86)ので、時間の単純比較はできませんが、参考にはなると思います。
AMD A10 7800、32GB DDR3-1600 の PC で linux-next x86 の time make -j4 all を実行しますと、
不遇の Bulldozer 系コア、もはや 4年落ちとなった CPU で、大して速くはありませんが、十分実用的というか、待っていられるレベルです。
Intel Pentium J4205、16GB DDR3L-1600 の PC で linux-next x86 の time make -j4 all を実行すると、
Pentium J は Atom 系列で遅いと思いきや、予想より何倍も速かったです…。ナメてました、ごめんなさい。
ROCK64、Rockchip RK3328、Cortex A53 x 4、4GB DDR3 で linux-next arm64 の time make -j4 all すると、
PC と比較するとほぼ 1桁遅いです。さすがにこれは待っていられません。ROCK64 は普段使いには十分速いですが、開発に使うのは辛そうですね…。
Raspberry Pi 3、Broadcom BCM2837、Cortex A53 x 4、1GB LPDDR2 で linux-next arm の time make -j4 all すると、
ビルドしているアーキテクチャが違う(ROCK64 は arm64、RasPi 3 は arm)ので、単純比較はできませんけど、ROCK64 と大差ないですね。
今のところスマホ、TV/STB 系 ARM SoC は A72 x 4、A53 x 4 が最強クラスのようです。サーバー系 ARM SoC に目を向ければ A72 x 16(NXP LX2160A)もしくは A53 x 24 や A53 x 48(Cavium ThunderX)といった桁違いメニーコアがありますが、そんなに要らないんですよね…。
中間の製品はありません。買う人いないんでしょうね。
今後のお買い物の参考に、ざざっと調べてみました。
性能だけ求めるなら Jetson か HiKey 960 で、コスパなら NanoPC-T4 ですかね。Jetson なら流行りの AI とか、GPGPU も実験できますね。お値段はべらぼうですけど…。
自分のマシンは何 GFLOPS か知りたくなって、スパコン界隈で有名な LINPACK を実行してみようと思い立ちました。ソースコードは HPL- A Portable Implementation of the High-Performance Linpack Benchmark for Distributed-Memory Computers にあります。私は hpl-2.2.tar.gz を使用しました。
ビルド方法は INSTALL ファイルに書いてある通りですが、結構ハマったので、私の手順もメモしておきます。環境は Debian GNU/Linux Testing の amd64 版です。
コードを展開し、setup ディレクトリの下にある Make.xxx をトップディレクトリにコピーして使います。たくさんファイルがありますが、Athlon マシンなので Linux_ATHLON_CBLAS を選びました。FBLAS という名前のファイルもありますが、
のようです。用語の意味はわかりませんが、Makefile の diff を見れば何となくわかるはず、きっと。
コピーしてきた Make.Linux_ATHLON_CBLAS は書き換える必要があります。特に大事なのは TOPdir です。
この変更を忘れるとホームディレクトリ直下の hpl というディレクトリがトップディレクトリだと思って、ビルドを始めます。最終的に「Make.inc が見つからない」と言われて失敗します。
Make.inc を find で探すとわかりますが Make.inc はシンボリックリンクです。ビルドに失敗するときは Make.inc が全然関係ない場所を指していると思います。
もし TOPdir を書き換え忘れてビルドが失敗した場合は make arch=Linux_ATHLON_CBLAS clean_arch としてください。アーキテクチャ名の付いたディレクトリ(Make.inc もそのディレクトリに入っている)が全て消滅するはずです。
# TOPdir をソースコードを配置した位置に合わせて修正します TOPdir = ... # コンパイラを gcc から mpicc にします CC = /usr/bin/mpicc # リンカも gcc から mpicc にします LINKER = /usr/bin/mpicc # OpenMPI のライブラリ位置 MPdir = /usr/lib/x86_64-linux-gnu MPinc = -I$(MPdir)/openmpi/include # ビルドしたバイナリが動かなくなるため、MPlib は削除 #MPlib = ... # LAlib のライブラリ位置 LAdir = /usr/lib/x86_64-linux-gnu # スタティックリンクだとなぜか遅いので、ダイナミックリンクに変更 LAlib = -lcblas -latlas # 末尾に -lrt -lbacktrace を追加します。 # HPL_LIBS の先頭に追加するとリンクエラーになります。 HPL_LIBS = ... -lrt -lbacktrace
あと、私の環境の場合、下記パッケージのインストールが必要でした。
実行はまた今度にします。
LINPACK のビルドができたので、さっそく実行してみます。バイナリは bin ディレクトリの下にあります。
実行の仕方は mpirun -n 4 xhpl のようにします。パラメータファイル(HPL.dat)が置いてあるディレクトリで実行してください。
これが最速パラメータかどうか自信がありませんが、とりあえず 10GFlops だそうです。
しかし hdk 氏の AMD A10-7870K は 19GFlops 出ているそうです。両者ともに Bulldozer 系の APU なのに、倍も差がつく理由がさっぱりわかりません。謎です…。
何気なく cblas と atlas のスタティックリンクをやめて、ダイナミックリンクに変更したところ、いきなり性能が上がり 1.7倍の 17GFlops になりました。
AMD A10-7800 での実行結果(ダイナミックリンク版)
えー?なぜ!?とりあえず perf top で見てみると libatlas.so の関数が 8割ほどの実行時間を占めています。ここが効率的になったんでしょうか?そんなに変わるものですかね、さっぱり意味がわかりません…。
ROCK64 でも実行してみました。SoC は Rockchip RK3328、CPU は Cortex-A53 x 4 です。
大体 1.5GFlops でした。A10-7800 と比べるとやはり 1桁違いますね(PC が 6.7倍速い)(ダイナミックリンク版だと 11倍速い)。
コンパイル実験(2018年 8月 12日の日記参照)のときは PC が 18倍ほど速かったので、コンパイル実験よりは差が縮まっている、とも取れます。
電力効率の点から見ると、PC 1台より ROCK64 を 10台並べた方が省エネなのでしょうか?微妙かな…?今度、ワットチェッカーで比べてみましょうか。
LINPACK を単独のマシンで実行してもあまり面白くないので、クラスタで実行したいと思います。役割としてはマスタが 1台、スレーブが他全部という分担になります。LINPACK の場合、マスタからスレーブに ssh でログインして、ログイン後 xhpl を実行するようです。
スレーブ側は LINPACK をコンパイルして、xhpl をマスタと同じパスに配置すれば OK です(HPL.dat は要らない)。マスタ側のバイナリが /home/username/a/b/c/xhpl に置かれているとしたら、スレーブ側も同じ /home/username/a/b/c/xhpl ディレクトリに置かなければ起動できないようです。
一番簡単なのはマスタ、スレーブ、全てのノードに同じユーザを作成して、MPI 実行用のバイナリを入れるディレクトリを作成することですね。
さらにスレーブは ssh の公開鍵認証にしておくと、LINPACK 起動時にパスワードを打たなくて良いので楽です。マスタからスレーブにログインできれば OK で、スレーブからマスタにログインする設定は不要です。
マスタ側は LINPACK をコンパイルするのは当然として、少しだけ特別な設定が必要です。私は hostfile の存在に気づくまでにかなり時間がかかりました…。
HPL.dat は単独動作と同じで良いです。性能は後で考えるとして、とりあえず動作するはずです。
クラスタのノード一覧 hostfile は単独のときには使っていませんでした。基本的にはクラスタを構成するノードのホスト名(IP アドレスでも良いです)を並べるだけです。
localhost slots=4
192.168.1.109 slots=4
上記は 2台構成(ROCK64 が localhost、Raspberry Pi 3 が 192.168.1.109)の記述です。slots= にはそのノードがいくつのプロセスを扱えるかを記述します。どちらも 4コア 4スレッドの CPU なので slots=4 としています。まあ 2 とか 8 とかにしても動きますが、効率は下がります。
実行は下記のようにします。ROCK64 がマスタ、Raspberry Pi 3 がスレーブです。下記のコマンドはマスタ側で実行してください。
$ cd bin/Linux_ATHLON_CBLAS $ ls HPL.dat hostfile xhpl $ mpirun -n 8 -hostfile hostfile -host localhost,192.168.1.109 xhpl ... ================================================================================ T/V N NB P Q Time Gflops -------------------------------------------------------------------------------- WR00L2L2 2000 64 1 4 3.74 1.429e+00 HPL_pdgesv() start time Wed Aug 15 00:11:49 2018 HPL_pdgesv() end time Wed Aug 15 00:11:53 2018 -------------------------------------------------------------------------------- ||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)= 0.0037309 ...... PASSED ...
MPI の凄いところは ROCK64(arm64)と RasPi(arm)のようにアーキテクチャが違うクラスタでも実行できてしまうところです。メッセージパッシングの隠れた利点かもしれません。
動作しているかどうか確認するには Raspberry Pi 3 側で top などで見るのが確実だと思います。LINPACK 実行中に xhpl が 4プロセス実行されているはずです(全力で実行した場合)。
ちなみに hostfile を指定し忘れるとこんなエラーになります。8プロセス起動しろと言われても、どのノードがプロセスをいくつ受け持ってくれるかわからないので、怒っている訳ですね。
$ mpirun -n 8 -host localhost,192.168.1.109 xhpl -------------------------------------------------------------------------- There are not enough slots available in the system to satisfy the 8 slots that were requested by the application: xhpl Either request fewer slots for your application, or make more slots available for use. --------------------------------------------------------------------------
それと OpenMPI のバージョンには注意してください。我が家のデスクトップ PC(Debian Testing, OpenMPI 3.1.1)とファイルサーバ(Debian Stable, OpenMPI 2.0.2)で x86_64 クラスタを構成しようとしたところ、OpenMPI のバージョン違いでこんなエラーになって実行できませんでした。
$ mpirun -n 4 -hostfile hostfile -host localhost,falcon xhpl [blackbird:29131] tcp_peer_recv_connect_ack: invalid header type: 0 ★★★★こんなエラーで怒られる★★★★ -------------------------------------------------------------------------- ORTE was unable to reliably start one or more daemons. This usually is caused by: * not finding the required libraries and/or binaries on one or more nodes. Please check your PATH and LD_LIBRARY_PATH settings, or configure OMPI with --enable-orterun-prefix-by-default * lack of authority to execute on one or more specified nodes. Please verify your allocation and authorities. * the inability to write startup files into /tmp (--tmpdir/orte_tmpdir_base). Please check with your sys admin to determine the correct location to use. * compilation of the orted with dynamic libraries when static are required (e.g., on Cray). Please check your configure cmd line and consider using one of the contrib/platform definitions for your system type. * an inability to create a connection back to mpirun due to a lack of common network interfaces and/or no route found between them. Please check network connectivity (including firewalls and network routing requirements). --------------------------------------------------------------------------
エラーメッセージはたくさん出ますが、解決に辿り着かないので何とも言えない気分です…。
結論から言ってしまえば ROCK64 と Raspberry Pi 3 のクラスタは意味がなさそうです。なぜなら ROCK64 1台のほうが速いからです…。
まずは単独実行と同じ問題サイズ N=2000 での実行結果です。多少上下しますが 0.6〜0.7GFlops くらいです。ROCK64 単独(1.4GFlops)の半分以下です。P, Q の値は 2, 4 が一番良さそうでした。他の値(1, 8 や 4, 2)にすると激遅で実行が終わりません。
$ mpirun -n 8 -hostfile hostfile -host localhost,192.168.1.109 xhpl ... ================================================================================ T/V N NB P Q Time Gflops -------------------------------------------------------------------------------- WR00R2L4 2000 64 2 4 7.97 6.699e-01 HPL_pdgesv() start time Wed Aug 15 00:41:15 2018 HPL_pdgesv() end time Wed Aug 15 00:41:22 2018 -------------------------------------------------------------------------------- ||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)= 0.0037423 ...... PASSED ================================================================================ T/V N NB P Q Time Gflops -------------------------------------------------------------------------------- WR00R2C2 2000 64 2 4 7.94 6.724e-01 HPL_pdgesv() start time Wed Aug 15 00:41:23 2018 HPL_pdgesv() end time Wed Aug 15 00:41:31 2018 ...
問題サイズが小さすぎたかな?と思い N=4000 にしてみました。0.9〜1.3GFlops とだいぶ性能が上がります。単独実行の場合 N=2000 と N=4000 ではほぼ性能に変化はありません。
$ mpirun -n 8 -hostfile hostfile -host localhost,192.168.1.109 xhpl ... ================================================================================ T/V N NB P Q Time Gflops -------------------------------------------------------------------------------- WR00L2L2 4000 64 2 4 32.17 1.327e+00 HPL_pdgesv() start time Wed Aug 15 00:50:32 2018 HPL_pdgesv() end time Wed Aug 15 00:51:04 2018 -------------------------------------------------------------------------------- ||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)= 0.0018773 ...... PASSED ================================================================================ T/V N NB P Q Time Gflops -------------------------------------------------------------------------------- WR00L2L4 4000 64 2 4 40.92 1.043e+00 HPL_pdgesv() start time Wed Aug 15 00:51:04 2018 HPL_pdgesv() end time Wed Aug 15 00:51:45 2018 ...
性能が違うノードを組み合わせているからなのか、放熱が足りなくてオーバーヒートしているのか、性能がかなり不安定です。たまに System 負荷が 50%台に張り付いて、実行が終わらなくなるときもあります。うーん、たった 2台でも難しいものだな。
先日(2018年 7月 23日の日記参照)ROCK64 の U-Boot が distro boot(U-Boot の distro boot の説明)を使っていることはわかりましたが、もう少し具体的に調べておきます。
U-Boot は起動するとカウントダウンを始めます(Hit any key to stop autoboot... と表示される通り、何かキーを押すと止まります)。カウントが 0 になると、bootcmd 環境変数に設定されたスクリプトを実行します。まずはそこから追います。
U-Boot 2017.09-g5aef9f7 (Oct 12 2017 - 09:11:39 +0000), Build: jenkins-linux-build-rock-64-136 Model: Pine64 Rock64 DRAM: 4 GiB MMC: rksdmmc@ff500000: 1, rksdmmc@ff520000: 0 *** Warning - bad CRC, using default environment In: serial@ff130000 Out: serial@ff130000 Err: serial@ff130000 Model: Pine64 Rock64 normal boot Net: eth0: ethernet@ff540000 Hit any key to stop autoboot: 0 => => print bootcmd bootcmd=run distro_bootcmd => print distro_bootcmd distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done => print boot_targets boot_targets=mmc0 mmc1 usb0 pxe dhcp => print bootcmd_mmc0 bootcmd_mmc0=setenv devnum 0; run mmc_boot => print bootcmd_mmc1 bootcmd_mmc1=setenv devnum 1; run mmc_boot
今回追いかける対象は SD カードからのブート(ROCK64 の場合は mmc1 として認識)ですので、mmc0, mmc1 に注目します。bootcmd -> distro_bootcmd -> bootcmd_mmc1 -> mmc_boot と辿れます。ここまでは単純です。
環境変数: devnum=1 ---------- => print mmc_boot mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi ---------- 改行入れた版 if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi ---------- if の条件式だけ実行した場合 => mmc dev 0 Card did not respond to voltage select! ★★★失敗する mmc_init: -95, time 9 => mmc dev 1 switch to partitions #0, OK ★★★成功する mmc1 is current device
このスクリプトは mmc デバイスを使えるかどうかチェックしています。devnum=1 のときは mmc dev 1 ですね。単独で実行するとわかりますが、このコマンドは成功し、デバイスが使用可能だとわかります。
デバイスが使用可能だとわかれば、scan_dev_for_boot_part を呼びます。
環境変数: devnum=1 devtype=mmc ---------- => print scan_dev_for_boot_part scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done ---------- 改行入れた版 part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done ---------- 最初の行 => part list mmc 1 -bootable aaa ★★★aaa は結果を格納する環境変数名(何を指定しても OK) => prin aaa aaa=6 ★★★boot 可能パーティション番号が設定される 全部のパーティションを表示 => part list mmc 1 Partition Map for MMC device 1 -- Partition Type: EFI Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00000040 0x00001f7f "loader1" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: 9bdf460d-26ba-4f39-b43f-e8289847b709 2 0x00001f80 0x00001fff "reserved1" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: 50b5d36d-c009-4538-925e-a4ca3db6f3b9 3 0x00002000 0x00003fff "reserved2" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: cbcf51cb-465b-47ee-a4ca-1c1ef59a8564 4 0x00004000 0x00005fff "loader2" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: fd2b2a59-fb82-4e11-827b-2297cdb0b74f 5 0x00006000 0x00007fff "atf" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: 10194a7e-66c7-4340-a932-060295f19fba 6 0x00008000 0x0003ffff "boot" attrs: 0x0000000000000004 ★★★6 に boot 可能フラグが存在 type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 guid: dbb99d65-e937-46a9-b740-256da98658a0 7 0x00040000 0x01cf7fde "root" attrs: 0x0000000000000000 type: 0fc63daf-8483-4772-8e79-3d69d8477de4 guid: 55c58d2b-29ce-4c0d-bfec-414479e8ca46 ---------- 2行目 => part list mmc 1 -bootable aaa => print aaa aaa=6 => env exists aaa || setenv aaa 1; ★★★左のコマンド結果が真のため、右のコマンドは実行されない => print aaa aaa=6 ★★★値は変わらない => setenv aaa ★★★環境変数を削除する => print aaa ## Error: "aaa" not defined => env exists aaa || setenv aaa 1; ★★★左のコマンド結果が偽のため、右のコマンドが実行される => print aaa aaa=1 ★★★値が 1 に設定される ---------- if の条件式 => fstype mmc 1:6 bootfstype => prin bootfstype bootfstype=fat
1行目は boot 可能フラグを持ったパーティションがあるかどうかを見ています。あれば devplist 環境変数に「パーティションの番号」が設定されます。
2行目は boot 可能フラグを持ったパーティションがなかったときのフェールセーフ処理で、先頭パーティション(1番)から起動を試みます。
ループ内の if 文はパーティションのファイルシステム形式を取得して、bootfstype という環境変数に設定します。ファイルシステムがわからない場合は処理をやめます。
あと、ループの条件文のところで distro_bootpart に devplist に格納されているパーティション番号(今回の場合は 6)が設定されます。これも後で使われます。
環境変数: devnum=1 devtype=mmc distro_bootpart=6 bootfstype=fat ---------- => print scan_dev_for_boot scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi; ---------- 改行入れた版 echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; ★★★成功すれば、以降は実行されない(他の scan_dev_xxx も同様) run scan_dev_for_scripts; done; run scan_dev_for_efi; ---------- boot_prefixes の内容 => print boot_prefixes boot_prefixes=/ /boot/
メッセージを出して、scan_dev_for_xxx のいずれかを実行します。これらのスクリプトは成功すると、OS つまり Linux などに制御が移りますので、成功したら U-Boot に戻りません。試す順は下記のようです。
今回は distro boot を使っていますので、scan_dev_for_extlinux スクリプトを見ます。
環境変数: devnum=1 devtype=mmc distro_bootpart=6 bootfstype=fat prefix=/ もしくは /boot/ ---------- => prin scan_dev_for_extlinux scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi => prin boot_extlinux boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf ---------- 改行入れた版 -- scan_dev_for_extlinux if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi -- boot_extlinux sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf ---------- if の条件文 => if test -e mmc 1:6 /extlinux/extlinux.conf; then echo OK; else echo NG; fi OK => if test -e mmc 1:6 /boot/extlinux/extlinux.conf; then echo OK; else echo NG; fi NG ---------- 新出の環境変数 => print scriptaddr scriptaddr=0x00500000 ---------- sysboot のヘルプ => sysboot sysboot - command to get and boot from syslinux files Usage: sysboot [-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename] - load and parse syslinux menu file 'filename' from ext2, fat or any filesystem on 'dev' on 'interface' to address 'addr'
ブートするパーティションに extlinux.conf という名前の設定ファイルがあるかどうかを探し、あれば boot_extlinux スクリプトを呼びます。boot_extlinux は sysboot コマンドを呼びます。
今まで設定してきた環境変数を総動員してあてはめると…、最終的には下記のコマンドが実行されることがわかります。
sysboot mmc 1:6 any 0x00500000 /extlinux/extlinux.conf
もちろん、このコマンドを単独で実行しても起動するはずです。
# cat extlinux/extlinux.conf
label kernel-4.4
kernel /Image
initrd /initrd.img
fdt /dtb
append earlycon=uart8250,mmio32,0xff130000 rw root=LABEL=linux-root rootwait rootfstype=ext4 init=/sbin/init coherent_pool=1M ethaddr=${ethaddr} eth1addr=${eth1addr} serial=${serial#}
言い忘れてました。extlinux.conf はこのような記述です。カーネルイメージ(Image)、initramfs イメージ(initrd.img), デバイスツリーブロブ(*.dtb)のファイル名、カーネルに渡すコマンドラインを指定できます。
GRUB の設定ファイルに似ているけど、もっとシンプルですね。
先日(2018年 7月 17日の日記参照)エアコンを 16℃設定 1時間で浄化運転し、見事に嫌な臭いが消え去りました。しかし最近エアコンが雑巾臭くなってしまいました。
今年の夏はかなりヘビーに使っているとはいえ、浄化した効果が 1か月しか持たないとなると、浄化が必要な頻度はかなり高そうです。
次の休みにでも、また浄化してみるかなあ。電気代がどうこうより、16℃運転の負荷で室外機が壊れそうで、心配ですけどね。
エアコンが臭くなった状態で、設定温度を 26℃に下げるとエアコンの嫌な臭いは一時的に消えます。
しかし 28℃設定に上げると、かなり嫌な臭いがします。27℃設定だと日によって違います。おそらくその日の気温依存だと思われます。
また、我が家のエアコンは、運転停止すると自動的に送風運転が始まります。送風運転はほぼ確実に嫌な臭いがします。
どうもエアコンの熱交換が働いているとき(気温が高いとき、設定温度が低いとき)はあまり臭いがせず、働いていないとき(運転停止後の送風、設定温度が高いとき)はかなり嫌な臭いがするみたいです。
宇宙戦艦物語 RPG というスマホのゲームをやっています。
攻略 Wiki(サイトへのリンク)にダメージ計算式が載っていたので計算してみたのですが、微妙にゲーム中のダメージ値と一致しません。Wiki によると攻撃司令の加算値の計算は、
とあります。その通りに足すと攻撃司令 Lv 9999 ならば、ダメージ補正値が 504900 になるはずです。
しかし適当な武器(702 式発掘超合剣 Lv 1313、攻撃力 1100 + 28885)と、計算で求めたダメージ補正値を足しても、ゲーム側で出てくるダメージと一致しません。計算ではダメージは 534885 になるはずなのに、実際のダメージは 534985 です。100 ほどズレてしまいます。
計算式を色々変えていて Lv が 100 で割り切れるときの加算を変な値にすると、計算結果とゲーム側のダメージが一致することに気づきました。例えば Lv 99 → 100 のとき、加算は +1 ないし +2 が素直ですが、あえて +1 と +2 を両方加算した +3 にします。
変な計算式ですが、あえてこの変な計算式で求めると、攻撃司令 Lv 9999 の場合、ダメージ補正値が 100 増えて 505000 になり、計算結果とゲーム側のダメージとも一致しました。変なの。ゲーム側の計算がバグってるように思えて仕方がない。
この加算値の計算はループでやればすぐできますが、Excel で計算を始めてしまったので、Excel で頑張ってみました。意外と面倒です。やり方はいろいろあると思いますが、私の場合は、
MAX(MIN(H2- 0,100),0)* 1+
MAX(MIN(H2- 99,100),0)* 2+
MAX(MIN(H2- 199,100),0)* 3+
MAX(MIN(H2- 299,100),0)* 4+
...
こんな風に 99行書いて求めました。セルが編集できないくらい重いです。
100で割り切れるところがバグっているのか、別の法則が発動しているのか、正確なところは確かめていないのでわかりません。
きちんと確かめるなら、攻撃司令の Lv を下げていって Lv 9900 を跨げばわかります。幸いにもこのゲームは、敵に防御力の概念が無い(?)ようで、誰に攻撃をぶつけても攻撃力=ダメージとなります。検証は簡単な部類だと思います。私はそこまでやっていませんけども……。
宇宙戦艦物語 RPG はどのように進めていても、いつかは必ず同じ面をグルグル何度も周回するゲームになります。それ自体は構わないのですが、ゲームバランスがマゾすぎます。
一番辛いのは「敵を〇〇体倒せ」系の Lv 上げで、多いステージでも 1 回に 1500 体しか敵が出ないのに、1 つの艦種 Lv カンストに 9999 * 300体(= 300万体)倒さなきゃいけないことです。さらに良くないことに、艦種は 23種類もあります。
私にはこのゲームを極めるのは無理そうです。
以前、高槻市での WAKWAK の遅さに嫌気がさして、DTI に乗り換え(2017年 6月 6日の日記参照)ました。
DTI は時々、名前を逆引きできない IP アドレスを割り当ててくるようです。害はありませんが、WAKWAK のときは無かったことだったので、少し気になって調べてみました。
DTI から割り当てられた IP を whois で調べてみると、AT&T が持っている 144.156.0.0/16 のアドレスでした。なぜかホスト名を逆引きできません。何でしょうね、このアドレス…?
毎回このアドレス帯なのか確かめるため、VDSL 終端装置を再起動したところ、フリービット株式会社が持っている 153.151.x.x というアドレスに変わりました。こちらはホスト名を逆引きできます。
何か事情があって 2種類(もっとあるかもしれないけど)を使い分けているのでしょうか?不思議な動きです。
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2021.
Powered by PHP 5.2.17.
using GD bundled (2.0.34 compatible)(png support.)