Raspberry PiにAlpine Linux入れてデスクトップ環境を構築した…い (3)

まさかの前回の続きです。続くとは思わなかった…。  

nitteru.hatenablog.com

色々と試行錯誤を重ねていたら、前回できなかった自動ログインができるようになりました。どうも設定が不足していたようで、lxdmのタイムアウトの設定を追加することで無事に自動ログインできるようになりました。タイムアウトは5秒以上が推奨されていたので下限値の5を設定しました。xfce4のせいかと思って一時OpenBoxを入れてみたんですが結果同じで、lxdmの設定で触れそうな所を、と探していた結果たどり着いた次第です。

timeout=5

/etc/lxdm/lxdm.conf

これでキオスク的な使い方もできそうですね。Raspberry Piの場合、GUIが不要な用途が多そうなのでGUI版の他にCUI版もSDカードの中身をまるごとバックアップして後々の環境構築が簡単になるようにしました。展開してコピーするだけは楽でいいですね。

ここでついでの確認事項としてRaspberry PiのGPIOやSPI、UARTの動作を確認してみました。確認には以前別のディストリ上で動かしていた自作のpythonスクリプトを動かしています。使用したライブラリはRPi.GPIOやpySerial、py-spidevなどです。これらモジュールのpipでのインストール時にいくつか開発環境が必要になります。メモが少しあやふやですが、確か下記3点ぐらいだったと思います。またarmv7版では問題なかったものの、aarch64版ではライブラリがうまく動きませんでした。むりに64bit OSでなくても大きく問題はないと思いますが、これからに期待ですかね。

# apk addlinux-headers alpine-sdk python3-dev

ここまできたら最後に残っているのが永続ストレージ (persistent storage)の扱い。

lbuはデフォルトで/etc直下の管理をしているらしいです(/homeも?)。ではなぜ/etcのみで永続化ができるかというと、詳しい仕様はぱっと見つけられませんでした。公式ドキュメントやソースコードを追ったりはまだできていませんが。とりあえず今できる範囲で調べてみた結果がこちら。

  • インストールしたパッケージは/dev/mmcblk0p1/cacheに保管されている(デフォルト設定時)
  • /etc/apk/worldにインストールしたパッケージ名が記録されている
  • /usrを永続化した後にapk add (パッケージ名)してlbu ci -dする前にリブートすると/usrには残っているが、/etc下の設定は無くなっている
    • /etc/apk/worldにも記録されていない
  • /usr下にインストールされたファイルを消してパッケージ名を/etc/apk/worldに追記し再起動するとインストールされている(キャッシュが残っている場合)

ということで、想像したブートプロセスのイメージがこんな感じ。順番の前後はかなりありそうですが。

  1. ブートローダカーネルの起動
  2. rootfsをtmpfs上に展開
  3. 基本のパッケージをインストール
  4. tar.gzにまとめてあったlbu (/etc)の変更分をオーバーレイで反映 (tmpfs)
  5. /etc/apk/worldにリスト化されているパッケージをインストール

下記サイトでもあるように、この辺りの動作はログに残っているそうです。というか確認を忘れました。後日覗いてい見ます。

unix.stackexchange.com

ここいらの想像が正しいとして、今までの設定だと/usrと/etc以外は永続化されないので例えば/var下にデータを保存するようなソフトは別途lbuの管理下に置く必要がありそうです。もしくは別にUSBメモリなどストレージをマウントしてそちらに逃がす手もありそうですね。

永続ストレージを作ったあとにlbu ci -dを実行しないように、というのも/etc/apk/worldに記録されてしまうとRAM上に展開されるからと考えられます。いや、そう書いてはあるんですが。逆に反映しないと/etc下のファイルがごっそり消えてしまう。lbuの管理対象設定いかんではその他のディレクトリに保存されているデータも永続化されないということで、パッケージのインストールには思ったより工夫が必要そうな感じです。

ある意味当たり前ですが、/etc/apk/worldにインストールされているという記録が残っている場合はapk delで永続ストレージにインストールしたパッケージも消すことができます。逆にlbu ci -dせずに/usrにだけ残っている場合は消すことができません(同パッケージを再度インストールし、すぐにアンインストールで消すことはできました)。

