—-追記—–
全然更新できてないのですが、ひとまずEMMCから起動とかもできるようになりました。友人がQua Stationで運用しているブログがこちら→https://blog.u-haru.com/
ご覧の通り、なかなかのパフォーマンスです。ついでにChinachu(録画サーバ)も動いており、普通に使える子になってます。
———–
最近USBメモリをくれた友人のせいでQua Stationがアツいのですが、やっぱりAndroidの上でchrootしてお茶を濁したところでサーバーにはなり得んのです。systemctl使いてぇ
で、ネイティブに動かすノウハウがある程度溜まったので公開します。
正直俺はマイサーバーがあるのであったところでなのですが、うまく動くようならこれ2台体制ぐらいに移行してもいいかなとか思ってます。
まあ殆どはライバル心というか起動しないからには起動させたい的な心で動いてるわけですが…
※この記事に書いてあることは半分ぐらい友人の成果物です
あとArchLinuxをインストールとか書いてますがどっちかというとデバイスについて成分が多めです。
1,ブートローダー
で、まずブートローダーを探っていきます。
どうも第一ローダーでオプションをセットしたあとDTB、ramdisk、カーネル、ファームウェアを読み込んで第二ローダーへ移行するようです。
bootrというコマンドでいろいろ読み込んで第二ローダーに行きます。
b2ndbcというコマンドで何もせずに第二ローダーに行きます。
第一ローダーで使えるコマンド一覧は
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 32 33 34 35 36 37 38 39 |
Realtek> help b2ndbc - load 2nd stage bootcode bdinfo - print Board Info structure bootm - boot application image from memory bootr - boot realtek platform dcache - enable or disable data cache env - environment handling commands factory - FACTORY sub system fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fdt - flattened device tree utility commands gettime - get timer val elapsed go - start application at address 'addr' or start running fw goru - start rescue linux from usb help - print command description/usage icache - enable or disable instruction cache keyset - keyset - write keyset file into factory area led - led - [0|all] [on|off|toggle] loady - load binary file over serial line (ymodem mode) md - memory display mmc - MMC sub system (patch for rtd299x) mtest - simple RAM read/write test mtest2 - simple RAM read/write test mw - memory write (fill) ping - send ICMP ECHO_REQUEST to network host reset - Perform RESET of the CPU rtkemmc - RTK EMMC functions rtkgpio - rtk gpio access saveenv - save environment variables to persistent storage source - run script from memory tftp - download image from TFTP server tftpput - TFTP put command, for uploading files to a server uart_write- for uart mp tool burn mac and sn key unzip - unzip a memory region usb - USB sub-system version - print monitor, compiler and linker version |
こんなかんじでした。USB(XHCIに対応してます!)やmmc等のコマンドが充実しています。
デフォの環境変数はこんな感じです。第二ローダーへ移行していく過程が見て取れます。
パスワードやSSIDが普通に書いてありますが使う気はないので問題ありません(←??)
そして第二ローダーはこんな感じです
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 32 33 34 35 36 37 38 39 40 41 42 |
Realtek> help ? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure booti - boot arm64 Linux Image image from memory bootm - boot application image from memory bootr - boot realtek platform cachetest- Stress cache operation cmp - memory compare cp - memory copy dcache - enable or disable data cache editenv - edit environment variable env - environment handling commands erase - erase FLASH memory exit - exit script false - do nothing, unsuccessfully fdt - flattened device tree utility commands flinfo - print FLASH memory information gettime - get timer val elapsed gictest - Turn on GIC and send SGI to CPU go - start application at address 'addr' help - print command description/usage icache - enable or disable instruction cache loadb - load binary file over serial line (kermit mode) loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing address) mw - memory write (fill) nm - memory modify (constant address) printenv- print environment variables protect - enable or disable FLASH write protection reset - Perform RESET of the CPU saveenv - save environment variables to persistent storage setenv - set environment variables setexpr - set environment variable as the result of eval expression showvar - print local hushshell variables source - run script from memory test - minimal test like /bin/sh true - do nothing, successfully version - print monitor, compiler and linker version |
起動系やメモリ操作系が充実してますね。
なんの意味があるのかは正直わからないのですが、こんな感じに2つu-bootを使い分けているようです。
また、通常起動時に
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Start Boot Setup ... ---------------LOAD NORMAL FW TABLE --------------- [INFO] fw desc table base: 0x00620000, count: 11 Normal boot fw follow... Kernel: FW Image to 0x03000000, size=0x00fe6600 (0x03fe6600) FW Image fr 0x02a25400 DT: FW Image to 0x01f00000, size=0x0000f7b4 (0x01f0f7b4) FW Image fr 0x026b0200 ROOTFS: FW Image to 0x02200000, size=0x00400000 (0x02600000) FW Image fr 0x0460ba00 Audio FW: FW Image to 0x01b00000, size=0x00335160 (0x01e35160) FW Image fr 0x026f0200 |
こういう表示が出てきますが、実はどれか1つでもチェックサムが合わないとそこで中断し、LOAD GOLD FW TABLEという表示を出しながらバックアップ用のシステムが起動してきます。
(写真from友人)
ここで起動するGOLD FWは後述するzidooのrescueとそっくりです。もしかしたら同じなのかもしれません。
あとローダーに入りにくいので5秒待つようにしときましょう。
1 2 3 4 5 6 7 8 |
Realtek> env set bootdelay 5 Realtek> env save Saving Environment to FACTORY... [ENV] Writing to Factory... [FAC] factory_save: MMC [FAC] Save to eMMC (blk#:0x1100, buf:0x07000000, len:0x21e00) [FAC] Save to eMMC (seq#:0xaa, pp:0) done |
ブートローダはこんなもんかな、次~
2,カーネル
とりあえずこいつではLinux 4.1.17のAndroidが動いています。
別のシステム動かねえかな~と、構成が比較的似ていてSoCが同じなZidoo X9Sのリカバリを動かしてみることにしました。
第一ブートローダーのgoruというコマンドが気になったからです。
https://www.zidoo.tv/Support/downloadList/target/rRwtRFydZ4xKKmVViAFMcQ%3D%3D.html
スクショがめんどいので載せませんが結果Zidooのリカバリ入USBメモリからOpenWRTというホスト名でレスキュー用のLinuxが起動しました。
またこれも4.1.17でした。RTD1295がサポートされた4.1.17がRealtekとかから入手できるんじゃないかなぁと思います。
一応他のカーネルが動くなら自分でビルドしたのも動くのかなっていうことで5.0.9で試してみました。
ちょっと前にRTD1295サポートが入っており、Zidoo X9sのデバイスツリーもあります。
適当にRTD1295サポートを入れてビルドしたものをZidooのレスキューUSBメモリに入れ、第一ローダーで
1 2 3 4 5 6 7 |
usb start fatload usb 0 0x01f00000 /rescue.emmc.dtb fatload usb 0 0x03000000 /Image.gz fatload usb 0 0x02200000 /initramfs-linux.pad.img b2ndbc setenv bootargs "earlycon=uart8250,mmio32,0x98007800 console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=PARTUUID="19ca1100-01" rw rootwait rootfstype=ext4 init=/sbin/init devtmpfs.mount=1 debug" booti 0x03000000 - 0x01f00000 |
こうすることでとりあえず起動します。(※ramdiskやArchについては後述)
あとrescue.emmc.dtbだとメモリが500MB弱しか認識されません。android.emmc.dtbだと1.6GBになります。
systemdも動いていい感じ~と思いきや、USBドライバやSATAドライバが入っていないためルートデバイスをみつけることができませんでした。
3,Archをインストール
(上の続き)ならZidooカーネルならどうやと試したところ…
動きました!
debugつけてるのでコンソールが忙しいですが、とりあえずsystemdが1で起動しているのでsystemctlとかも使い放題です。
ZidooカーネルはSATAをサポートしているのでHDDをルートデバイスにできます。ほぼパソコンです。
というわけで、Archのインストール方法なのですが、ほぼ
https://archlinuxarm.org/platforms/armv8/generic
のままやるだけです。というかルートデバイスについてはこのままやってOKです。
問題はramdisk。
普通にarchlinuxarmのbootの中にあるinitramfs-linux.imgを読み込んだだけだと
Initramfs unpacking failed: junk in compressed archive
と言われて展開に失敗します。
どうも0x1000バイトずつ読んでいるようで、その間は終端文字の後であってもゴミは許されないようです。
適当にddで後方を埋めときましょう。
initrd=0x02200000,0x7F0000と指定したなら終端から8Mのところまで埋めとくと確実でよいです。
1 2 3 4 5 6 7 |
dd if=initramfs-linux.img of=initramfs-linux.pad.tmp 14262+1 records in 14262+1 records out 7302635 bytes (7.3 MB, 7.0 MiB) copied, 0.155887 s, 46.8 MB/s //上の7302635をseekに dd if=/dev/zero of=initramfs-linux.pad.tmp bs=1 count=10485760 seek=7302635 dd if=initramfs-linux.pad.tmp of=initramfs-linux.pad.img bs=512 count=16384 //8Mジャスト切り出し |
スマートとは言い難いやり方ですがこれしか思いつきませんでした…
→すいません、rootでHDDを指定してinit=/sbin/initにすれば普通に動きました…
early-hook等を使用しない場合はramdiskにこだわらなくてもいいと思います。
あとはZidooのカーネルを使って起動すれば動いてくれます
1 2 3 4 5 6 7 |
usb start fatload usb 0 0x01f00000 /rescue.emmc.dtb fatload usb 0 0x03000000 /emmc.uImage fatload usb 0 0x02200000 /initramfs-linux.pad.img b2ndbc setenv bootargs "console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=PARTUUID="00065d92-01" rw rootwait rootfstype=ext4 init=/sbin/init selinux=0 nmi_watchdog=0 devtmpfs.mount=1" booti 0x03000000 - 0x01f00000 |
が!!
最初に書いたとおりネットワークがまともに動いてくれません。
具体的に言えばdhcpcdでアドレスを取得しようにも192.168.255.20/24のアドレスを取得してしまい(どの携帯のUSBテザリングでもこうなります。)
手動で設定してもパケットが通りません。またネットワークを使おうとするたびSELinuxの警告が出てきます。多分Enconfigになってるんじゃないかな…
→違いました。Qua Station内蔵LTEモデムがusb0として認識されてたみたいです。なので携帯のテザリングが認識されていなかったようです
ドライバをビルドできる環境がほしいです。
しかし、zidooの/system/vendor/modulesを見ていたところ、RTL8192EEとRTL8812AEのドライバを発見しました。
1 2 3 |
lspci 0000:00:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8192EE PCIe Wireless Network Adapter 0001:01:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8812AE 802.11ac PCIe Wireless Network Adapter (rev 01) |
適当にコピーしてinsmodしてみると…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000 link/ether 08:6a:0a:b8:31:10 brd ff:ff:ff:ff:ff:ff 3: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 link/ether 42:d4:62:a4:c1:3b brd ff:ff:ff:ff:ff:ff 4: wlp0s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 link/ether 00:e0:4c:87:00:00 brd ff:ff:ff:ff:ff:ff 5: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000 link/ether 02:e0:4c:87:00:00 brd ff:ff:ff:ff:ff:ff 6: wlP1p1s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 link/ether 42:6a:f4:be:09:93 brd ff:ff:ff:ff:ff:ff 7: wlan2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 link/ether 76:aa:ff:b0:2f:6f brd ff:ff:ff:ff:ff:ff |
無事Wi-Fiが認識されました
rtk-btusb.koをinsmodすればBluetoothも使えるんじゃないですかね、試してないのでわかりませんが
そして、今の僕の環境、実はArchLinuxARM-aarch64-latest.tar.gzではなくpacstrapで作ったものなのでNetworkManagerもついでに入ってます。
なのでsystemctlでNetworkManagerを立ち上げたあとnmcliで設定すると…
https://qiita.com/youyo_/items/376503446135c0dd3da7
無事にネットに繋がりました!
しかしAndroidのCONFIG_ANDROID_PARANOID_NETWORK
のせいでグループに所属していないとソケット通信とかができません
https://stackoverflow.com/questions/36451444/what-can-cause-a-socket-permission-denied-error
こんなんで屈する訳にはいかないのでauにOSS開示のメールを送ってみました。
とりあえず宿題でもやりながら待ちたいと思います。宿題多すぎてキレそう(どうでもいい)
EMMCを使った自動起動はauからカーネルソースをもらってからやろうと思いますが、USBメモリを使った自動起動だとbootcmdをちょっといじるだけでできてお手軽です。
1 2 |
env set bootcmd "usb start;fatload usb 0 0x01f00000 /android.emmc.dtb;fatload usb 0 0x03000000 /emmc.uImage;fatload usb 0 0x02200000 /initramfs-linux.pad.img;env set bootargs console=ttyS0,115200n8 initrd=0x02200000,0x7F0000 root=PARTUUID=00065d92-01 rw rootwait rootfstype=ext4 init=/sbin/init selinux=0 audit=0 nmi_watchdog=0 devtmpfs.mount=1;env set bootcmd 'booti 0x03000000 - 0x01f00000';b2ndbc" env save |
ここまでくれば(ひと手間かかりますが)ほぼサーバーですね!
Androidの上にchrootで寄生していたときより圧倒的に使いやすいです。
(いつもの)
ちなみに電源管理も一応出来てるみたいで再起動もちゃんとできます。ただ電源を切ると一回プラグを抜くまで動きません…(仕様..?)
4,最後に
えーというわけで未完成です。auからの返事を待ちたいと思います。
#2019/5/31追記
書き忘れてましたが、auからカーネルソースを送ってもらえました。
https://github.com/Haruroid/linux-kernel-kts31
僕は今テスト期間なので何もできませんが終わったらなんかやろうと思ってます。5.1に移植とか…
にしてもカスタマイズされたカーネルっていうのはどれも面倒くさいですね…
SC-03Eのときもそうでしたが特定のオプションをオンにしないとビルドできないとか余裕であります…
https://drive.google.com/file/d/1U_OucdZhlmwdZV7v_Yzlm_NUTqGU_a7L/view
もらったDVDの生ISOはこちらです。Android側のものがいろいろ入ってます。
#追記終わり
でもなんでzidooもカーネルを開示してないんですかね、Realtekてそういう契約するところだっけ、よく知らないのでわかりません
ちなみにおまけとして書いとくと、
Normal boot fw follow…
Kernel:
FW Image to 0x03000000, size=0x00fe6600 (0x03fe6600)
FW Image fr 0x02a25400
DT:
FW Image to 0x01f00000, size=0x0000f7b4 (0x01f0f7b4)
FW Image fr 0x026b0200
ROOTFS:
FW Image to 0x02200000, size=0x00400000 (0x02600000)
FW Image fr 0x0460ba00
Audio FW:
FW Image to 0x01b00000, size=0x00335160 (0x01e35160)
FW Image fr 0x026f0200
のとおりmmcblk0から
dd if=/dev/mmcblk0 of=./some.img bs=1 skip=(FW Image fr:のアドレスを10進にしたもの) count=(size=を10進にしたもの)
で各イメージを吸い出せます。
最初これのカーネルとdtbで試してたのですが、ウォッチドッグがどうしても止まらず、30秒付近で強制再起動されてました。
Android側に習って(Androidの)/initをwatchdogdとして起動したりしてみたのですがだめでした
ではでは~
コメント失礼いたしました。
こちらの文章を拝見いたしました、とてもいい文章です。
自分もArchLinuxをQua Stationにインストールしたいですが、
ブートローダーに入れませんでした、
いつも
‘root@kylin32:/ #’
環境に入れて、
‘Realtek>’はできませんでした、こちらは起動する時に何のキー押せばよいでしょうか(今まではEnter使って入れませんでした)。
後、インストールの順番ですが、文章に従って、
1. Bootloaderに入って。
2. Zidoo X9sのfirmwareをインストールして。
3. Arch Linuxをインストールする。
こんな感じですよね。
どうぞよろしくお願い致します。
バラバラに書いたせいで自分でも見にくい文章ですいません…
僕は確かEscを連打で入れたと思います。起動時に出てた気がしますがアップデートで消えたんでしょうかね…
またインストールという程のことはしておらず、ファームウェアという概念も存在しません。
ようはzidooのカーネルを使ってArchLinuxARMを起動しているだけです。
ついでに、今からZidooカーネルを使うのはおすすめしません。
https://github.com/BPI-SINOVOIP/BPI-W2-bsp/tree/master/linux-rtk
が新しくてよいです。
また友人がやっていた実験のメモも貼っておきます。
https://gist.github.com/ugaharu/cb1acdb9d683a3a9fb16c6c44b683eb1
EMMCからの起動等も書かれているので一見の価値ありです
返信ありがとうございます!
bootloaderはEscで入れました!
そうなんだ、新しいカーネルでインストールしてみます!
できたら、まだ報告します!
メモありがとうございます、大変助かります!
ARM系は初心者ので、ご丁寧にありがとうございました。
色んな試しましたが、上手くARCH LINUXを起動できませんでした。
文章通りのコマンドもメモの中のコマンドも全部試しましたが、色んなエラーが出きって、多分Bootargsのパラメータが違うと思いますので、色んな調べましたが、root=PARTUUID=”00065d92-01″のPARTUUIDはどうやって分かれるでしょうか、教えていただけますでしょうか。
ZidooのDTBとImage
bootargsのrootwaitを削除して起動すると end Kernel panic – not syncing: VFS: Unable to mount root fs on unknown-block(0,0)このようなエラーが表示される。
rootwaitがある場合、cfg80211: Exceeded CRDA call max attempts. Not calling CRDA このエラーが表示されるとカーネルがフリーズしました。
DTBに関して、どんなDTB使えばよいでしょうか、BANANA PIをコンパイルしたのDTBを使てなんがKill initKill initのエラーが表示されるので、AUのソースでコンパイルしようと思って、AUのソースのDTBはコンパイル失敗しました。もしよければDTBをいただいてもよろしいでしょうか。
どうぞよろしくお願い致します。
UUIDはblkidコマンドで見れるはずです。これは僕のHDDの値なので動かなくて当然ですね…
initがキルされるのはrootfsのマウントに失敗しているからだと思うのでUUID合わせたらちゃんと動くと思いますよ
rootwaitをつけるとフリーズするというのは永遠にrootデバイスを待ち続けているのでフリーズしたように見える状態です。
dtは基本的にはカーネルについてたやつを使うといいです。BPIのやつは忘れてしまいましたがzidooのやつでもちゃんと動いたと思います。
ありがとうございます!
一応Zidooのやつはできます、ArchのImageはできませんでした。
無事に入りましたが、EMMCに移す時自分がばかすぎでUBootを削除しちゃった、
今Ubootを入れるように戦いてます。