ev3のOSをコマンドラインから量産する．

LEGO社の開発したev3が古くなってきており，すべて点検することになりました．
車検ならぬ，ロボ検です．

今回はev3のOSはクローンの作成ですが，大容量HDDやSSDがあれば，PCで動かしているLinuxOSのバックアップも取れます．
ただし，今回と同様にコピー対象のOSは起動してないことが前提となります．
そもそも，起動中のファイルをコピーすること自体タブーですが...
大まかな手順は今回記事にする手順と同じだと思いますが，試していないので，
躓いた際は，皆さんで調べて，もしよろしければ教えてください．

#2021/07/15追記
SDカードのパーティションが破壊されている個体が数体発見されました．
まぁ，フォーマットして，パーティション分割して....
って感じですが，一応その方法も記載しておきます．

フォーマットはどの方法でやっても構いません．
私はDebian11上のアプリケーション->アクセサリー->ディスク->ディスクの初期化で行いました．

初期化すると，パーティションが無い状態のSDカードなりUSBなりが表示されると思います．
その状態のSDカードの認識名は<font color="Red"> $ sudo fdisk -l</font> コマンドで探しましょう．

今回は対象のSDカードをsdaとします．
皆さんのPCでは，sdaが本体のHDDかもしれませんので，容易にペーストしないようにお願いします．

USBやSDカード系のパーティションには fdisk コマンドで行うという記事をたくさん見かけましたが，今回はわからないことが多いので， <font color="Red"> $ cfdisk</font> というコマンドを使います．
※cfdiskというのはGUI的にパーティションを作成できる対話型スクリプト？だと思います

ターミナル上で
<font color="Red">$ sudo cfdisk /dev/sda </font>と入力すると，GUIが立ち上がります．

現状，sdaはパーティションが作成されていないので，<font color="DeepSkyBlue"> Free space</font>という表示と空き容量が表示されているはずです．

矢印キーで，画面下部のタブを選択できます．
今回はNewで新たなパーティションを作成します．

画面下部に<font color="DeepSkyBlue"> partition size: 212M</font>というような表示が出てるかと思います．
それを設定したい大きさに設定します．(ex.7GBとか60MBとか)
入力して，[Enter]を押すと，
[primary][extended]というボタン？が出てくるので，大抵の場合は[primary]だと思います．
今回私は[primary]を選択しました．

そうすると，最初のディスク全体の表示に変わります．
そのまま書き込むのではなく，パーティションのタイプを変更しなければいけません．

画面下部のタブに[ Type ]という部分が有ると思います．
矢印キーで[ Type ] タブまで移動します．そこで[Enter]

そうすると，たくさんの表示が出てきます．
そこで希望のファイルタイプを選んでください．

その後は[ Write ]タブで書き込み．
yes or no と入力する部分をyesと入力して，書き込み完了しました．みたいな表示が出たら，完了．
あとは[ Quit ]で抜ければパーティションは作成されています．


##ev3の起動方法
私たちが使用しているev3は，機体側面に挿入したSDカードを読み込んでブートします．
SDカード上にはev3devが書き込まれています．