最後に気になるRAMの使用状況。freeコマンドで表示される-/+ buffers/cacheのFreeはCUI版で890MB、GUI版で730MBほどでした。他の情報はメモを消してしまったので機会があればまた今度。とりあえず思ったより使える印象です。

ここにきてようやく、Alpine Linuxの動きがなんとなく見えてきました。シャットダウン処理無しに電源を切られても壊れにくいという利点を生かして、diskless化していない環境で動かしていたものを移行してみたいと思います。

Raspberry PiにAlpine Linux入れてデスクトップ環境を構築した…い (2)

前回のつづきです。

前回はCUIでログインできるところまでできたので、この上にWindow環境を構築してみます。今回の参考文献はこちら。

wiki.alpinelinux.org

wiki.alpinelinux.org

とりあえず公式の手順に則り、まずはxorg用のパッケージをインストールし、その後必要なパッケージをインストールしていきます。dbus自動起動するように設定した後、xfce4をインストールしました。

# setup-xorg-base 
# ​apk add xf86-video-fbdev xf86-video-vesa xf86-input-mouse xf86-input-keyboard dbus ​set​xkbmap kbd  
# rc-update ​​add dbus
# apk add xfce4

ここでstartxを叩いてもいいらしいのですが、今回使用しているのがRaspberry Pi3のためOpenGL関係もインストールします。ビデオメモリの割当容量が設定できるので今回は32Mを割り振りました。

(/media/mmcblk0p1/config.txtに下記を追加)
dtoverlay=vc4-kms-v3d
gpu_mem=32

/media/mmcblk0p1/config.txt

該当ファイルがあるパーティションは永続ストレージを作る際に書き込みできるよう再マウントされているものとします。

# apk add mesa-dri-vc4

これで準備完了、としたいところですがこの手順ではウィンドウマネージャ (xfce4)はインストールされますがディスプレイマネージャ (今回はlxdm)がインストールされておらずデスクトップ環境には足りません。足りないものを追加でインストールしました。

# apk add lxdm faenza-icon-theme mesa-egl xf86-input-evdev libinput
# rc-update add lxdm

上記の例ではlxdm以外もインストールしています。アイコンパックはいいとして、mesa-egl以下3つはデスクトップ環境を立ち上げた際にXorg.0.logやlxdm.logに読み込みエラーとして記録されていたものです。

最後にもう2点、必要な設定を行います。この設定のまま再起動するとウィンドウマネージャが立ち上がった時点からXorg.0.logに下記メッセージが大量に出力されます。これを抑制するためにPageFlipモードをいうものを無効化する必要があるようです。このための設定が1点目です。

(EE) modeset(0): Failed to get GBM bo for flip to new front.
(EE) modeset(0): present flip failed

無効化の方法は下記設定内容を記述したファイルを作成します。

Section "Device"
  Identifier "DisplayLink"
  Driver "modesetting"
  Option "PageFlip" "false"
EndSection

/usr/share/X11/xorg.conf.d/20-displaylink.conf

2点目は、デフォルトセッションをxfce4に変更します。

(下記設定を追記)
session=/usr/bin/startxfce4

/usr/lxdm/lxdm.conf

ここでlbu ci -dで変更を反映し、再起動します。するとGUIのログイン画面が表示される、はず。動作はやはりというかもっさりな感じがしますし、メモリ使用量も500~600MB近くまで上がりました。

記事タイトルがデスクトップ環境を構築し「たい」にも関わらず、うまく構築できています。今回引っかかたのは実はここから。キオスク端末のごとく自動ログインさせたいという要件が残っていました。自動ログインの設定自体は簡単です。デフォルトセッションを設定したファイルに下記内容を追記して再起動するだけです(設定反映を忘れずに)。

(下記を追記)
autologin=root

/usr/lxdm/lxdm.conf

この設定を有効化したまま再起動すると…ログイン画面が表示されません。lxdm.logやXorg.0.logにもそれらしきエラー(EE)の記述もなし。不思議なことにCUIでログインしてstartxfce4もしくはrcコマンドを実行すると何事もなかったかのようにログインが完了した状態で起動します。大きく違うのはデスクトップ環境起動時にすでにユーザー(ここではroot)でログインしていたか否か、だと思います。となると認証関係でしょうか…。この一点のために行き詰まってしまいました。

