とりあえず TBD

とりあえず、いきあたりばったり

RTL-SDR 無改造でダイレクトサンプリング

大元の話は reddit.com のこの話

A Very Surprising Discovery (self.RTLSDR)

チューナーに対し3686.6MHzというような周波数を指示すると、ローカル発振が止まって RF側の信号が筒抜けて来てダイレクトサンプリング状態になるということらしい。

この話 E4000 チューナに限った話だと思っていたのだが

R820Tチューナでも無改造でダイレクトサンプリングができるらしい

rtl-sdr and GNU Radio w/Realtek RTL2832U, E4000 and R820Tの "High Frequency (0-30Mhz) Direct Sampling Mod" の"No hardware change, software mod direct sampling" の項に

... (R820T IF frequency, IF filter bandwidths, ?, etc)  ...

とあるのが目に付いた。

2014年 1月に IRCチャンネルにて tejeezという人がチューナーをバイパスするようなレジスタ設定を見つけ出したとか何とか。

直後にあるGitHubリポジトリ(RTL-SDR experimental branch)へのリンクをたどって、変更履歴をみてみると、1/26のコミットで src/tuner_r82xx.cに r82xx_set_nomod(struct r82xx_priv *priv)なる関数が追加されていたりする。

src/librtlsdr.c の rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) の on に 3を渡すと呼ばれるようだ。

rtl_fm コマンドに対しては

-E no-mod
rtl_sdr, rtl_power コマンドに対しては
-D 3
のようにオプション指定してやると、このモードが使われるような修正が入っている(ソース見ただけで未確認)。

とりあえず SDR# から使ってみたい

いつもSDR# から rtl_tcp 越しに使っているのだが、これを試すにはどうしよう? SDR#に手を入れるのはメンドクサすぎるので、rtl_tcp を修正してみよう。この間 APCコンパイルしてみたことだし。

340行目付近に

printf("set direct sampling %d\n", ntohl(cmd.param));
rtlsdr_set_direct_sampling(dev, ntohl(cmd.param));

とダイレクトサンプリングモード設定を呼び出しているところがあるので、"3" に固定してみる

    printf("set direct sampling %d\n",3);
    rtlsdr_set_direct_sampling(dev, 3);

こんな具合。

たしかに HFが受信できる

ラジオNIKKEI(3.925MHz, 6.055MHz)が受信できるのは確認したが、もっと低い方の中波や高い周波数のほうはダメのようだ。

アンテナがどうしようもない状態なので本当にダメなのかはわからない。

rtl_tcp をAPC で動かそうと思ったら Raspbery Piでも動かなくなっていた

APCにインストールした Apricot-R5 は Raspbianとおなじなので、Raspberry Piと同じことをすればよいハズ。

rtl_tcp などのビルド/インストール

rtl-sdr – OsmoSDRSoftware の項にあるので、従えばよい。

ビルドに必要なパッケージのインストールをしておいて

# apt-get install git cmake install autoconf libtool libusb-1.0-0-dev

ソースを持ってくる

# git clone git://git.osmocom.org/rtl-sdr.git

で、ビルドする。

APC/Apricot では autoconf を使うとなぜか libusb の場所などを誤解するようなので cmake を使った。

# cd rtl-sdr/
# mkdir build
# cd build
# cmake ../ -DINSTALL_UDEV_RULES=ON
# make
# make install
# ldconfig

これでよさそう。

でも、ハマッた

rtl_tcpを実行すると

Found 1 device(s):
  0:  Generic RTL2832U OEM
Using device 0: Generic RTL2832U OEM
Kernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.
usb_claim_interface error -6
Failed to open rtlsdr device #0.

とはいたあとに、kernelが Bug! メッセージを出して、以降どうにもならなくなった。

Raspberry Pi の方でも試してみる

Raspberry Piの方ではどうか確認してみたところ、同じメッセージを出して動かない。

ただし kernelの Bugメッセージは出ない。

むむむ。

最近の linux kernel には DVBドライバが入っていて衝突する

ということらしい。

http://www.hamradioscience.com/raspberry-pi-as-remote-server-for-rtl2832u-sdr/のコメントを追っていくと、解決策があった

/etc/modeprobe.d/以下に blacklistを置いて DVBドライバを読まないようにするということだ。

blacklist をつくる

/etc/modprobe.d/rtl-tcp-blacklist.conf に以下のような内容を書いておくことにした。

blacklist dvb_usb_rtl28xxu
blacklist rtl2830
blacklist dvb_usb_v2
blacklist dvb_core

既存のファイルに追加してもよい。

これで reboot してやれば OK。 Pi でも APCでもうまく起動できた。

