Linux From Scratch に挑戦!【Part 1】

Linux From Scratch に挑戦!の第1回ということで,今回からは実際に LFS の構築作業を行っていきたいと思います.

今回の作業範囲

第1回では LFS 構築の準備作業として,ホスト OS の準備と手動パーティショニングを中心に行っていきたいと思います.

具体的には,以下の通りです.

  • ホスト OS の準備
  • 手動パーティショニング
  • パーティションのフォーマット
  • 変数の設定
  • パーティションのマウント

LFS のドキュメントでは第2章の内容になります.

作業内容

ホスト OS の準備

まずは,LFS を構築するためのホスト OS を準備します.ディストリビューションは特に指定されていませんが,この後に示すホストシステム要件を満たしている必要があります.一応 LFS では,例として Debian, OpenMandriva, Fedora, openSUSE を挙げています.

ホストシステム要件

  • Binutils-2.17 (Versions greater than 2.30 are not recommended as they have not been tested)
  • Bison-2.3 (/usr/bin/yacc should be a link to bison or small script that executes bison)
  • Bzip2-1.0.4
  • Coreutils-6.9
  • Diffutils-2.8.1
  • Findutils-4.2.31
  • Gawk-4.0.1 (/usr/bin/awk should be a link to gawk)
  • GCC-4.7 including the C++ compiler, g++ (Versions greater than 7.3.0 are not recommended as they have not been tested)
  • Glibc-2.11 (Versions greater than 2.27 are not recommended as they have not been tested)
  • Grep-2.5.1a
  • Gzip-1.3.12
  • Linux Kernel-3.2
  • M4-1.4.10
  • Make-3.81
  • Patch-2.5.4
  • Perl-5.8.8
  • Sed-4.1.5
  • Tar-1.22
  • Texinfo-4.7
  • Xz-5.0.0

ホスト OS のディストリビューションは Fedora 28 を使うことにしました.特に理由はないのですが,使い慣れた Red Hat 系 かつ久しぶりに使いたかったからです.

Fedora 28 のインストール

とりあえず,Fedora 28 の CUI を VirtualBox 上にインストールします.その後に,パッケージのアップデート,必要最低限のツールのインストールを行います.また,今回はサーバとして外部に公開するわけではないので SELinux を停止しておきます.

$ sudo yum update
$ sudo yum upgrade
$ sudo yum groupinstall "Development Tools"
$ sudo yum install vim
$ mkdir ~/Documents
$ sudo vim /etc/selinux/config
SELINUX=disabled
$ sudo systemctl reboot

ホストシステム要件のチェック

ホストシステム要件のチェックを行うシェルスクリプトを作成し,実行します.その結果を参考に,足りないソフトウェアをインストールします.

$ cd ~/Documents/
$ cat > version-check.sh << "EOF"
#!/bin/bash
# Simple script to list version numbers of critical development tools
export LC_ALL=C
bash --version | head -n1 | cut -d" " -f2-4
MYSH=$(readlink -f /bin/sh)
echo "/bin/sh -> $MYSH"
echo $MYSH | grep -q bash || echo "ERROR: /bin/sh does not point to bash"
unset MYSH

echo -n "Binutils: "; ld --version | head -n1 | cut -d" " -f3-
bison --version | head -n1

if [ -h /usr/bin/yacc ]; then
  echo "/usr/bin/yacc -> `readlink -f /usr/bin/yacc`";
elif [ -x /usr/bin/yacc ]; then
  echo yacc is `/usr/bin/yacc --version | head -n1`
else
  echo "yacc not found"
fi

bzip2 --version 2>&1 < /dev/null | head -n1 | cut -d" " -f1,6-
echo -n "Coreutils: "; chown --version | head -n1 | cut -d")" -f2
diff --version | head -n1
find --version | head -n1
gawk --version | head -n1

if [ -h /usr/bin/awk ]; then
  echo "/usr/bin/awk -> `readlink -f /usr/bin/awk`";
elif [ -x /usr/bin/awk ]; then
  echo awk is `/usr/bin/awk --version | head -n1`
else
  echo "awk not found"
fi

gcc --version | head -n1
g++ --version | head -n1
ldd --version | head -n1 | cut -d" " -f2-  # glibc version
grep --version | head -n1
gzip --version | head -n1
cat /proc/version
m4 --version | head -n1
make --version | head -n1
patch --version | head -n1
echo Perl `perl -V:version`
sed --version | head -n1
tar --version | head -n1
makeinfo --version | head -n1
xz --version | head -n1
echo 'int main(){}' > dummy.c && g++ -o dummy dummy.c
if [ -x dummy ]
  then echo "g++ compilation OK";
  else echo "g++ compilation failed"; fi
rm -f dummy.c dummy
EOF

$ sudo chmod 755 version-check.sh
$ ./version-check.sh

この結果,自分の場合は bison, gcc-c++, texinfo, byacc が足りなかったので追加でインストールしました.

$ sudo yum -y install bison gcc-c++ texinfo byacc
$ ./version-check.sh
bash, version 4.4.19(1)-release
/bin/sh -> /usr/bin/bash
Binutils: version 2.29.1-23.fc28
bison (GNU Bison) 3.0.4
Usage: /usr/bin/yacc [options] filename

Options:
  -b file_prefix        set filename prefix (default "y.")
  -B                    create a backtracking parser
  -d                    write definitions (.tab.h)
  -i                    write interface (y.tab.i)
  -g                    write a graphical description
  -l                    suppress #line directives
  -L                    enable position processing, e.g., "%locations"
  -o output_file        (default ".tab.c")
  -p symbol_prefix      set symbol prefix (default "yy")
  -P                    create a reentrant parser, e.g., "%pure-parser"
  -r                    produce separate code and table files (y.code.c)
  -s                    suppress #define's for quoted names in %token lines
  -t                    add debugging support
  -v                    write description (y.output)
  -V                    show version information and exit