このままこの問題を追うか、arch Linuxなど別の軽量Linuxに乗り換えるか。どうしたものかなぁと言うことでこれまでの作業内容をブログに残しました。

Raspberry PiにAlpine Linux入れてデスクトップ環境を構築した…い (1)

ちょっとした実験や軽いものの実行環境としてRaspberry PiにRaspbianを入れて使っています。しかしLite版でも最初から色々入っていて軽量、という所では今ひとつな感じです。そこでDockerでもお馴染み、Alpine Linuxを使ってみようと試行錯誤してみました。まだ目的を完遂できていないので理解できたかもしれないメモとして残します。正直わからない部分のほうが多いので、理解次第修正ということで。

alpinelinux.org

Alpine LinuxRaspberry Pi用にファイルシステムが公開されています。簡単なインストール手順としては公式の手順を参考にします。  

wiki.alpinelinux.org  

まず手頃なSDカードを用意し、FAT形式でフォーマットします。ブートフラグが立っていることが必要です。このSDカードにイメージを配置します。後ほど確保する永続化領域(Persistent storage)もFAT領域内で問題ないようですが、パーティションを分け、ext4で別途フォーマットする方法でも行けるようです。今回は簡単のため前者を採用しました。  

ダウンロードしたtar.gzを展開し、できたファイルをSDカードに書き込みます。armhf版はRaspberry Pi Zeroや1。armv7版はRaspberry Pi 2、3、3+。aarch64はRaspberry Pi 3用…という理解です。アーキテクチャの分類はたまにゴッチャになります…。

イメージを書き込んだSDカードをRaspberry Piに挿し込み電源を入れブートします。最初のセットアップではモニタとキーボードが必要です。ログインプロンプトが表示されたらユーザー名はroot、パスワードは無しでログインできます。

ログインしたらログインメッセージにあるようにalpine-setupコマンドを実行してセットアップを進めます。今回デフォルト以外で設定したのは下記のとおりです。

  • キーボードと言語はjp指定
  • ネットワークは有線(eth0)のみでdhcpを使用
  • wlanはdoneを指定し設定なし
  • apkリポジトリは速いところをfで測定
  • rootのパスワードは適宜

セットアップが一通り終わったら、apkリポジトリの編集を行います。今回はopenJDK8を使用したいのでmainの他にcommunityも有効化します。apk updateも忘れずに。

/etc/apk/repositories

http://nl.alpinelinux.org/alpine/v3.9/main
http://nl.alpinelinux.org/alpine/v3.9/community
#http://nl.alpinelinux.org/alpine/edge/main
#http://nl.alpinelinux.org/alpine/edge/community

 

次に作業を楽にするために外部からsshで入れるように設定します。rootでsshログインするのであくまで一時的なものとお考えください。設定を書き換えたらrc-service sshd restartで再起動します。

/etc/ssh/sshd_config (一部抜粋)

PermitRootLogin yes

次にRaspberry PiのSPIとI2Cを有効化し、UARTもTinyUARTではない方を有効化します。UARTの切り替えはBluetoothと排他のはずですのでご注意ください。この設定のために起動時に読み込まれる設定ファイルを修正します。修正のために一部マウントの再設定が必要です。

/media/mmcblk0p1/config.txt または /media/mmcblk0p1/usercfg.txt (新規作成)

# mount -o rw,remount /media/mmcblk0p1
# vi /media/mmcblk0p1/user.txt
(下記4行を追記)
dtparam=spi=on
dtparam=i2c_arm=on
enable_uart=1
dtoverlay=pi3-miniuart-bt
(上書き保存後)
# rc-update add hwdrivers

次にI2CとSPI用のモジュールを読み込むための設定を行います。

/etc/modules

(下記2行を追記)
i2c-dev
spi-bcm2835

ここまでの作業の締めにPersistent Storage (永続ストレージ)を設定します。Alpine Linuxは通常の手順でインストールするとOSをRAMディスク上に展開して実行するDisk lessモードになります。電源を切ると変更分が失われますが、SDカードへの書き込みが基本的に無いためにSDカードが長持ちします。ただしRaspberry PiのRAM(ここでは50%の512MB?)を使用するため容量的には言うほど大きくありません。そこで永続ストレージを使用するようです。永続ストレージの大きさは必要に応じて指定します。