windows で SDR# を起動、APCでの rtl_tcpに接続して FM放送が受信できることまで確認した。

ただ SDR# からの接続を切ると rtl_tcp が Segmentation Fault を起こして落ちてしまう。 これは rtl_tcp側の問題のようだ。

TUMBLR氏のブログの記事

*Raspberry PiとRTL2832Uドングルを受信サーバとして使うためにrtl_tcpを修正した

に同様の症状を修正したことが書いてあった。この記事の github リンクにあるものは確かに落ちないのだが、1年ほど前のものなので、ドングルの情報が取れなかったり、ゲインが変更できなかったりする。

今のバージョンに修正をあてても症状が変わらない。根が深そうなので後で見ることにしよう。

APC に Apricot-R5 をインストールした

Google group に forumがあった https://groups.google.com/forum/#!forum/apc-pico-itx-boards

というわけで、APC に Apricot-R5 をインストール

USBメモリに書き込んで立ち上げるだけ。

Raspbian のパッケージがそのまま使える。ということで、ネットワークで使う分には Raspberry Piとかわらなくなった。

GRUB2 からZFS rootの FreeBSDの起動を試す

 実は FreeBSD 10.0-RELEASE をインストールしたマシンには、ArchLinuxをインストールした別のHDDが接続してあり、そちらはGRUB2から起動するようにしてあった。

 マシンのBIOSメニューに入ってbootドライブを変更してやることで、FreeBSDLinuxの選択ができる。

 でも、いちいち BIOSに入るのはメンドクサイ!

そこにGRUBがあるじゃないか

 GPTパーティションからの起動なので MBM は使えない。というわけで、GRUBから FreeBSDの起動する設定を模索する。そもそもそのための GRUBだ。しかし、UFSならともかくZFS rootに設定したところからブートできるのか?

幸い、ArchLinuxから入れたので GRUB は最新(だと思う)の GRUB 2.02。ZFSにも対応しているらしい。

Google先生は役に立たない(こともある)

 とりあえず grub zfs freebsdなどでググってみる

 これはFreeBSDportsからGRUBをインストールしてうまくいかなくてパッチを当てている話だ。っと、portsGRUB があったんだ。知らなかった。しかし、今回の目的とは違うようだ。

 これか? ZFS root から起動しているようだ。真似していろいろ試みるが、うまくいかない。2011年の記事だし。  よく読んでみると /boot は UFS に置いているようだ。ダメではないか。今回 /bootはZFS の中にあるのだ。

灯台下暗し。困ったときは源典へ。GNU のドキュメントは info を見る

 GRUB そのものについても検索するも、よくわからない。man grub はありません。GRUB のドキュメントはいったいどこに?

 あぁ、忘れてたよ info だ。 info grub だ。

 info grub → Configuration → Multi-boot manual config とたどると、探していたそのものの例があった。

menuentry "FreeBSD" {
          insmod zfs
          search --set=root --label freepool --hint hd0,msdos7
          kfreebsd /freebsd@/boot/kernel/kernel
          kfreebsd_module_elf /freebsd@/boot/kernel/opensolaris.ko
          kfreebsd_module_elf /freebsd@/boot/kernel/zfs.ko
          kfreebsd_module /freebsd@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
          set kFreeBSD.vfs.root.mountfrom=zfs:freepool/freebsd
          set kFreeBSD.hw.psm.synaptics_support=1
}

insmod zfs の指定とパーティション指定、ルートディレクトリへのpathの指定がキモのようだ。 synapticsは関係ない。

GRUBからZFS中のFreeBSDが起動できた

 さて、どうすればよさそうか考える。

手元のマシンでは

  • プール名 zroot

  • ルートディレクトリ zroot/ROOT/default

  • zfsパーティションはドライブ0 の GPTインデックス3 (hdd0,gpt3)

なので、目の前にあるマシンの状態と先の例を見比べてできたのが以下の設定。

menuentry "FreeBSD load kernel zroot" --class freebsd --class bsd --class os {
        insmod zfs
        search --no-floppy --set=root --label zroot --hint hd0,gpt3
        echo 'Loading FreeBSD kernel in zroot ...'
        kfreebsd /ROOT/default@/boot/kernel/kernel
        kfreebsd_module_elf /ROOT/default@/boot/kernel/opensolaris.ko
        kfreebsd_module_elf /ROOT/default@/boot/kernel/zfs.ko
        kfreebsd_module /ROOT/default@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
        set kFreeBSD.vfs.root.mountfrom=zfs:zroot/ROOT/default
}

grub.cfg は custom.cfg というファイルがあれば、それを読み込むようなので、 こいつを grub.cfg と同じディレクトリの custom.cfg に書いてやった。

