Nerves

2020/07/12import

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},

Nerves hacks

2020/07/12Nervesimport

Nerves Project

本家は上記リンクからたどれます

このサイトでは 個人的に調査したり, 動かしてみたりした問いのメモを残していく予定です. ローカルに散らかしておくと見失ってしまうので, マサカリをいただいたりして自分の認識誤りを正してもらえることを期待しています..

発信する分, 何らかのメリット(feedback,寄付)は享受したいものですね!

日本国内リソース

cnnpassのグループがあります. いくつかの Nerves関連サイト, Elixir関連サイトを除いてみると, 参考リンクが出てきます. 複数からリンクしているところが有力 or 根っこだと思うとよいかもですね.

Nerves: erinit

2020/02/21import

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