# mount /media/mmcblk0p1 -o rw,remount
# vi /etc/fstab
(/media/mmcblk01pのマウント設定行でroをrwに変更する)
- /dev/mmcblk0p1 /media/mmcblk0p1 vfat ro,relatime,fmask=0022,dmask=0022,errors=remount-ro 0 0
+ /dev/mmcblk0p1 /media/mmcblk0p1 vfat rw,relatime,fmask=0022,dmask=0022,errors=remount-ro 0 0

# dd if=/dev/zero of=/media/mmcblk0p1/persist.img bs=1024 count=0 seek=1048576
# apk add e2fsprogs
# mkfs.ext4 /media/mmcblk0p1/persist.img
# echo "/media/mmcblk0p1/persist.img /media/persist ext4 rw,relatime,errors=remount-ro 0 0" >> /etc/fstab
# mkdir /media/persist 
# mount -a
# mkdir /media/persist/usr 
# mkdir /media/persist/.work 
# echo "overlay /usr overlay lowerdir=/usr,upperdir=/media/persist/usr,workdir=/media/persist/.work 0 0" >> /etc/fstab 
# mount -a

最後に今までの変更分を反映させ再起動します。

# lbu ci -d
# reboot

ここまでで最低限CUIの設定ができている、はずです。永続ストレージを作ったおかげで完全なDisk lessとはなっていない部分もあると思います。公式では永続ストレージを作った場合はlbu ci -dを実行しないよう書いてあります。英語苦手なのでよくわかりませんが、せっかく永続ストレージにインストールしてもlbu commitでRAM側に展開されてしまい意味がないって事でしょうか。となると、apk addで追加した場合はlbu commitせずに再起動したほうがいいのではないかと思います。でもこの設定では/usrがoverlayFSによってマージされますが、例えば/etcにある設定ファイルの扱いなどが気になります。この辺りはもっと理解を深めないといけません。

この時点で再起動した直後のメモリ使用量は100MBほどでした。これはこれで使い勝手がいいので、一度SDカードの中身をごっそりPCに保管します。これでバックアップはオッケーという手軽さ。次はlxdmとxfce4を使ってデスクトップ環境を構築してみたいと思います。

我が家にVPNを張ってみた

お勉強がてらネットワーク環境で遊んでみたくて色々やっております。今回はVPNを張ってみました。

 

まず前提として、インターネットサービスプロバイダにIIJmio (FiberAccess/NF)を利用しています。IPv6はIPoE、IPv4IPv4 over IPv6を行うDS-Liteを使用しています。が、DS-Liteはグローバル側からプライベート側への接続ができません。

 

www.mfeed.ad.jp

 

ですがこのためのIIJmioIIJmioではIPoEと同時にPPPoEで接続することができます。こちらは普通のPPPoEなので外側からのアクセスも可能。普段使うPCやタブレットはIPoE + DS-Liteで速度重視。VPN接続用はIPoE + PPPoE接続とわけることで解決できます。

 

help.iijmio.jp

 

今回このネットワーク設定を行うルーターYAMAHA製RTX1200。中古品が大量に流れている時期があり、そのときにボチりました。ルーターで行うのは概ね下記の感じ。基本的なフィルタはすでにやってあるものとします。

  1. IPoE (LAN2)の設定
  2. DS-Lite (TUNNEL1)の設定
  3. PPPoE (PP1)の設定
  4. VPN用端末のIP振り出しを固定
  5. 4で指定したIPのゲートウェイにPP1を設定
  6. VPNで使用するポートの静的IPマスカレードを設定
  7. 6で指定したポートを通過させるフィルタを設定
  8. DDNSにnetvolanteを使用 (SoftEtherDDNSサービスもあります)

ちなみにRTX1200自体にもVPNサーバー機能がありますが古いルーターなので速度が物足りないこと、クライアントとの相性があるらしいこと(特にWindows?)から別にVPNサーバーを用意しました。OpenVPNやら色々あるなかで採用したのはSoftEther。理由としては未踏ソフトウェア創造事業に採用された頃から気になってた、の一点。OpenVPNも後々触りたいのですがこちらは後回し。

 

SoftEther自体のインストールは、Linux用パッケージをダウンロードして展開。展開先のディレクトリでインストール用シェルを実行。パーミッション諸々を設定してサービスとして登録、などなど。ソースコードからのビルドになるので事前に開発環境を入れておく必要はあります。

 

qiita.com

 

インストール後に、仮想ハブを作成したりユーザーを作成したりとサーバー側の設定があります。vpncmdを使いCUIで設定するもよし、他のWindows端末からGUIツールを使うもよし。今回はL2TP/IPsecも有効にしました。既存のLANにアクセスするためにローカルブリッジも設定します。

ここでまだ理解が追いついていないのが仮想ブリッジ。VPNサーバー自体にVPN経由で接続できないという制限があり、これを回避するために仮想ブリッジというものを設定する必要があるらしいです。とりあえず今回はLAN内のNASにアクセスできればいいので仮想ブリッジの設定は保留。

 

khws4v1.myhome.cx

qiita.com

 

そんなこんなで、iPhoneAndroidからはL2TP/IPsec。PCからはSoftEtherクライアントから接続できることが確認できました。

VSCodeでC言語のフォーマットが効かない問題【解決済】

久方ぶりの記事が簡単。

 

マイコンファームウェアを実装する時、だいたいC言語な訳です。今回はPICを使おうとしておりまして純正のMPLAB Xを…と言いたいところですが、MPLABはビルド作業だけに集中させてコード編集はVSCodeで行っています。

MPLAB XはNetBeansがベースになったお陰もあり、Ver8系に比べてかなり最近のIDEという感じがしますが見た目とか軽さ、ドキュメントフォーマットやgit対応とか含めて最近はVSCode推しです。

 

余談はここまでにして、具体的にソースコードを編集しようとしていたらドキュメントフォーマットが効かない事に気が付きました。拡張機能のメッセージを見てね!とVSCodeから言われたのですが、まずそのメッセージは何処ぞ?と探す作業から。いろいろ探した結果、出力を表示させ、右上のドロップダウンリストから「C/C++」を選べばいいみたいです。

 

f:id:nitteru:20190122161021p:plain

C/C++拡張のメッセージ

この時点ではErrorレベルのメッセージしか出ませんので、設定の検索欄で「debug」と入力して「C/C++」を選んでからLogging LevelをDebugに変更しました。これで細かい情報が流れてくるようになりました。

 

この状態でソースコードを開き、ドキュメントのフォーマットを行うと「Failed to spawn process. Error: 267」やら「Unable to start child process !」と言ったエラーが散見されます。前者のエラー番号はGoogle先生にお伺いを立てたところ、どうもディレクトリ関係のエラーだそうです。

エラーメッセージの他の部分も眺めていると、対象となるソースコードのパスに日本語が含まれていてエンコードされておりました。エンコードされた部分が悪いのか、パスが長くなりすぎたのか不明ですが、日本語を含まないパスに変更して、再度フォーマットをかけると…成功!

あとはLogging Levelをもとに戻して無事に作業に戻ることができました。

 

今頃になって日本語にやられるとは思いませんでしたし、真の原因は不明ですがとりあえず動き出したので良しとします。昔とは根本的な原因は違うと思いますが、今頃日本語に悩まされるとは。

 

いずれまたやらかしそうなので、メモとして残します。

はじめての でんけんさんしゅ

もうそろそろ受けてみようか、と思いつつ数年経ってしまいましたが今年ようやく受験まで至りました。

 

とは言うものの、受験を決意したのが申し込み期限ギリギリ。それから今日まで個人的なことで忙しく、ほぼ準備期間が取れない状況でした。

 

そして結果は惨敗。短い準備期間でやったところすら怪しい体たらく。

 

早くも来年に向けて勉強は継続します。今までは沢山の問題が載っている参考書を使っていましたが、もう少し教科書的な物の方が基本を抑えられるので良さそうです。特に理論。ちょうど大学時代の教科書も残ってますし。

 

法規、機械は一部理論と繋がってる様子なので合わせて挑む感じでしょうか。法規は電工二種の教材も役に立ちそうです。

 

自分の分野が弱電なので、強電の範囲になる電力は知識も少なく苦手な傾向にありました。ここはちょっと課題かもしれません。

 