成功! 起動した。

 --label zroot する代わりにUUID指定で --fsuuid xxxxxxxx でもよいかもしれない。UUIDを調べるのは ArchLinuxから lsblk -o NAME,UUID /dev/sda でよいかもしれない。うまくいっちゃったので未確認。

 /boot/kernel のところを /boot/kernel.old などとしたものを作っておけば、腐った kernelをインストールして起動しなくなっても、前のカーネルに切り替えられて便利かもしれない。

FreeBSD のローダーメニューは出せないか?

 試してみたらできてしまった。見慣れた BSD のブートメニューが現れた。

kernel を指定する代わりに zfsloaderを指定する。設定は以下の通り。さっきより行数が減った。

menuentry "FreeBSD load zfsloader in zroot" --class freebsd --class bsd --class os {
        insmod zfs
        search --no-floppy --set=root --label zroot --hint hd0,gpt3
        echo 'Loading FreeBSD ZFSloader in zroot...'
        kfreebsd /ROOT/default@/boot/zfsloader
        set kFreeBSD.vfs.root.mountfrom=zfs:zroot/ROOT/default
}

 めでたし。

FreeBSD 10.0-RELEASE の ZFS root へのインストールを試してみた

今時、こんなことは仮想マシンでやればいいのだが、

DVD から 10.0-RELEASE をインストールする

 実マシンでまっさらにできる HDD ができたので、10.0-RELEASE の DVD からのインストールを試してみた。

 ZFS rootへのインストールがインストーラからできるようになったとのことで、せっかくなので ZFS rootにしてみる。

 インストーラが全部やってくれるので、とても楽。何も問題は出なかった。 ZFS のメニューに進むと stripe/mirror/raid選択、HDD選択があったが、 試せる HDD は一台のみなので、冗長化なしの pool になった。

できたパーティションの状態

 150GBしかない HDD だけどこんな感じになった。

 当たり前だけれども GPT になっている。

# gpart show ada0
=>       34  312581741  ada0  GPT  (149G)
         34       1024     1  freebsd-boot  (512K)
       1058    8388608     2  freebsd-swap  (4.0G)
    8389666  304192109     3  freebsd-zfs  (145G)

 各パーティションにはラベルがついていて、それぞれ gptboot0 swap0 zfs0 となっていた。

ZFS プール名は zroot 。

デバイスは ada0 などではなく UUID (gptid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx) で参照される。長くて見難い。

できた ZFS ファイルシステム

 以下のような構成になった。

NAME                 USED  AVAIL  REFER  MOUNTPOINT
zroot               1.63G   141G   144K  none
zroot/ROOT           852M   141G   144K  none
zroot/ROOT/default   852M   141G   852M  /
zroot/tmp            176K   141G   176K  /tmp
zroot/usr            813M   141G   144K  /usr
zroot/usr/home       184K   141G   184K  /usr/home
zroot/usr/ports      813M   141G   813M  /usr/ports
zroot/usr/src        144K   141G   144K  /usr/src
zroot/var           1.25M   141G   616K  /var
zroot/var/crash      148K   141G   148K  /var/crash
zroot/var/log        216K   141G   216K  /var/log
zroot/var/mail       144K   141G   144K  /var/mail
zroot/var/tmp        152K   141G   152K  /var/tmp

zroot/ROOT/default がルートになる。

 結構細かく分けているようだ。ZFS なので構成の変更は後でどうにでもなるだろう。

 src や ports は展開しなかったが filesystem はできている。

プロパティに関してメモ

  • zroot以下 atime=off がデフォルト /var/mail だけは atime=on

  • compression=lz4 になっているもの

        /tmp
        /usr/ports
        /var/crash
        /var/log
        /var/mail
        /var/tmp
  • setuid=off になっているもの
        /tmp
        /var/log
        /var/tmp
  • exec=off になっているもの
        /var/crash
        /var/log

追記

 150GBの古いHDD なので当然 物理セクタサイズは 512byte/sector なのだが、zdb zroot で見てみると ashift が 12 になっていた(つまり 4Kbyte/sectore扱い)。  

ZFS 配下のディレクトリに linprocfs をマウントするには late オプションを使えばいいらしい

自宅サーバ(FreeBSD9.2)では ZFS を使っている。

まだ全部 ZFS にしてしまうには不安があったので、/ や /usrなどは ufs のまま。

linuxエミュレーションを使うのに linux procfs が必要だったので、/etc/fstab に

linproc    /usr/compat/linux/proc    linprocfs    rw         0    0

のように記述していたのだが、boot時このマウントがうまくいかなくて single user mode で対処しないといけない状態になってしまった。

