目次: Linux
OpenSBI + Linuxの環境まで動いたので、次はLinuxのディストリビューションに挑みます。ディストリビューションはDebianにします。以前はUnofficialでしたがDebian 13(Trixie)から正式にRISC-Vをサポートする(riscv64 is now an official architecture - debian-riscv)そうです。良いですね。
DebianのドキュメントにStarFive VisionFive V1用のインストール手順がある(Installing Debian On StarFive VisionFive V1 - Debian Wiki)ので、非常に参考になります。
RISC-Vサポート予定とされているDebian 13(Trixie)は現時点だとTesting版のはずですが、RISC-V向けのパッケージが存在しないものがあって(※)動かなさそうだったので、今回はUnstable版(sid)を使用しています。
今回の実験環境はこんな感じです。
(※)例えばlibcbor0.10はRISC-V版が存在しません。openssh-client -> libfido2-1 -> libcbor0.10の依存を持つ、OpenSSHクライアントがインストールできません。
Debianを動作させるにはDebianのルートファイルシステムが必要です。debootstrapコマンドで作成できて超便利です。
$ apt-get install qemu-user-static binfmt-support debootstrap systemd-container rsync wget $ sudo debootstrap --arch=riscv64 unstable /path/to/riscv-chroot https://deb.debian.org/debian I: Target architecture can be executed I: Retrieving InRelease I: Checking Release signature I: Valid Release signature (key id 4CB50190207B4758A3F73A796ED0E7B82643E131) I: Retrieving Packages I: Validating Packages I: Resolving dependencies of required packages... I: Resolving dependencies of base packages... I: Checking component main on https://deb.debian.org/debian... I: Retrieving adduser 3.137 I: Validating adduser 3.137 I: Retrieving apt 2.9.7 I: Validating apt 2.9.7 ... I: Configuring tasksel-data... I: Configuring libc-bin... I: Configuring ca-certificates... I: Base system installed successfully.
このとき依存パッケージ、特にQEMU(qemu-user-static)をインストールし忘れていると、E: Unable to execute target architectureとメッセージが出て止まります。
作成したDebian rootfsをQEMUからNFSでマウントします。サーバー側の設定例はこんな感じです。insecureを指定しているなど、セキュリティ完全無視の設定なので実験が終わったら設定を消してください。
#### /etc/exports
/path/to/debian_rootfs    *(rw,no_root_squash,no_subtree_check,insecure)
設定を反映するにはexportfsコマンドを使います。何も出力されませんが、エラーがでなければ良いです。
# apt-get install nfs-kernel-server nfs-common # exportfs -a
手動でマウントする場合はこんな感じです。
# sudo mount -t nfs -o nolock 192.168.1.1:/path/to/debian_rootfs rootfs
オプションnolockを付けている理由は、portmapやnfslockのようなデーモンなしでもマウントできるようにするためです。busyboxからマウントするときは便利です。
QEMUの起動引数はたくさんありますがまずはネットワークデバイスの設定をします。netdevでQEMUの外とのネットワーク接続を定義し、deviceでQEMUの中のネットワークデバイスを定義します。カーネル引数はappendに指定します。rootfsをNFSでマウントするためのオプションは、下記の3つです。
NFS v4でも動きそうに思うんですけど、私の環境はなぜかNFS v3じゃないと動作しませんでした。これに気づくまでかなり時間を浪費しました……。
$ qemu-system-riscv64 \ -machine virt \ -bios none \ -nographic \ -chardev stdio,id=con,mux=on \ -serial chardev:con \ -mon chardev=con,mode=readline \ -netdev user,id=netdev0 \ -device virtio-net-device,netdev=netdev0 \ -kernel ../../opensbi/build/platform/generic/firmware/fw_payload.bin \ -append "root=/dev/nfs nfsroot=192.168.1.1:/path/to/debian_rootfs,v3 ip=on nfsrootdebug rw" \ -m 2g \ -smp 4 \ -s \ ... [ 2.312617] ALSA device list: [ 2.313060] No soundcards found. [ 2.534757] VFS: Mounted root (nfs filesystem) readonly on device 0:20. [ 2.541726] devtmpfs: mounted [ 2.708101] Freeing unused kernel image (initmem) memory: 2260K [ 2.710000] Run /sbin/init as init process [ 4.808617] systemd[1]: systemd 256.4-2 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT +LIBARCHIVE) [ 4.811613] systemd[1]: Detected virtualization qemu. [ 4.812465] systemd[1]: Detected architecture riscv64. Welcome to Debian GNU/Linux trixie/sid! [ 4.857724] systemd[1]: Hostname set to <qemu>. ... Debian GNU/Linux trixie/sid qemu ttyS0 qemu login:
うまくいけばログイン画面が拝めるはずです。
ログインユーザーを作成する方法が良くわからなかったため、Debianのrootfsを別のinitramfsからマウントして無理やりuseraddしてユーザーを追加しました。本来どうするものなんでしょうね……?
自分でQEMUをビルドしていると、netdev user,...に対してnetwork backend 'user' is not compiledエラーが出る場合があります。その時はQEMUビルド時のconfigureのログを確認してください。
$ ./qemu-system-riscv64 -netdev user,id=a
qemu-system-riscv64: -netdev user,id=a: network backend 'user' is not compiled into this binary
#### configureのログ(NGパターン)
  Network backends
    AF_XDP support                               : NO
    slirp support                                : NO    ## ★slirpが使えない★
    vde support                                  : NO
    netmap support                               : NO
#### configureのログ(OKパターン)
  Network backends
    AF_XDP support                               : NO
    slirp support                                : YES 4.8.0    ## ★slirpが使える★
    vde support                                  : NO
    netmap support                               : NO
QEMUはnetdev user,...の実装にslirpを使っているようで、slirp supportがNOになっているとnetdev user,...が機能しません。libslirp-devをインストール(apt-get install libslirp-dev)してから、QEMUのconfigureと再ビルドをしてください。
 この記事にコメントする
 この記事にコメントする
目次: Kindle
いつからかわかりませんがAmazonのマイリスト(ほしい物リスト)の挙動が変わっていました。以前は未購入フィルターで絞り込みすればKindleで購入した本は出現しませんでした。
今は仕様が変わったのかバグなのか何だか知りませんが、購入済みの本でもお構いなしに出てきます。例えば上記「未購入」で絞り込みして表示される「宝くじで40億当たった〜 16巻」を見ます。
購入済みです!とデカデカと表示されます。Amazonの「未購入」とは一体どういう意味なんでしょう……??
ちなみにTwitter(現X)でこういうことを呟くとAmazonの公式アカウントがすっ飛んできて「カスタマーサポートに連絡せよ」と言ってきます。
カスタマーサポートは返品対応のような実務は迅速で助かるんですけど、不具合の原因つまり「なぜそうなったのか?」についてはほぼ全く教えてくれません(2021年8月10日の日記参照)から、今回みたいな現象だとあまり当てにならんのではないかと予想してます。一応連絡してみるつもりですけども……。
 この記事にコメントする
 この記事にコメントする
目次: Linux
以前、Debianのrootfsを手軽に作成できるツールdebootstrapを使いました(2024年8月2日の日記参照)が、1つ気になった点があります。アーキテクチャが異なっていても作成可能な(例: x86_64上でRISC-V向けのDebian rootfsを作成できる)点です。
他アーキテクチャ向けバイナリをdebootstrapの内部で実行しているように見えます。qemu-user-staticを使ってエミュレーションするようですが、debootstrapとqemu-user-staticはどうやって連携をとるのでしょう?
まずQEMUの有無、というよりdebootstrapが他アーキテクチャバイナリの実行可否を確認している部分を見ます。コードは/usr/bin/debootstrapと/usr/share/debootstrap/*に分かれて存在しており、qemu-user-staticがインストールされていないときの「Unable to execute target architecture」エラーは下記の部分で出力しています。
# /usr/bin/debootstrap
if [ -x /usr/bin/arch-test ] && am_doing_phase second_stage; then
	if doing_variant fakechroot; then
		ret=0; arch-test "$ARCH" || ret=$?        ★arch-testを使って確認している★
	# Avoid failure with old arch-test package
	elif arch-test --version > /dev/null 2>&1; then
		ret=0; arch-test -c "$TARGET" "$ARCH" || ret=$?
	else
		ret=3
	fi
	case $ret in
	0)      info ARCHEXEC "Target architecture can be executed" ;;
	1)      error 1 ARCHNOTEXEC "Unable to execute target architecture" ;;    ★この行がエラーメッセージ★
	*)      info ARCHEXECUNKNOWN "Can't verify that target arch works" ;;
	esac
fi
判別方法に使うarch-testはシェルスクリプトで、引数にて指定されたアーキテクチャのバイナリが実行できるかどうかを見ています。arch-testが実行するバイナリは/usr/lib/arch-testの下にあり、実行バイナリファイル名はアーキテクチャ名と同じです。
例えばRISC-V 64bit向けを調べるときはarch-test riscv64と実行します。arch-testは/usr/lib/arch-test/riscv64つまりRISC-V 64bitの実行バイナリを実行し、正常に実行できれば成功ステータス、実行できなければ失敗ステータスを返す仕組みです。
シェルから/usr/lib/arch-test/riscv64を直接実行するとokとだけ表示されるはずです。不思議ですよね?なぜx86_64 Linuxマシン上でRISC-V 64bit Linux用のバイナリが実行できるのでしょう?
秘密はLinuxのbinfmt_miscにあります。次回以降はbinfmt_miscを調べます。
 この記事にコメントする
 この記事にコメントする
目次: Linux
RISC-V 64bit用の実行ファイルをx86_64 Linuxマシン上のシェルから直接実行できる不思議な仕組み、Linuxのbinfmt_miscについて調べます。
ざっくりbinfmt_miscを説明するなら、バイナリタイプ(binary type)の先頭部分があるパターンに一致したら、設定で指定したインタープリタを起動してバイナリを渡し実行してもらう仕組みです。スクリプト言語で書かれたプログラムは直接実行できず、インタープリタ経由で実行する仕組みと似ています。今回のように他アーキテクチャのバイナリを実行する(インタープリタ: QEMU)以外に、Javaのアーカイブ*.jarを実行する(インタープリタ: Java仮想マシン)用途にも使えます。
今回はbinfmt_miscそのものの詳細な仕組みは調べず(いずれ調べたいとは思います)、binfmt_miscの設定方法、使い方を紹介します。
Linuxの疑似ファイルシステムの一種としてbinfmt_miscは実装されています。カーネル組み込み、モジュールいずれも可能です。Debian Testingではモジュールとしてビルドされているようです。
#### binfmt_miscがモジュールかつロードされていない場合 # modprobe binfmt_misc #### binfmt_miscがマウントされていない場合 # mount -t binfmt_misc none /proc/sys/fs/binfmt_misc/
バイナリタイプの登録方法はとても簡単で/proc/sys/fs/binfmt_misc/registerに設定をechoやcatで書き込むだけです。正常に登録されるとbinfmt_misc/ディレクトリの下にファイルが増えます。
#### バイナリタイプの確認、登録方法 # ls /proc/sys/fs/binfmt_misc/ register status # cat /usr/lib/binfmt.d/qemu-riscv64.conf > /proc/sys/fs/binfmt_misc/register # ls /proc/sys/fs/binfmt_misc/ qemu-riscv64 register status # cat /proc/sys/fs/binfmt_misc/qemu-riscv64 enabled interpreter /usr/libexec/qemu-binfmt/riscv64-binfmt-P flags: POCF offset 0 magic 7f454c460201010000000000000000000200f300 mask ffffffffffffff00fffffffffffffffffeffffff
試しにRISC-V 64bit用の設定をregisterに書き込むと、qemu-riscv64ファイルが増えました。ディレクトリ内のファイルを読み出すと登録した設定がわかります。statusファイルは読みだすとbinfmt_miscがenableかdisableかがわかります。書き込むと下記の効果を発揮します。
詳細についてはLinuxカーネルのドキュメント(Kernel Support for miscellaneous Binary Formats (binfmt_misc) - The Linux Kernel documentation)を参照ください。
設定はテキスト1行です。例えばRISC-V 64bitバイナリをQEMU上で実行するための設定は下記のとおりです。
# less /usr/lib/binfmt.d/qemu-riscv64.conf :qemu-riscv64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/libexec/qemu-binfmt/riscv64-binfmt-P:OCPF
設定の意味はLinuxカーネルのドキュメント(Kernel Support for miscellaneous Binary Formats (binfmt_misc) - The Linux Kernel documentation)に載っています。
私がハマったポイントは最後にある4つのOCPFフラグ指定の1つ、F(fix binary)フラグです。Fフラグが指定されると、新たにバイナリタイプを登録した後にインタープリターのバイナリを削除したり書き換えても動作が変化しないです。
Fフラグを指定したバイナリタイプに対して、インタープリタープログラムを書き換えて動作の変化を見るときはバイナリタイプを登録し直さなければなりません。systemd-binfmt.serviceを再起動(= バイナリタイプを全て登録し直す)すると一番ラクかと思います。
インタープリタがbinfmt_miscから受け取る引数を見るため、/usr/bin/qemu-riscv64-staticを下記のプログラムで置き換えます。
// a.c
#include <stdio.h>
int main(int argc, char *argv[])
{
	for (int i = 0; i < argc; i++) {
		printf("%d: '%s'\n", i, argv[i]);
	}
	return 0;
}
プログラムを置き換えた後はsystemd-binfmt.serviceの再起動をお忘れなく。
# sysctl restart systemd-binfmt.service $ export PATH=$PATH:/usr/lib/arch-test $ riscv64 a b c #### Pフラグあり $ riscv64 a b c 0: '/usr/libexec/qemu-binfmt/riscv64-binfmt-P' 1: '/usr/lib/arch-test/riscv64' 2: 'riscv64' 3: 'a' 4: 'b' 5: 'c' #### Pフラグなし $ riscv64 a b c 0: '/usr/libexec/qemu-binfmt/riscv64-binfmt-P' 1: '/usr/lib/arch-test/riscv64' 2: 'a' 3: 'b' 4: 'c'
インタープリタープログラムの引数に、実行するバイナリのフルパス+バイナリ実行用の引数が渡されるシンプルな仕組みです。パスが2つ渡されているように見えるのは、P(preserve-argv[0])フラグの影響です。Pフラグを外せばフルパス1つだけになります。詳しい仕様はドキュメントをご覧ください。
話は少し変わりますが、DebianのQEMUパッケージは特殊なパッチがあたっていて、本家QEMUと少し違う動きをします。次回はその辺りを調べます。
 この記事にコメントする
 この記事にコメントする
目次: Linux
前回はbinfmt_miscの使い方や動作を調べました。今回はDebian特有の挙動を見ていきたいと思います。細かいことを言えばQEMUの実装の話でありbinfmt_miscの実装ではありません。しかし二者は密接に関わっているので関連項目として取り上げます。
Debianのbinfmt_miscの設定では、インタープリターに/usr/libexec/qemu-binfmt/以下のファイルを指定します。このディレクトリには独特なファイル名(例: (arch名)-binfmt-P)のシンボリックリンクが置かれています。一例を紹介します。
$ ls -la /usr/libexec/qemu-binfmt/riscv64-binfmt-P lrwxrwxrwx 1 root root 29 May 20 22:14 /usr/libexec/qemu-binfmt/riscv64-binfmt-P -> ../../bin/qemu-riscv64-static
この/usr/libexec/qemu-binfmt/riscv64-binfmt-Pはシンボリックリンクで、実体はQEMU(/usr/bin/qemu-riscv64-static)だと解ると思います。引数を何も指定せずに実行すると普通のQEMUとは異なるメッセージを出力します。
$ /usr/libexec/qemu-binfmt/riscv64-binfmt-P qemu: /usr/libexec/qemu-binfmt/riscv64-binfmt-P has to be run using kernel binfmt-misc subsystem
メッセージを出力しているのは見た通りQEMUです、が、オリジナルのQEMUにこのメッセージを出すコードはありません。
Debianのqemu-user-staticパッケージソースコードを見るとこのエラーメッセージを表示するためのパッチがありました。
// qemu/debian/patches/linux-user-binfmt-P.diff
diff --git a/linux-user/main.c b/linux-user/main.c
index e44bdb17b8..587bd02db2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -562,7 +562,7 @@ static void usage(int exitcode)
     exit(exitcode);
 }
 
-static int parse_args(int argc, char **argv)
+static int parse_args(int argc, char **argv, bool *preserve_argv0)
 {
     const char *r;
     int optind;
@@ -579,6 +579,28 @@ static int parse_args(int argc, char **argv)
         }
     }
 
+    /* HACK alert.
+     * when run as an interpreter using kernel's binfmt-misc mechanism,
+     * we have to know where are we (our own binary), where's the binary being run,
+     * and what it's argv[0] element.
+     * Only with the P interpreter flag kernel passes all 3 elements as first 3 argv[],
+     * but we can't distinguish if we were run with or without this P flag.
+     * So we register a special name with binfmt-misc system, a name which ends up
+     * in "-binfmt-P", and if our argv[0] ends up with that, we assume we were run
+     * from kernel's binfmt with P flag and our first 3 args are from kernel.
+     */
+    if (strlen(argv[0]) > sizeof("binfmt-P") &&
+        strcmp(argv[0] + strlen(argv[0]) - sizeof("binfmt-P"), "-binfmt-P") == 0) {
+        if (argc < 3) {
+            (void) fprintf(stderr, "qemu: %s has to be run using kernel binfmt-misc subsystem\n", argv[0]);    //★★エラーメッセージ★★
+            exit(EXIT_FAILURE);
+        }
+        exec_path = argv[1];
+        handle_arg_argv0(argv[2]);
+        *preserve_argv0 = true;
+        return 2;
+    }
+
     optind = 1;
     for (;;) {
         if (optind >= argc) {
コマンド名の末尾が-binfmt-Pであり、引数が3つより少ない場合にエラーを出す実装です。引数を渡すか、シンボリックリンクをリネームして実行するとエラーメッセージは出現しなくなります。
# ls -la riscv64-binfmt-P_ lrwxrwxrwx 1 root root 29 May 20 22:14 riscv64-binfmt-P_ -> ../../bin/qemu-riscv64-static # ./riscv64-binfmt-P_ qemu: no user program specified # ../../bin/qemu-riscv64-static qemu: no user program specified
QEMUで実行するbinfmt_miscのバイナリタイプ設定はこんな感じで、
# less /usr/lib/binfmt.d/qemu-riscv64.conf :qemu-riscv64:M::\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/libexec/qemu-binfmt/riscv64-binfmt-P:OCPF # ★FlagsはO, C, P, Fの4つ★
実装のコメントを見る限り、下記の条件を満たすことを期待しています。
この条件から外れる場合はエラーにしたいようです。riscv64-binfmt-Pのリンク先の実体はQEMUですが、間違ってQEMUとして起動することを防いでいる……?そこまでする理由があまり思いつかないですけど、昔に何かあったのかな?
 この記事にコメントする
 この記事にコメントする
目次: Linux
今どき(?)のinitrdとカーネル引数の渡し方を知らなかったのでメモしておきます。
昔のARM LinuxですとATAGと呼ばれるブートの情報を並べたリストをメモリ領域に置いてカーネル引数やinitrdを渡して(ATAGの仕様はVincentさんのBooting ARM Linuxが詳しいです)いました。ATAGは今も使えます(Booting ARM Linuxの4a. Setup the kernel tagged list)けど主流はデバイスツリーのはずです。たぶん。ARM Linuxの場合レジスタに指定すべき情報はこんな感じだそうです。
RISC-V Linuxの場合はカーネルのドキュメント(RISC-V Kernel Boot Requirements and Constraints)によれば、RISC-V Linuxの場合レジスタに指定すべき情報はこんな感じだそうです。
ARM Linuxよりさらに減ってhartidとデバイスツリーのアドレスのたった2つです、シンプルですね。
仕様からデバイスツリーを書いても良いですが、目の前のQEMUでDebianが動作している(2024年8月2日の日記参照)のですから実際に動作しているものを調べたほうが早いでしょう。
QEMUが内部で生成しているデバイスツリーのダンプ方法は以前(2024年7月23日の日記参照)紹介した通りです。initrdとappend="root=/dev/nfs"を渡してQEMUを起動し、デバイスツリーをダンプして&dtsに変換します。
$ qemu-system-riscv64 \ -machine virt \ -bios none \ -chardev stdio,id=con,mux=on \ -serial chardev:con \ -smp 4 \ -kernel fw_payload.bin \ -initrd initramfs.cpio \ -append "root=/dev/nfs" (QEMUモニターにて) dumpdtb virt_initrd_cmd.dtb $ dtc -O dts virt_initrd_cmd.dtb > virt_initrd_cmd.dts
/* virt_initrd_cmd.dts */
/dts-v1/;
/ {
...
	chosen {
		bootargs = "root=/dev/nfs";           /* ★appendで渡したカーネル引数★ */
		linux,initrd-end = <0x84227600>;      /* ★initrd終端アドレス★ */
		linux,initrd-start = <0x84000000>;    /* ★initrd先頭アドレス★ */
		stdout-path = "/soc/serial@10000000";
		rng-seed = <0x2a0a5693 0x41742b2a 0x49faf2f1 0xaf1d27cc 0x9c06cb87 0x277e3472 0xfdf688c7 0x5029079c>;
	};
...
ルートノード以下のchosenノードにあるbootargs, linux,initrd-なんとかがappendやinitrdオプションと対応しています。
以上、今どきのLinuxに対してカーネル引数やinitrdを渡す方法がわかりました。Linuxでデバイスツリーに対応したアーキテクチャは多いですから、一度実装しておけば多数のアーキテクチャでカーネルパラメーター指定ができます。便利ですね。
欠点はブートローダーでデバイスツリーのchosenノードを変更する必要がある、すなわちブートローダーにデバイスツリーを加工する処理を実装しなければならない点です。難しくはないでしょうけど、それなりに手間が掛かるでしょう。
ちなみにlinux,initrd-startのようなlinux,で始まるプロパティの仕様はLinuxカーネルのドキュメント(The chosen node - kernel.org)に記載があります。
先程まで見てきたbootargsやinitrd-なんとかが正しく生成できれば、QEMUのappendやinitrdオプション無しでもカーネル引数やinitrdをカーネルに渡すことができるはずです。やってみましょう。
/* virt_mod.dts */
/dts-v1/;
/ {
...
	chosen {
		/* ★この行を追加する★ */
		bootargs = "root=/dev/nfs nfsroot=192.168.1.1:/path/to/debian_rootfs,v3 ip=on nfsrootdebug rw";
...
以前作成したGDBスクリプト(2024年7月29日の日記参照)を使ってカーネルとデバイスツリーをロードします。
# load_dtb_opensbi.gdb restore virt_mod.dtb binary 0x87f00000 thread 1 set $a1=0x87f00000 thread 2 set $a1=0x87f00000 thread 3 set $a1=0x87f00000 thread 4 set $a1=0x87f00000 restore fw_payload.bin binary 0x80000000 thread 1 set $pc=0x80000000 thread 2 set $pc=0x80000000 thread 3 set $pc=0x80000000 thread 4 set $pc=0x80000000
QEMUをkernel, dtb, append引数なし、-Sオプション付き(デバッガーのアタッチ待ち)で起動します。
$ qemu-system-riscv64 \ -machine virt \ -bios none \ -nographic \ -chardev stdio,id=con,mux=on \ -serial chardev:con \ -mon chardev=con,mode=readline \ -netdev user,id=netdev0 \ -device virtio-net-device,netdev=netdev0 \ -m 2g \ -smp 4 \ -s \ -S $ riscv64-unknown-linux-gnu-gdb (gdb) target remote :1234 Remote debugging using :1234 warning: No executable has been specified and target does not support determining executable automatically. Try using the "file" command. 0x0000000000001000 in ?? () (gdb) source load_dtb_opensbi.gdb Restoring binary file virt_mod.dtb into memory (0x87f00000 to 0x87f01cb5) [Switching to thread 1 (Thread 1.1)] #0 0x0000000000001000 in ?? () [Switching to thread 2 (Thread 1.2)] #0 0x0000000000001000 in ?? () [Switching to thread 3 (Thread 1.3)] #0 0x0000000000001000 in ?? () [Switching to thread 4 (Thread 1.4)] #0 0x0000000000001000 in ?? () Restoring binary file fw_payload.bin into memory (0x80000000 to 0x81f51608) [Switching to thread 1 (Thread 1.1)] #0 0x0000000000001000 in ?? () [Switching to thread 2 (Thread 1.2)] #0 0x0000000000001000 in ?? () [Switching to thread 3 (Thread 1.3)] #0 0x0000000000001000 in ?? () [Switching to thread 4 (Thread 1.4)] #0 0x0000000000001000 in ?? () (gdb) continue Continuing.
最後のcontinueを実行するとQEMU側もログが出ます。例えばこんな感じです。
$ qemu-system-riscv64 \
  -machine virt \
  -bios none \
  -nographic \
  -chardev stdio,id=con,mux=on \
  -serial chardev:con \
  -mon chardev=con,mode=readline \
  -netdev user,id=netdev0 \
  -device virtio-net-device,netdev=netdev0 \
  -m 2g \
  -smp 4 \
  -s \
  -S
OpenSBI v1.5
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|
Platform Name             : riscv-virtio,qemo
Platform Features         : medeleg
...
Boot HART MIDELEG         : 0x0000000000001666
Boot HART MEDELEG         : 0x0000000000f0b509
[    0.000000] Linux version 6.9.0 (katsuhiro@blackbird) (riscv64-unknown-linux-gnu-gcc (GCC) 14.1.0, GNU ld (GNU Binutils) 2.42.50.20240622) #9 SMP Thu Aug  1 00:38:49 JST 2024
[    0.000000] random: crng init done
[    0.000000] Machine model: riscv-virtio,qemo
...
[    2.652369] VFS: Mounted root (nfs filesystem) on device 0:20.
[    2.661913] devtmpfs: mounted
[    2.831443] Freeing unused kernel image (initmem) memory: 2260K
[    2.833459] Run /sbin/init as init process
[    4.984017] systemd[1]: systemd 256.4-2 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT +LIBARCHIVE)
[    4.988413] systemd[1]: Detected virtualization qemu.
[    4.989856] systemd[1]: Detected architecture riscv64.
Welcome to Debian GNU/Linux trixie/sid!
[    5.048884] systemd[1]: Hostname set to <qemu>.
...
[  OK  ] Reached target graphical.target - Graphical Interface.
         Starting systemd-update-utmp-runle…- Record Runlevel Change in UTMP...
[  OK  ] Finished systemd-update-utmp-runle…e - Record Runlevel Change in UTMP.
Debian GNU/Linux trixie/sid qemu ttyS0
qemu login: 
Debianのログインプロンプトまで表示されれば成功です。カーネル引数を変えたりinitrdのサイズが変わるたびにdtsを書き換えてdtcでコンパイルする……なんて考えると面倒くさいことこの上ないですが、QEMUや気の利いたブートローダーは自動的にデバイスツリーのchosenノードを加工してくれます。ありがたいですね。
 この記事にコメントする
 この記事にコメントする
目次: Kindle
先日(2024年8月4日の日記参照)Amazonへ問い合わせた、マイリストの変な挙動についてお返事が来ていました。
お客様からお問い合わせいただいた件につきまして、担当部署へ報告させていただき、 問題が確認された場合には適切に対応させていただきます。 大変お手数ですが、所有数を手動で変更し、購入済に移動していただきますようお願いいたします。 なおほしい物リストの商品登録数について、1つのアカウントで管理できるデータ量には制限があります。 各リストには、登録できる最大数は2500点となりますが、サーバーに負荷をかけずに利用いただく理想の 商品数はおよそ100件となります。それを超えると、データ容量超過でスムーズに作動しない場合や、 エラーメッセージが表示される等の問題が生じる場合がございますので、それぞれのリストの登録商品が 100件以内に収まるようリストを分けて作成いただきますようお願いいたします。
不具合かどうかわからないまま終わりましたけど、本当に不具合ならAmazonのエンジニアが直すでしょう。たぶん。あとマイリストの理想の商品数なんて全く関係ない豆知識を授けてくれたのはなぜでしょうね。「お前はリストに登録し過ぎだ、変なエラーが起きても不思議じゃない」と揶揄したかった?のでしょうか。
 この記事にコメントする
 この記事にコメントする
目次: apt
Debianアーカイブのミラーを試してみた(Debianアーカイブミラーの構築 - Debian)のでメモです。
Debianミラーを作成するにはftpsyncスクリプトを使用します。
$ wget https://ftp-master.debian.org/ftpsync.tar.gz
$ tar xf ftpsync.tar.gz
$ ls
distrib
$ tree distrib/
distrib/
|-- README.md
|-- bin
|   |-- ftpsync
|   |-- ftpsync-cron
|   |-- rsync-ssl-tunnel
|   `-- runmirrors
|-- doc
|   |-- ftpsync-cron.1.md
|   |-- ftpsync.1.md
|   |-- ftpsync.conf.5.md
|   |-- rsync-ssl-tunnel.1.md
|   |-- runmirrors.1.md
|   |-- runmirrors.conf.5.md
|   `-- runmirrors.mirror.5.md
`-- etc
    |-- ftpsync.conf.sample
    |-- runmirrors.conf.sample
    `-- runmirrors.mirror.sample
4 directories, 15 files
アーカイブにはdistribディレクトリだけ存在しています。設定する際はdistrib/etcの下にftpsync.confファイルを置きます。distrib/etcディレクトリにあるftpsync.con.sampleが設定ファイルのサンプルです。
# distrib/etc/ftpsync.conf
TO=/path/to/debian
RSYNC_HOST=ftp.jp.debian.org
RSYNC_PATH="debian"
ARCH_INCLUDE="riscv64"
RISC-V用のDebianアーカイブを日本のサーバーからミラーする設定は上記の通りです。実行はdistrib/bin/ftpsyncを実行するだけです。数時間かかりますが、進捗やステータスの類が何も表示されないので不安になります……。
 この記事にコメントする
 この記事にコメントする
目次: 車
ディーラーまで車検の車を取りに行きました。外は非常に暑くて辛いです……。今後、新しく車を買うときは車検が冬になるようにしたいですね。夏の車検はもう嫌だ。
追加の修理費は特にありませんが、タイヤがもうダメそうだったのでFALKEN AZENIS FK520Lに交換しました。FALKENのプレミアムグレードですが、割と安かった気がします。ブリヂストンやヨコハマは結構高くて1.5〜2倍くらいしますね。
今回FALKENのタイヤを調べていて初めて知ったのですが、DUNLOP(アジア地域など)とFALKENはどちらも住友ゴム工業が製造しているんですね。しかもDUNLOPブランドは非常に複雑でグッドイヤー、住友ゴム工業、コンチネンタルなど複数社が地域ごとにDUNLOPブランドを分け合っているようです。何でそんなことに?ややこしいなあ?
前回の車検からの懸念事項だったパワステギアボックスだかのオイル滲みはまだ耐えてくれているようです。駆動系のブーツ類も硬くなっているそうですが、ブーツ類は消耗品だからしかたないですね。半年後の点検まで様子見します。
 この記事にコメントする
 この記事にコメントする
目次: RISC-V
Milk-V Jupiterが届きました。お値段が非常に安かったのもあってM1/K1両方購入しました。注文したのは2か月くらい前で、何も音沙汰がなかったので忘れかけていましたが無事に届いて良かったです。
Jupiterの見た目はPCのMini-ITX規格マザーボードとほぼ一緒です。動かすためにはATX電源が必要なので別途用意してください。SoCはSpacemiT Key Stone M1/K1で、CPUは独自コアのX60を8コア搭載、RVA22のほかRVV 1.0にも対応しています。いいですね〜。
Key Stone M1とKey Stone K1の違いがよくわかりませんが、とりあえずM1はCPU 1.8GHz駆動でK1は CPU 1.6GHz駆動の違いがあるらしいです(Jupiter - Milk-V)。わかりやすい違いは見た目ですね。M1はヒートスプレッダが付いていて銀色のパッケージ、K1は樹脂のみで黒色のパッケージです。
SpacemiTのドキュメントは一応ある(Documentation - SpacemiT)のですが、ダウンロードできない形式になっていて不親切ですね……。イケてない。
起動方法はSDカード、SSD、eMMCと複数ありますが簡単な方法はSDカードからの起動です。Milk-Vの公式サイトにある通りにインストールすれば良いです(Milk-V Jupiter Install OS Image - Milk-V)。OSイメージはUbuntuとFedoraとSpecemiT独自(?)のBianbu OSが用意されていますので、お好みで使うと良いと思います。私は使い慣れているUbuntuにしました。
SDカードに書き込むツールもRaspberry Piのときにお世話になったBalena Etcherを使います。なぜかUbuntuのバージョンは23.10(Mantic Minotaur)です。LTSではないUbuntuはサポート期限が短い(24.04リリースまでの9か月程度)ので、長期間の運用には向いていません。普通の人はしないと思いますけども。
新しいボード購入時の恒例、CoreMarkを実行します。まずはCPUの動作周波数を確認します。
katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq 1800000 katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq 614400 katsuhiro@milkv-jupiter:~$ sudo cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq 1800000
CPUの動作周波数は0.614GHz〜1.8GHzのようですが、curは1.8GHz固定で変動している様子はありません。バグってる?固定?まあいいや、とりあえずこの値を信じましょう。
最初はシンプルにオプションOfastを試します。
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 17322
Total time (secs): 17.322000
Iterations/Sec   : 6350.305969
Iterations       : 110000
Compiler version : GCC13.2.0
Compiler flags   : -Ofast -g
Memory location  : Please put data memory location here
                        (e.g. code in flash, data on heap etc)
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x33ff
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 6350.305969 / GCC13.2.0 -Ofast -g / Heap
6350.305969 / 1800 = 3.52CM/MHzですね、正直言ってあまり速くないです。Cortex-A53より上、Cortex-A55より下といったところです。
RISC-Vは標準的な命令以外にも拡張命令が多数定義されています。なかでもbit manipulation命令はこの手のベンチマークには結構効き目がありますので、有効にして測ってみます。Zbc拡張は有効にしたら逆に遅くなったので外しています。
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 16201
Total time (secs): 16.201000
Iterations/Sec   : 6789.704339
Iterations       : 110000
Compiler version : GCC13.2.0
Compiler flags   : -Ofast -g -march=rv64gc_zicsr_zifencei_zmmul_zba_zbb_zbs
Memory location  : Please put data memory location here
                        (e.g. code in flash, data on heap etc)
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x33ff
Correct operation validated. See README.md for run and reporting rules.
CoreMark 1.0 : 6789.704339 / GCC13.2.0 -Ofast -g -march=rv64gc_zicsr_zifencei_zmmul_zba_zbb_zbs / Heap
6789.704339 / 1800 = 3.77CM/MHzです、だいぶ改善されてCortex-A55と同程度になりました。それでも速いとは言い難いですけど……。X60コア用にコンパイルするときはbit manipulation系の拡張命令は必須ですね。
 この記事にコメントする
 この記事にコメントする
3年前くらいに購入した(2021年3月6日の日記参照)Microsoft Basic Optical Mouseが壊れました。今までのマウスは左ボタンが壊れて勝手にダブルクリック病になっていましたが、今回はセンターホイールが壊れて下に回しているのに上にスクロールされたり、上に回しているのに下にスクロールされたりする症状が出ています。初めて出会う症状ですが、ダブルクリック病と同じくらいイライラします。

Microsoft Basic Optical Mouse分解
3年使ったものなので内部は埃だらけで若干お見苦しいですが、捨てる前に分解して内部の写真を撮りました。ボタンと逆側にあるねじ1本で留まっているだけで、分解はとても簡単です。内部の基板は極めてシンプルです。片面が茶色(レジストなし)、逆側が緑色(レジストあり)のちょっと変わった基板でした。両面レジストが普通だと思っていましたが、コストカットのためですかね?
さて次のマウスは何にしようかな〜と言いたいところですが、実は同じマウスがもう1つあるので引き続き2個目のMicrosoft Basic Optical Mouseを使います。
間違って2個買ったのではなく、あまりに安かったのですぐ壊れるかと思い2個買いました。でも蓋を開けてみれば3年も使えたし杞憂でしたね。1年あたりにすれば300円くらいで驚異のコストパフォーマンス、素晴らしい製品だと思います。Microsoftはこの価格で儲かっているのでしょうか……?
 この記事にコメントする
 この記事にコメントする
 wiki
 wiki Linux JM
 Linux JM Java API
 Java API 2002年
 2002年 2003年
 2003年 2004年
 2004年 2005年
 2005年 2006年
 2006年 2007年
 2007年 2008年
 2008年 2009年
 2009年 2010年
 2010年 2011年
 2011年 2012年
 2012年 2013年
 2013年 2014年
 2014年 2015年
 2015年 2016年
 2016年 2017年
 2017年 2018年
 2018年 2019年
 2019年 2020年
 2020年 2021年
 2021年 2022年
 2022年 2023年
 2023年 2024年
 2024年 2025年
 2025年 過去日記について
 過去日記について アクセス統計
 アクセス統計 サーバ一覧
 サーバ一覧 サイトの情報
 サイトの情報