目次: ROCK64/ROCKPro64
先日(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種類(もっとあるかもしれないけど)を使い分けているのでしょうか?不思議な動きです。
< | 2018 | > | ||||
<< | < | 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 | - |
合計:
本日: