Nerves

2020/07/12

Nerves Project の システム部(OS,bootloader?, elixer起動までの構築)

個々のライブラリ群?だけをみていても理解できないっぽい。 Nerves examplesを参照していくとつながるかもしれん。

platform依存部分(Apache License 2.0):

nerves_system_x86_64

  defp deps do
    [
      {:nerves, "~> 1.5.0", runtime: false},
      {:nerves_system_br, "1.9.1", runtime: false},
      {:nerves_toolchain_x86_64_unknown_linux_musl, "1.2.0", runtime: false},
      {:nerves_system_linter, "~> 0.3.0", runtime: false},
      {:ex_doc, "~> 0.18", only: [:dev, :test], runtime: false}
    ]
end

nerves (Apache License 2.0)

nerves

  defp deps do
    [
      {:distillery, "~> 2.1", optional: true, runtime: false},
      {:jason, "~> 1.0", optional: true},
      {:ex_doc, "~> 0.19", only: [:test, :dev], runtime: false},
      {:dialyxir, "~> 1.0.0-rc.3", only: [:test, :dev], runtime: false},
      {:nerves_bootstrap, "~> 1.0", only: [:test, :dev]},
      {:plug, "~> 1.4", only: :test},
      {:plug_cowboy, "~> 1.0", only: :test}
    ]
  end

パーティション

以下がデフォルト. fwup.conf で構成を変えられる模様. SDカードを raw dataアクセスしてしまっているのかな..

FILE: nerves/docs/Advanced Configuration.md

 +----------------------------+
 | MBR                        |
 +----------------------------+
 | Firmware configuration data|
 | (formatted as uboot env)   |
 +----------------------------+
 | p0*: Boot A        (FAT32) |
 | zImage, bootcode.bin,      |
 | config.txt, etc.           |
 +----------------------------+
 | p0*: Boot B        (FAT32) |
 +----------------------------+
 | p1*: Rootfs A   (squashfs) |
 +----------------------------+
 | p1*: Rootfs B   (squashfs) |
 +----------------------------+
 | p2: Application     (EXT4) |
 +----------------------------+

ファイルシステムを触りたければ squashfsを展開/再圧縮してね、ってなってる. br2触らしたくないんだね.

→ "Cunstomizing Systems.md"に br2触る方法があるね..

nerves_bootstrap (Apache License v2)

  defp deps do
    [
      {:ex_doc, "~> 0.19", only: [:dev, :test], runtime: false}
    ]
  end
FILE: nerves_bootstrap/aliases.ex

このあたりで mix targetを追加している様子. "deps.get", "deps.update", "deps.loadpaths", "deps.compile", "run" かな? mixのビルドシステムに対して 追加している感じやろか..

Buildroot(external tree)共通部 (GPLV2)

nerves_system_br

Nerves Systemのビルドに必要な環境を Docker file で提供している。

これを使えばよかったのでは... fwupも NAT超えで使えるはずだしなぁ.

nerves_app

nerves new で雛形を作る

depsに以下が設定されている.. システム起動語に必要なのは nerves_system_* と nerves_runtime, nerves_init_gadget (USB targetとして使う場合)

      {:nerves, "~> 1.5.0", runtime: false},
      {:shoehorn, "~> 0.6"},
      {:ring_logger, "~> 0.6"},
      {:toolshed, "~> 0.2"},

      # Dependencies for all targets except :host
      {:nerves_runtime, "~> 0.6", targets: @all_targets},
      {:nerves_init_gadget, "~> 0.4", targets: @all_targets},

      # Dependencies for specific targets
      {:nerves_system_rpi, "~> 1.8", runtime: false, targets: :rpi},
      {:nerves_system_rpi0, "~> 1.8", runtime: false, targets: :rpi0},
      {:nerves_system_rpi2, "~> 1.8", runtime: false, targets: :rpi2},
      {:nerves_system_rpi3, "~> 1.8", runtime: false, targets: :rpi3},
      {:nerves_system_rpi3a, "~> 1.8", runtime: false, targets: :rpi3a},
      {:nerves_system_rpi4, "~> 1.8", runtime: false, targets: :rpi4},
      {:nerves_system_bbb, "~> 2.3", runtime: false, targets: :bbb},
      {:nerves_system_x86_64, "~> 1.8", runtime: false, targets: :x86_64},

気づき

2020/06/19

学習中に気づいたこととか覚えておいたほうがよさそうなこと

語彙

アリティ arity

関数末尾にある /n のこと. 引数の数.

引数の数が異なる同名の関数が定義できるので、関数への参照?を得るためには arityを指定して唯一性を担保しなくてはいけないようだ.

内包表記 (comprehension)

ローカル変数を定義して、それにマッチするリストを与え、すべての組み合わせに対して 関数を評価した結果のリストが得られる。

for value <- range, cond, do: expression

バイナリを扱う場合の例

iex(1)> pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
iex(2)> for <<r::8, g::8, b::8 <- pixels>>, do: {r, g, b}
[{213, 45, 132}, {64, 76, 32}, {76, 0, 0}, {234, 32, 15}]

ジェネレータ節

cond式

プロトコル

ビヘイビア

ファイル拡張子の識別

拡張子 概要
*.exs scriptから直接実行する(実行時コンパイル?)
*.ex コンパイルしてバイナリを生成する

elixir関連ネタ

2020/06/16(火)Elixirを学ぶ

動機

さる SWEST-21 において、 Nervesハンズオンを体験した。

ここでElixir, earlangについて知るきっかけとなる。組み込み向けのシステムとして使用されており、サーバサイドのNerves Hubから末端のNerves device(raspberry Pi, Beagle Bone)までサポートされていた。

OTA(Over The Air)による自動デプロイがサポートされていたことがとても印象強く、安定した(比較的リアルタイム性を必要としない)システムを構築できそう、という感じを受けました。

なにより開発者の一人である, Justin氏が来日されていたのも大きいですね。

環境を探す

editor

IntelliJやCLionだとプラグインがある.

vim-plugin

語彙

初めて触れたとき、単語の意味がわからなかった。正確性にかけるかもしれないけれど、以下に記録しておく:

概要?
Earlang Erlangは数学者のアグナー・アーランから名前をとって命名された。Ericson社が1998年にOSS化。
OTP Elixirで Earlを使うための結合部分?
Elixir Earlを使っている新たな言語. Rubyの影響を大きく受けている?
mix ビルドシステム?
Hex パッケージ管理システム
asdf Earlang/Elixirをソースビルドする管理システム??(shell script)

公式?

入門記事

Phoenix (WEB framework)

書籍類

プログラミング Elixir(AA)

Nerves: erinit

2020/02/21

erlinit at 2020-02-14

リポジトリ

依存関係

libc

機能

initの置き換えとなる実行ファイル.

nerves_system_br(buildroot)上の busyboxベースで作られる rootfsに対して、 /sbin/initへシンボリックリンクが張られる. コマンドラインオプションでコマンド実行、マウント設定も行うことができる。

設定ファイル

/etc/erlinit.config

nerves_system_brの設定ファイルを参照するとよい。マウントオプションやerlangインタプリタ、サーチパスの設定がある。

引数の格納用に固定長配列(要素数 MAX_ARGC(=32))を使っているようで、ファイル中の設定とコマンドライン引数の総和がこれを超えられない。

FILE: src/options.c
Func: void parse_args(int argc, char *argv[])

ドキュメント(README.md)の以下の見出しにも明文化されている。迷ったらソースを読むと漏れはないだろう...

## Configuration and Command line options

主な流れ

FILE: src/erlinit.c Func: main()

    merge_config(argc, argv, &merged_argc, merged_argv);
    parse_args(merged_argc, merged_argv);

    /*
     * Mount devpts on /dev/pts, procfs on /proc, sysfs on /sys
     */
    setup_pseudo_filesystems();

    // Create symlinks for partitions on the drive containing the
    // root filesystem.
    create_rootdisk_symlinks();

    // Fix the terminal settings so output goes to the right
    // terminal and the CTRL keys work in the shell..
    set_ctty();

    fork_and_wait(&is_intentional_exit, &desired_reboot_cmd);

この中で child processを起こして、zombie processの回収を行う.

    // Set up a controlling terminal for Erlang so that
    // it's possible to get to shell management mode.
    // See http://www.busybox.net/FAQ.html#job_control

erl実行のための loopback i/f設定は netlink socketを触って設定している.. ipコマンドのたぐいではない...

FILE: src/network.c

static void configure_loopback(int ifindex)

という感じなので デフォルトで sshとかなんとかが使える状態ではない. erlinitの設定ファイルで、以下を使えば 任意のデーモンを起こしておくことはできそう. ただしネットワークインタフェースの設定は shoehornとかで行われるのかもしれないから, この時点では 外向けのinterfaceは死んでいると思ったほうがいいだろうな.

--pre-run-exec