Linux の SD カードで遊ぶ

今までよく知らないで使ってきたので調べました。まずどうでも良い SD カードを刺して `lsblk -p` でデバイス名を表示します。ここで抜いたり刺したり容量を確認したりして間違えないように注意します。

```shell
$ lsblk -p
NAME                                  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
...
/dev/sdb                                8:32   1   7.4G  0 disk 
```

このドライブは巨大は一つのファイルのような物です。あなたの SD カードなので何でも大胆に書いたり読んだりできます。巨大なので読む時には head で先頭だけ読むようにします。

```shell
$ sudo chmod 666 /dev/sdb
$ echo 'Hello, World!!' > /dev/sdb
$ sudo head -c100 /dev/sdb
Hello, World!!
```

ただ巨大なファイルが一つだけあっても使いにくい。。。そこで何個かのパーティションに分けてみます。

```shell
$ cat <<EOT | sudo sfdisk /dev/sdb
label: gpt
size=1GiB, name="first"
size=1GiB, name="second", type="Microsoft basic data"
size=1GiB, name="third"
EOT
```

と、このようにパーティションの仕様を一行ずつ標準入力に与えます。最低 size だけ指定すれば良いようです。先頭に `label: gpt` と指定すると GPT パーティションになります(後述)。なんとなく二行目だけ `type="Microsoft basic data"` としました。こうすると Mac OS や Windows からも読めるようになります。念の為確認してみましょう。

```shell
$ sudo sfdisk --dump /dev/sdb
label: gpt
label-id: 596DA60C-F243-CF44-B0CF-A3EAD72F20FF
device: /dev/sdb
unit: sectors
first-lba: 2048
last-lba: 15523806
sector-size: 512

/dev/sdb1 : start=        2048, size=     2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=600A5087-2D38-1F4E-8528-8A024C004191, name="first"
/dev/sdb2 : start=     2099200, size=     2097152, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, uuid=E373F144-9723-B74F-AA06-9F8B554743CE, name="second"
/dev/sdb3 : start=     4196352, size=     2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=338F1BE2-8E3C-414B-A578-A9D150057B07, name="third"
```

省略した start (開始位置) や uuid (後述) などが適当に設定されている事が分かります。さて、これでパーティションに色々書き込んでみます。

```shell
$ sudo chmod 666 /dev/sdb*
$ echo 'Good Morning!' > /dev/sdb1
$ echo 'Good Afternoon!' > /dev/sdb2
$ echo 'Good Evening!' > /dev/sdb3
$ sudo head -c100 /dev/sdb1
Good Morning!
$ sudo head -c100 /dev/sdb2
Good Afternoon!
$ sudo head -c100 /dev/sdb3
Good Evening!
```

これだけでは巨大な一つのファイルがまあまあ大きい３つのファイルになっただけで、あまり便利とは言えません。普通にディレクトリやファイル名でファイルを読み書きしたいです。それにはパーティション上にファイルシステムを作ります。

```shell
sudo mkfs.ext4 /dev/sdb1
sudo mkfs.vfat /dev/sdb2
sudo mkfs.minix /dev/sdb3
```

意味もなく色々な種類のファイルシステムを作ってみました。実際にこれを使うには既存のファイルツリーに mount します。VFAT だけ勝手に umask=022 になってしまうので誰でも書き込めるように `-o umask=000` を追加しました(正しい方法調査中)。

```shell
mkdir -p ~/mnt/1
mkdir -p ~/mnt/2
mkdir -p ~/mnt/3

sudo mount /dev/sdb1 ~/mnt/1
sudo mount /dev/sdb2 ~/mnt/2 -o umask=000
sudo mount /dev/sdb3 ~/mnt/3

sudo chmod -R 777 ~/mnt

echo 'Good Morning!' > ~/mnt/1/morning.txt
echo 'Good Afternoon!' > ~/mnt/2/afternoon.txt
echo 'Good Evening!' > ~/mnt/3/evening.txt
```

試しにこの SD Card を Mac に指すと二番目のパーティションだけが見えます。

## その他

* `type="Microsoft basic data"` のような sfdisk の partition type に使える引数を調べるには `sfdisk -T --label=gpt` を実行します。
* ややこしいことに二つの UUID が存在する。どちらも `/dev/なんとか` の代わりに使えるらしい。
    * Partition UUID:
        * sfdisk の uuid パラメータで指定する。パーティションを表す UUID。
        * Partition UUID からデバイス名を得るには `sudo findfs PARTUUID=a3ebab22-e627-47e6-939e-0a8f78b7cb1a` のように指定。
    * Filesystem UUID:
        * mkfs.ext4 などで出来る。ファイルシステムを表す UUID。
        * Filesystem UUID からデバイス名を得るには `sudo findfs UUID=813b5e9f-45f5-41b8-b26b-20e1200025ce` のように指定。

## 参考

* [Ubuntu Manpage: sfdisk - ディスクパーティションテーブルの表示や操作を行う](https://manpages.ubuntu.com/manpages/jammy/ja/man8/sfdisk.8.html)
* [Parted を使ってディスクを初期化する - Qiita](https://qiita.com/propella/items/a085ec43fd59841da9d0)
* [Linux のデバイスファイルに無理やり書き込む - Qiita](https://qiita.com/propella/items/285da1ab65617016c3a1)