/usr/compat 以下は ZFS 配下にあり、boot時の mount 順がうまくない様子だった。

サーバなのでそれほど reboot する機会はないので /etc/fstab から先の記述をはずしてそのまま放っておいたのだが、 ふと思い立って Google 検索したところ あるブログが引っかかった。うちの状況と同じだ。

というわけで、/etc/fstab の linproc に関する部分に lateオプションを追加、以下のようにした。

linproc    /usr/compat/linux/proc    linprocfs    rw,late    0    0

むむむむ late というオプションには気がつかなかったよ。

FreeBSD-10.0BETA1 が出た

予想どおりアナウンスがあった。

amd64, i386, ia64, powerpc, powerpc64, sparc64についてイメージが出ている模様。

注意が必要なのは、10.0-BETA1 の freebsd-update(8)に問題があるので、アップグレードに freebsd-update(8)を使わないでね ということ。

-ALPHA5 から -BETA1 への変更点

Changes between -ALPHA5 and -BETA1 include:
o Introduce freebsd-version(1), which is intended to be used as an
  auditing tool, to determine the userland patch level when it
  differs from what 'uname -r' reports.
o Improve ZFS lzjb decompress performance.
o Add two new MIPS CPU families - mips24k and mips74k.
o The "jail_<jname>_*" rc.conf(5) variables for per-jail
  configuration are automatically converted to
  /var/run/jail.<jname>.conf before the jail(8) utility is invoked,
  so the new jail.conf(5) syntax is used.
o Remove most of the ATF tools and the _atf user.
o Updates to random(4).  Please note the following:
- In 10.0-BETA1, it is not possible for random(4) to be loaded
  as a kernel module via kldload(8).  If not using GENERIC, and
  the system kernel configuration excludes 'device random',
  please include random(4) in the kernel configuration file.
  The fix for this issue is pending review, and is expected to
  be fixed in 10.0-BETA2.
o Updates to bsdinstall(8).  Please note the following:
- 10.0-BETA1 introduces a number of updates to bsdinstall(8),
  notably the ability to install to a full ZFS filesystem.
  Please keep in mind that this is an experimental feature.
- If using the ZFS installation option in *and* have enabled
  full-disk encryption is enabled, a few entries will need to be
  manually added to loader.conf(5) before the 'bootpool' zpool
  will be available after the system boots.  This manual step
  is expected to be fixed in 10.0-BETA2.

  The entries that need to be added are:

    zpool_cache_load="YES"
    zpool_cache_type="/boot/zfs/zpool.cache"
    zpool_cache_name="/boot/zfs/zpool.cache"

  This can be done at the final menu of bsdinstall(8), when
  prompted to boot into the newly-installed system;
  alternatively, this can be done post-install, in which case,
  the following must be run before appending loader.conf(5):

    # zpool import -f bootpool

テキトーにやくしてみる

  • freebsd-version(1) の追加
  • ZFS lzjb 展開時パフォーマンスの向上
  • MIPS CPUファミリを二つ追加 - mips24k and mips74k
  • jail毎のコンフィグ変数 rc.conf(5)をjail(8)起動前に自動的に /var/run/jail..conf に変換する。なので jail.conf(5)の文法を使うようになった
  • ほとんどの ATF ツールと _atf ユーザの削除
  • random(4) へのアップデート。以下に注意のこと

10.0-BETA1 では random(4)を kldload(8)でカーネルモジュールとしてロードすることができない。カーネルコンフィグファイルに device random'が除かれていたり、GENERIC を使わないなら、random(4)をカーネルコンフィグに追加のこと。この問題は10.0-BETA2では修正される見込み。

  • bsdinstall(8)へのアップデート。以下に注意のこと

** 10.0-BETA1 では bsdinstall(8) に、特に full ZFS filesystem へのインストールができるという、いくつかアップデートが追加された。 これはまだ実験的な機能だということに注意。

** ZFSインストールで 全disk暗号化を有効化する場合、システムブート後 'bootpool' zpool が現れる前に、手動でエントリを loader.conf(5)に追加する必要がある。この手動ステップは 10.0-BETA2 では修正される予定。 追加する必要のあるものとは

    zpool_cache_load="YES"
    zpool_cache_type="/boot/zfs/zpool.cache"
    zpool_cache_name="/boot/zfs/zpool.cache"

これは bsdinstall(8)の最終メニュー、 新しくインストールしたシステムをブートするところで行うことができる。 あるいは、これはインストール後に行うことができる、この場合、 loader.conf(5)への追加の前に、以下を実行しないといけない。

    # zpool import -f bootpool