思えばあと5年早く挑んでおけばよかったという後悔もありますが、仕方がないので次までの一年、頑張りたいと思います。

スマートコンセントのPSE対応

スマートコンセントの様な遠隔操作でのON/OFFってPSE的にどうだったかなと思ったら、条件付きで大丈夫って事になってました…。情報の更新が遅れてますね。

IoT界隈でもスマートホームの自作やハックが流行っていますし、古いネタもありますが更新ついでに知っていることと併せて整理してみたいと思います。

 

 今回見て気になったのはTP-Linkの製品「HS105」です。これまでもこの手の製品は販売されていましたが、スマートスピーカーが出始めてから加速した感があります。

 

www.tp-link.com

 

元々遠隔操作で電気製品の電源入り切りができるのは色々条件があって、屋内使用、使用できる通信方法や負荷の上限、認められた器具であることなどが規定されています。基本は人が動作状況を確認できることが前提で制限がかかっています。事故った時に止められる、これが大事。

 

遠隔操作で話題になったのはパナソニックのエアコンでしたね。当初、PSEが時代遅れだとか経済産業省の腰が重いなど色々ありましたが、わりとその通りだと思います。ですが、PSEも最低限の品質を担保と言う、それなりの根拠というか意義はあると考えています。ここで言う品質とは、感電・火災など事故を起こさないということです(もちろん他の機器に妨害を加えないとか物理的な強度などその他諸々ありますが)。

 

それが担保できないなんてあり得ないだろと思いますが、実際に規格を満足せず開発中の試作品で火を吹く事もありますし、市場で事故を起こしたり経済産業省の試買テストで引っかかり晒され行政処分があったりします。管轄の経済産業局からの立入検査(抜き打ち)なんてものもあります。電気製品の事故も怖いし、経済産業省も怖い。

 

試買テスト・流通後規制 - 電気用品安全法(METI/経済産業省)

 

もちろんPSEを守れば安泰と言う訳ではなく、ISOやUL、JISなどの国際(国内)規格、業界規格、社内独自規格などたくさんの規格が存在します。規格の目的はそれぞれ違ったりしますが…。

 

話が逸れましたが、エアコンや国外情勢の件もあり業界から要望を受け、適用できる器具の範囲や遠隔操作の方法なども徐々に拡大されてきました。負荷が想定できない物については使う側でリスクを考えろ、ともありますが、これによりスマートコンセントが世に出回る事ができるようになったようです。

 

トピックス - 電気用品安全法(METI/経済産業省) 

電気用品調査委員会|活動成果 (該当PDF)

 

なぜ遠隔操作が制限されていたか。制限がどう緩和されたのかの詳細はJETの資料がわかりやすいかもしれません。

  

ちなみに。PSEは色々と穴みたいな物がありまして、遠隔操作機能は製品の一部だとアウトですが別製品であればセーフ、みたいな事がありました。この隙を使って間に挟む赤外線を送受信する機器も流行りました。またACアダプタで動くものはACアダプタがPSE該当で本体は非該当だったりします。PSEを取りにくい場合ACアダプタ駆動にする、なんて事もあるようです。

 

 

冒頭にも書きましたが、マイコンモジュールなどを使って商用電源に繋ぐものを作ったり電化製品をハックしたりするのに凄く敷居が下がっています。PSEがあるように商用電源での事故は本当に洒落になりません。

 

ブレーカーがあるから大丈夫だろとも思いがちですが、物によっては定格電流の500~600%が流れても遮断までに1秒かかるなんてのも普通にあります。これは電線を加熱して被覆を発火させるのに充分です。完全に短絡してブレーカーが落ちればまだいいのですが、半端な短絡でスパークしている状態だと中々遮断されません。燃えている火に油を注いでいるようなものです。慌てて消化しようとして触ってしまい感電もありえます。

 

コンセントのパーツを買ってきて配電する場合も知識、技能不足で事故る可能性が高いです。そもそも資格無しでは工事できない場合もありますし、最近ではコンセントを修理した記事が悪い意味で話題になったりしました。

 

togetter.com

 

商用電源を利用するプロダクトを作る場合、PSE周辺の情報を集めたり電工二種の資格を取ることで安全を確保しやすくなると思います。作れる物も広がるかもしれません。第一、事故ったら元も子もありませんからね。