tetsu31415.log

androidなどのことを書き綴っていこうと思います。

ELECOMのNASにArch Linuxをインストールした

ELECOMのNAS(NSB-3NR2T1MLV)にArch Linuxをインストールしてみました.

製品版に組み込まれているLinuxカーネルでは,Arch Linuxが起動しないので, ELECOMの公式サイトからソースコードをダウンロードしてコンフィグをいじってカーネルビルドしました.

手順

  1. Linuxカーネルのビルド
  2. HDDにArch Linuxをインストール
  3. Linuxカーネル書き込み
  4. Arch Linuxの設定

準備するもの

  • NSB-3NRVシリーズのNAS (Ver1.08にアップデートしたもの)
  • OSインストール用HDD(付属のHDDを使わない場合)
  • シリアルコンソールケーブル
  • TFTPサーバ
  • Linuxマシン(カーネルビルドとOSインストール用)

Linuxカーネルビルド

ロスコンパイル環境構築

カーネルビルドにはArch Linuxのマシン(x86_64)を使用しました. NASアーキテクチャはarmv7lなのでクロスコンパイル環境を整えます.

まずcrosstool-ng(AUR)をインストール後,適当なディレクトリでビルドします. デフォルトではうまく行かなかったのでmenuconfigで下記を変更しました.

  • GCCのバージョンを4.9.4に変更 (C compiler ---> gcc version --> 4.9.4)
  • GDBをオフ (Debug facilities --> gdb)
$ ct-ng arm-unknown-linux-gnueabi
$ ct-ng menuconfig
$ ct-ng build

ロスコンパイル

uImageを生成するために必要なuboot-toolsをインストールします.

$ sudo pacman -S uboot-tools

エレコムのサイト https://www.elecom.co.jp/support/download/storage/hd/nas/linux-nas/nsb-3nr_3ms/ からソースコードをダウンロードします.

ダウンロードしたファイルを展開してsrc_20180125/linux-3.4に移動します. 一時的にクロスコンパイラのPATHを通して,カーネルコンフィグの設定をします. 下記の3つの項目を変更しました.

  • CONFIG_ARM_THUMBをyにする (System Type --> Support Thumb user binaries)
  • CONFIG_CGROUPSをyにする (General setup --> Control Group support)
  • CONFIG_FHANDLEをyにする (General setup --> open by fhandle syscalls)

カーネルコンフィグを編集したら,カーネルビルドします.

$ export PATH=$PATH:/home/username/x-tools/arm-unknown-linux-gnueabi/
$ export PATH=$PATH:/home/username/x-tools/arm-unknown-linux-gnueabi/bin

$ make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- menuconfig 

$ make -j8  ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- uImage

ビルドが終わると,arch/arm/boot/uImageにカーネルイメージが生成されます.

$ file arch/arm/boot/uImage 
arch/arm/boot/uImage: u-boot legacy uImage, Linux-3.4.86, Linux/ARM, OS Kernel Image (Not compressed), 4418736 bytes, Mon Dec 17 21:09:09 2018, Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x457ED5B5, Data CRC: 0x349B35A2

あとでNASからカーネルイメージを読み込むので,TFTPサーバにuImageをアップロードしておきます.

Arch Linuxインストール

LinuxマシンにHDDを接続して適当にパーティションを切ってext4でフォーマットします. 下記は/dev/sdbにパーティションを1つ作った例です

# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.33).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): o
Created a new DOS disklabel with disk identifier 0x5ad8791d.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (1-4, default 1): 
First sector (2048-156301487, default 2048): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-156301487, default 156301487): 

Created a new partition 1 of type 'Linux' and of size 74.5 GiB.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

ext4にフォーマットする際,mke2fsのバージョンの問題でオプション無しでフォーマットするとうまく起動できないので, 下記のオプションでフォーマットします.

# mkfs.ext4 /dev/sdb1 -O ^metadata_csum

https://archlinuxarm.org/about/downloads から ArchLinuxARM-armv7-latest.tar.gz をダウンロードします. フォーマットしたパーティションをマウントしてbsdtarで展開します.

# mkdir /mnt/arch
# mount /dev/sdb1 /mnt/arch
# bsdtar -xpf ArchLinuxARM-armv7-latest.tar.gz -C /mnt/arch
# sync
# umount /mnt/arch

Linuxカーネル書き込み