ev3devは[ev3dev公式ページ](https://www.ev3dev.org/)からダウンロードできます．

OSの焼き方などは省略．

##たくさん量産する理由
そんなん，1台1台セットアップすればええんとちゃう？と思ったそこのあなた．
私も最初はそう思いました．ですがそれでは年が明けてしまいます．

- 設定項目が重い(net-tools,juputer-notebook,etc...)
- 設定台数が8台ほど
- 各ロボット起動時の自動スクリプトなどのコピーがだるい

なによりも，そもそもレゴロボット自体の処理が遅すぎて，フリーズしてるのか処理が続いているのかわからないことが多々あったから．



#ある方法を思いついた

ちゃんと起動している(ネットワークやjupyterなど)OSをコピーすればいいんじゃね？
ddコマンドでいけるっぽいしな．

##じゃあ，ddコマンドでやっていきますよっと．

まず，正常なOSが入ったデータをPCへ移します．
SDカードをカードリーダーやPC本体へ接続したら，fdiskコマンドで認識名を確認します．

```
$ sudo fdisk -l
Disk /dev/nvme0n1: 238.47 GiB, 256060514304 bytes, 500118192 sectors
・
・
・
Device             Start       End   Sectors  Size Type
/dev/nvme0n1p1      2048   1050623   1048576  512M EFI System
/dev/nvme0n1p2   1050624 498116607 497065984  237G Linux filesystem
/dev/nvme0n1p3 498116608 500117503   2000896  977M Linux swap


Disk /dev/sda: 14.84 GiB, 15931539456 bytes, 31116288 sectors
・
・
・
Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1          64    98367    98304   48M  b W95 FAT32
/dev/sda2       98368 15130623 15032256  7.2G 83 Linux

```

上記のような表示が出るかと思います．
私の場合はnvme0n1がPCの内蔵SSDです．sdaxがSDカードの認識&パーティション名です．

まずはPC上に動かします．
ev3_backupというフォルダを作成しておきます．

```
$ mkdir ev3_backup
$ cd ev3_backup
$ sudo dd if=/dev/sda of=/home/username/ev3_backup/ev3_os.img
```

ddコマンド実行中は何も表示されないので，気長に待ちます．
これで，コピーは完了します．

#なぜかファイル容量が大きくなるバグ？
16GBのSDカードに8GB程度の中身が書き込んであったのだが，書き込む前にファイルサイズを確認すると，16GBという表示．
当然書き込み予定のSDカードカードも16GBなので，書き込めるわけもなく...
ddコマンドはイマイチ理解が及んでいないので，追加オプションで改善される可能性もあります．
ddコマンドで実行中に表示が出ないのも怖いので，他のソフトなりツールなりを検索......


# なんかいいの見つけた．
ddrescueというツールが良さそう．

```
$ aptitude search ddrescue
p   ddrescueview    -  GNU ddrescue マップファイルのグラフィカルビューア                                                
i   gddrescue       -  GNU data recovery tool
```

すでにインストールしてしまったので，" i "が付いている方です．

ddrescueを使っていきましょう．

[ddrescueに関する記事](https://www.itmedia.co.jp/enterprise/articles/0811/20/news019.html)

#ddrescueを使ってみる．

ddrescueの基本書式は以下の通り．

コピー元とコピー先はfdiskコマンドで調べておきましょう．

```
$ sudo ddrescue -v /dev/sda1 /dev/sdb1
$ sudo ddrescue -v /dev/sda2 /dev/sdb2
                    コピー元  コピー先
```

- sda1->sdb1
- sda2->sdb2

上記のようにパーティションごとにコピーするのが正しいです．

##実行結果

```
sda1 -> sdb1 へのコピー
$ sudo ddrescue -v /dev/sda1 /dev/sdb1 --force
GNU ddrescue 1.23
About to copy 50331 kBytes from '/dev/sda1' to '/dev/sdb1'
    Starting positions: infile = 0 B,  outfile = 0 B
    Copy block size: 128 sectors       Initial skip size: 128 sectors
Sector size: 512 Bytes

Press Ctrl-C to interrupt
     ipos:   50266 kB, non-trimmed:        0 B,  current rate:  15925 kB/s
     opos:   50266 kB, non-scraped:        0 B,  average rate:  12582 kB/s
non-tried:        0 B,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:   50331 kB,   bad areas:        0,        run time:          3s
pct rescued:  100.00%, read errors:        0,  remaining time:         n/a
                              time since last successful read:         n/a
Finished   
```

なんと3秒で終了．fdiskで確認した容量では4.8MBでしたが，実際に移動したファイルのサイズは5000kB(5MB)？？？
このわずかなズレはなぜ？？？
まぁ，ファイル転送というか読み書きはLinuxの得意分野だけありますね．

次はsda2のコピー結果です．
fdiskの確認では7.2GBですが，実際の移動ファイルサイズは7696MB(7.6GB)？？？
ずれてますね．まぁ，その辺りは謎ということで...

```
sda2 -> sdb2 へのコピー
$ sudo ddrescue -v /dev/sda2 /dev/sdb2 --force
GNU ddrescue 1.23
About to copy 7696 MBytes from '/dev/sda2' to '/dev/sdb2'
    Starting positions: infile = 0 B,  outfile = 0 B
    Copy block size: 128 sectors       Initial skip size: 256 sectors
Sector size: 512 Bytes

Press Ctrl-C to interrupt
     ipos:    7696 MB, non-trimmed:        0 B,  current rate:   4489 kB/s
     opos:    7696 MB, non-scraped:        0 B,  average rate:   7992 kB/s
non-tried:        0 B,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    7696 MB,   bad areas:        0,        run time:     16m  2s
pct rescued:  100.00%, read errors:        0,  remaining time:         n/a
                              time since last successful read:         n/a
Finished
```

以上の手順でコピーは完了です．
おさらいすると．
1. しっかり起動するSDカードを準備
2. ddrescueをインストール
3. SDカードをパーティションごとにコピー
4. 起動することを確認する
5. ※今後のことを考えて，PC上にpart1,part2としてコピー
6. 作成したUSBが起動することを確認する

コピーして作成したSDカードOSはIPアドレスなどコピー元と同一の状態となりますので，同時に起動チェックすると，IPアドレス競合状態となりますので，注意してください．

#おまけ
毎回SDカード挿入してコピーするのは効率が悪すぎます．
なので，OSバックアップを兼ねて，ローカルPCに保存しておきます．
最初はディレクトリにぶちこめばいいかと思ってましたが，そうではなさそう．

```
$ cd
$ cd ev3_backup
$ touch part1 #パーティション1のためのファイル
$ touch part2 #パーティション2のためのファイル
$ sudo ddrescue -v /dev/sda1 part1 --force
$ sudo ddrescue -v /dev/sda2 part2 --force
```