yacc is
bzip2,  Version 1.0.6, 6-Sept-2010.
Coreutils:  8.29
diff (GNU diffutils) 3.6
find (GNU findutils) 4.6.0
GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2)
/usr/bin/awk -> /usr/bin/gawk
gcc (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1)
g++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1)
(GNU libc) 2.27
grep (GNU grep) 3.1
gzip 1.9
Linux version 4.16.14-300.fc28.x86_64 (mockbuild@bkernel02.phx2.fedoraproject.org) (gcc version 8.1.1 20180502 (Red Hat 8.1.1-1) (GCC)) #1 SMP Tue Jun 5 16:23:44 UTC 2018
m4 (GNU M4) 1.4.18
GNU Make 4.2.1
GNU patch 2.7.6
Perl version='5.26.2';
sed (GNU sed) 4.5
tar (GNU tar) 1.30
texi2any (GNU texinfo) 6.5
xz (XZ Utils) 5.2.4
g++ compilation OK

Command Not Found が表示されなくなったので多分大丈夫だと思います.また,推奨されていないバージョンのソフトウェアがありますが,ダウングレードが面倒なのでとりあえずこのまま進めます.エラーが出たら考えます(笑)

手動パーティショニング

パーティション分割を行っていきます.今回は VirtualBox 上で行っているので,LFS 用の仮想ストレージを作成し Fedora に追加しました./dev/sda が Fedora がインストールされているストレージ,/dev/sdb が LFS を構築するストレージです.また,OS の起動は BIOS + MBR を想定しています.

ドキュメントを参考に,パーティションは以下のように分割することにしました.fdisk コマンドの使い方についてはここでは説明を省きます.

  • /boot – 128MB
  • / – 10GB
  • swap – 2GB
  • /home – 残り
$ sudo fdisk /dev/sdb
$ lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   64G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   63G  0 part
  ├─fedora-root 253:0    0   15G  0 lvm  /
  └─fedora-swap 253:1    0  2.2G  0 lvm  [SWAP]
sdb               8:16   0   40G  0 disk
├─sdb1            8:17   0  128M  0 part
├─sdb2            8:18   0   10G  0 part
├─sdb3            8:19   0    2G  0 part
└─sdb4            8:20   0 27.9G  0 part
sr0              11:0    1 1024M  0 rom

パーティションのフォーマット

次にパーティションのフォーマットを行います.swap 領域以外は,ファイルシステムを ext4 にしました.

$ sudo mkfs.ext4 /dev/sdb1 -L boot
$ sudo mkfs.ext4 /dev/sdb2 -L /
$ sudo mkfs.ext4 /dev/sdb4 -L home
$ sudo mkswap /dev/sdb3
$ lsblk --fs
NAME            FSTYPE      LABEL UUID                                   MOUNTPOINT
sda
├─sda1          ext4              38a102c4-7fbd-4bbe-923e-3d91e9c3b7bd   /boot
└─sda2          LVM2_member       y1Xa3L-GRpp-R5vL-QKhp-bW4Y-Y4B3-r0mUZf
  ├─fedora-root xfs               13a464ea-5073-4ce0-bc42-532f0030e3d0   /
  └─fedora-swap swap              3919edbe-7bfb-40bd-84c4-46d377086f59   [SWAP]
sdb
├─sdb1          ext4        boot  0a75681d-6986-4d83-89ac-3a2116deca9d
├─sdb2          ext4        /     4971cad7-597d-44f2-b464-fb247df852b2
├─sdb3          swap              23688bc9-0256-4ff4-9a42-5e47884cd575
└─sdb4          ext4        home  37ecb975-eea6-4a72-b52d-18f36edabe76
sr0

変数の設定

この後の作業で使用する変数の設定を行います.再起動するたびに設定し直すのが面倒なので,bash の設定ファイルに変数を設定しておきます.

$ echo 'export LFS=/mnt/lfs' >> ~/.bash_profile
$ echo $LFS
/mnt/lfs

パーティションのマウント

次に作成したパーティションをマウントします.また,今後再起動するたびにマウントし直すのが面倒なので,/etc/fstab ファイルに設定を追加します.

$ sudo mkdir -pv $LFS
$ sudo mount -v -t ext4 /dev/sdb2 $LFS
$ sudo mkdir -v $LFS/boot
$ sudo mount -v -t ext4 /dev/sdb1 $LFS/boot/
$ sudo mkdir -v $LFS/home
$ sudo mount -v -t ext4 /dev/sdb4 $LFS/home/
$ sudo /sbin/swapon -v /dev/sdb3
$ sudo vim /etc/fstab
/dev/sdb2               /mnt/lfs                ext4    defaults        1 1
/dev/sdb1               /mnt/lfs/boot           ext4    defaults        1 2
/dev/sdb4               /mnt/lfs/home           ext4    defaults        1 2
/dev/sdb3               swap                    swap    defaults        0 0

おわりに

今回はホスト OS の準備と手動パーティショニングを行いました.これらの作業は ArchLinux などのインストールでも行うので初めてではありませんでした.しかし,最初の頃は一つ一つ言葉の意味やなぜ行うのかを調べながら行った覚えがあります.これらの作業を行ったことがない人は一度でも触れておくと,自動パーティショニングを行う主要ディストリビューションを使う際も,柔軟な設定の変更を行うことができるようになるため非常におすすめです.

参考文献

http://www.linuxfromscratch.org/lfs/view/8.2-systemd/index.html
http://azsky2.html.xdomain.jp/note/archlinux/index.html