起動テスト

Arch LinuxをインストールしたHDDをNASに接続します. tftpサーバにカーネルビルドで生成されたuImageを置きます.

LANケーブルをNASのLAN1からLAN3のいずれかに接続します. シリアルコンソールケーブルをNASのCONSOLE端子に接続します.

baudrateを115200にしてシリアル通信を行います.

電源ボタンを押すと,起動音がなったあと

Hit any key to stop autoboot : 5

とカウントダウンが始まるので適当なキーを押してU-BOOTに入ります.

TFTPサーバに接続するためにNASIPアドレス(ipaddr)とTFTPサーバのIPアドレス(serverip)を設定します. ※ setenvコマンドで設定した変数は,saveenvコマンドを実行するとNANDフラッシュメモリに保存されます.

U-BOOT # setenv ipaddr 192.168.1.101
U-BOOT # setenv serverip 192.168.1.100
U-BOOT # saveenv

uImageをTFTPサーバからメモリにロードします

U-BOOT # tftpboot 0x2100000 uImage
Using Goldengate device
TFTP from server 192.168.1.100; our IP address is 192.168.1.101
Filename 'uImage'.
Load address: 0x2100000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########################################
done
Bytes transferred = 4418800 (436cf0 hex)

bootargsを下記のように変更します.MACアドレスはXXで伏せてあります. デフォルトのbootargsの先頭にroot=/dev/sda1 init=/sbin/init を追加したものです.

U-BOOT # setenv bootargs root=/dev/sda1 init=/sbin/init console=ttyS0,115200 SB_PHY=PPSS ni_napi_budget=16 qm_acp_enable=0 ni_rx_noncache=0 qm_int_buff=0 ethaddr0=XX:XX:XX:XX:XX:XX ethaddr1=XX:XX:XX:XX:XX:XX ethaddr2=XX:XX:XX:XX:XX:XX wifiaddr0=XX:XX:XX:XX:XX:XX wifiaddr1=XX:XX:XX:XX:XX:XX mtdparts=cs752x_nand_flash:1024K@0x00100000(uboot-env0),1024K@0x00300000(uboot-env1),1024K@0x00400000(sb0),1024K@0x00500000(sb1),153600K@0x15200000(rootfs),174080K@0x0A800000(rootfs_data),6144K@0x00600000(kernel1),153600K@0x01200000(rootfs1)

起動してみます.

U-BOOT # bootm 0x2100000

下記のようなログイン画面が出ると成功です. ユーザ名とパスワードともにrootで入れます.

Arch Linux 3.4.86 (ttyS0)

alarm login: 

NANDフラッシュ書き込み

このままでは,毎回TFTPサーバからカーネルをダウンロードしないとArch Linuxが起動できません. そこで,NANDフラッシュメモリにカスタムカーネルを書き込みます.

NANDフラッシュメモリの書き込みに失敗すると最悪起動しなくなる可能性ががあります.自己責任でお願いします

デフォルトのbootargsのパラメータを見るとNANDフラッシュメモリの構造は下記のようになっていることがわかります.

0x00100000 - 0x00200000  uboot-env0
0x00300000 - 0x00400000  uboot-env1
0x00400000 - 0x00500000  sb0
0x00500000 - 0x00600000  sb1
0x00600000 - 0x01200000  kernel1
0x01200000 - 0x0A800000  rootfs1
0x0A800000 - 0x15200000  rootfs_data
0x15200000 - 0x1e800000  rootfs

また,デフォルトのbootcmdは,nboot 0x2100000 0 0x00C00000; bootmとなっているので, kernel1の後半部分(0x00C00000 - 0x01200000)のカーネルをロードして起動していると推測できます.

そこで,ビルドしたカスタムカーネルを通常の起動で使用されていないkernel1の前半部分(0x00600000 - 0x00C00000)に書き込みます.

nand eraseでkernel1の前半部分(0x00600000 - 0x00C00000)を削除し, tftpbootコマンドでメモリの0x2100000にuImageをロードします.

そして,nand writeコマンドでuImageを書き込みます. 書き込み時に注意する点として,書き込むサイズ(nand writeの3つ目のアドレス)を128KiBの倍数にしないと書き込めません. ここでは,5MiBと指定していますが,uImageのサイズ以上6MiB以下であれば問題ありません.

U-BOOT # nand erase 0x00600000 0x00600000

U-BOOT # tftpboot 0x2100000 uImage

U-BOOT # nand write 0x2100000 0x00600000 0x00500000

起動パラメータ変更

NANDフラッシュメモリカーネルを書き込んだら,起動時にカスタムカーネルを読み込みんでArch Linuxが起動するように設定します.

U-BOOT # set arch_bootargs root=/dev/sda1 init=/sbin/init console=ttyS0,115200 SB_PHY=PPSS ni_napi_budget=16 qm_acp_enable=0 ni_rx_noncache=0 qm_int_buff=0 ethaddr0=XX:XX:XX:XX:XX:XX ethaddr1=XX:XX:XX:XX:XX:XX ethaddr2=XX:XX:XX:XX:XX:XX wifiaddr0=XX:XX:XX:XX:XX:XX wifiaddr1=XX:XX:XX:XX:XX:XX mtdparts=cs752x_nand_flash:1024K@0x00100000(uboot-env0),1024K@0x00300000(uboot-env1),1024K@0x00400000(sb0),1024K@0x00500000(sb1),153600K@0x15200000(rootfs),174080K@0x0A800000(rootfs_data),6144K@0x00600000(kernel1),153600K@0x01200000(rootfs1)

U-BOOT # set archlinux 'nboot 0x2100000 0 0x600000;setenv bootargs ${arch_bootargs};bootm 0x2100000'

U-BOOT # set bootcmd 'run archlinux'

U-BOOT # saveenv

起動パラメータの変更が終わったので実際に起動してみます.

U-BOOT # run archlinux

Arch Linuxのログイン画面が出れば成功です.

Arch Linuxの設定

ネットワーク設定

Arch Linuxが起動できたので,netctlでネットワークの設定をします. /etc/netctl/eth1に下記のようなファイルを作成します. IPアドレスは適宜変更してください.

Description='A basic static ethernet connection'
Interface=eth1
Connection=ethernet
IP=static
Address=('192.168.1.101/24')
Gateway='192.168.1.1'
DNS=('192.168.1.1')

そしてeth1を有効にすればネットワーク接続できると思います.

[root@alarm ~]# systemctl start netctl
[root@alarm ~]# systemctl enable netctl
[root@alarm ~]# netctl start eth1
[root@alarm ~]# netctl enable eth1

Pacmanの設定

Pacmanを使用するために,キーリングを初期化する必要がありますが,pacman-key --initを実行してもエントロピーの生成が終わらないためキーリングの初期化ができませんでした.

そこで,havegedを使用して擬似的にエントロピーを生成します. 下記のような手順でキーリングの初期化を行います.

  1. Pacmanの署名チェックを無効化
  2. havegedをインストール
  3. havegedを使用してキーリングの初期化
  4. havegedをアンインストール
  5. Pacmanの署名チェックの有効化

Pacmanの署名チェックを無効化するために,/etc/pacman.conf[community]SigLevel = Neverを追加します.

  [community]
+ SigLevel = Never
  Include = /etc/pacman.d/mirrorlist

havegedをインストール後,キーリングを初期化し,havegedをアンインストールします.

[root@alarm ~]# pacman -S haveged
[root@alarm ~]# haveged -w 1024
[root@alarm ~]# pacman-key --init
[root@alarm ~]# pacman-key --populate archlinuxarm
[root@alarm ~]# pkill haveged
[root@alarm ~]# pacman -Rs haveged

Pacmanの署名設定を元に戻します.

  [community]
- SigLevel = Never
  Include = /etc/pacman.d/mirrorlist

これでPacmanが使えるようになります. あとは通常のArch Linuxと同様にいろいろ設定すればOKです.

シャットダウン時にカーネルパニックを起こしたり(シャットダウン自体はできている),起動後に勝手にリブートしたりするなど問題はありますが, とりあえずArch Linuxが使えるようになりました.

f:id:tetsu31415:20181223010937j:plain

参考記事

  1. NSB-3NR1T1MLVにGentooを入れる - misodengakuのブログ
  2. NSB-3NR1T1MLVをLinux箱として使う (Debian インストール) - Qiita
  3. Raspberry Pi - ArchWiki
  4. Calvin's | Insufficient entropy pacman-key –init
  5. CentOS7にcrosstool-ngを使ってARMクロスコンパイラをインストール – Kyangのブログ