ブートローダについてのメモ

PCが起動時に, OSを呼び出すためのソフトウェア. 一般的にハードディスクの先頭にある「MBR(マスターブートレコード)」 という領域に記録されている. PCの電源を投入するとBIOSが起動される.BIOSは0xfffffff0(reset vector)番地に格納されている. BIOSがブートローダを呼び出し, その後ブートローダがカーネル(OS)を呼び出す. MBRの探索は優先度の高いブートデバイスから順番にそのデバイスの1セクタの末尾2バイトが0x55, 0xaa(boot signature)であるか確認する 発見するとそのセクタを 0x7c00 番地にロードして実行する. どうやらUEFIではMBRとかのところらへんが少し違うらしいがよくわからん.

僕の理解では,BIOS(UEFI)はファームウェアだからギリギリハードウェアの領域で, ブートローダからソフトウェアという印象.

おそらく今の主流はGRUB2でubuntuは早々にこれを導入していた. 他のデストリはしばらく従来の「GRUB Legacy」を使っていた. ちなみにGRUBは GRand Unified Bootloader とかっていう UEFIは Unified Extensible Firmware Interface とかっていう 他にはSyslinux とか LILOとかっていうのがあるらしい.

GRUB2

以下,GRUB2についてのメモ

仕組み

ファイル構成と設定方法について

設定のメインファイルは「/etc/grub/grub.cfg」だが, このファイルは直接編集する訳ではなく,別のファイルに設定を書き, コマンドを実行してファイルを生成する. 編集するファイルは「/etc/default/grub」と「/etc/grub.d/」. これらを編集したのちに

$ sudo grub-mkconfig -o /boot/grub/grub.cfg

or

$ sudo update-grub2       #これちょっとオプションとか足りないかもしれないけど

とかする.

/etc/default/grub

grub-mkconfigはシェル(sh)スクリプトで,基本的にはそれに読み込まれる パラメータを記述するファイル.

パラメータ

説明

GRUB_DEFAULT

デフォルトのOSを指定する為のパラメータ.
index,メニューで表示される名称の他,
「saved」とすると前回起動したOSがデフォルトになる.

GRUB_TIMEOUT

デフォルトのOSを起動するまでの時間を秒で指定する.

GRUB_HIDDEN_TIMEOUT

これが指定されるとメニューの表示がない.
また,これで指定された秒数だけ待つ.

GRUB_HIDDEN_TIMEOUT_QUIET

trueかfalseを指定する.
falseの場合画面にGRUB_HIDDEN_TIMEOUTの残り時間を表示する.

GRUB_CMDLINE_LINUX

カーネルのコマンドラインオプションを追加する.

GRUB_CMDLINE_LINUX_DEFAULT_DEFAULT

通常起動の場合にコマンドラインオプションを追加する.

GRUB_GFXMOD

画像の解像度を指定するパラメータ.

GRUB_BACKGROUND

背景画像を指定するパラメータ.

コマンドラインオプションに関して: http://manpages.ubuntu.com/manpages/bionic/ja/man7/bootparam.7.html

コマンドラインオプションを確認する

$ sudo cat /proc/cmdline

/etc/grub.d/

「README」,「.dpkg-」以外の実行権限のあるファイルが対象. これらは/etc/default/grubの設定に従った内容を出力するので, 基本的にこのファイルも編集しない.どうしてもの場合のみ編集する.

カーネルが起動した後どうなってるのって話

カーネルが起動した後,まず初期化の為のソフトウェア(ブートプロセス)を走らせる. これが古いubuntuだとinit/Upstart?だったり,1604くらいから?はsystemdだったりする. カーネルは初期の実行コマンドとして/sbin/init, /etc/init, /bin/init, /bin/shの順番で実行を試み,全てに失敗したらpanicする. ちなみに初期コマンドはカーネルのコマンドラインオプションで指定することができて,init=...ってする. 今は/sbin/initはsystemd(/lib/systemd/systemdとか)へのシンボリックリンクになっているため,systemdが動くことになる.

あとはまだ書くのめんどいからここ参照(http://equj65.net/tech/systemd-boot/)

initについてとプロセスの話

Linuxでは厳密にプロセスツリーという階層が存在する. これの一番上にinitがある. プロセスはforkすることで子プロセスを作るが,(作った元は親プロセス) 最初のプロセス(多分initを限定していいと思うけど)を覗く全てのプロセスには親プロセスが存在する. 子プロセスよりも先に親プロセスが死んでしまう場合,カーネルが子プロセスを親プロセスに繋ぎ直す.

プロセスは終了してもすぐにはシステムから削除されず, プロセスの一部をメモリ内に残して親プロセスが終了を確認できるようにする. 終了待ち合わせが完了すると子プロセスは完全に破棄される. 終了待ち合わせがされないプロセスはゾンビプロセスと呼ばれる. initはゾンビプロセスが永久に存在することの内容に定期的に全ての子プロセスに終了を問い合わせる.

systemd

うおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお 詳細はまたこんどだなああああああああああああ

systemctlコマンド

SYNOPSIS

$ sudo systemctl [OPTIONS...] COMMAND [NAME...]

OPTIONS

めんどいあとでかく

COMMAND

COMMAND

意味

start

Unitを開始

stop

Unitを停止

status

ステータスを見る

reload

設定ファイルをリロード

restart

リスタート(対象が停止してたら起動)

kill

対象のUnitに対してシグナルを送る.デフォルトはSIGTERM(killコマンドで出るシグナル). --signal= で指定可能.

https://qiita.com/sinsengumi/items/24d726ec6c761fc75cc9

bootに関するまとめ

ちなみにこれはUEFIの場合はおそらく間違っているので修正が必要.

※参考※https://eng-entrance.com/linux-bootloader UEFIの場合はUEFI自体が一つのシステムとして形になっており、 FAT系のパーティションを自力で検出、のちにGPTをロードしOSを読み出してゆくというながれになる。 昨今のGRUBであればUEFI環境でも問題なく稼動する。 しかし、もし何か事情があって古いブートローダ、例えば古典的なLILOを使用しなければならないときはUEFIをレガシーなモードで動作させると、 従来のBIOSとMBRの組み合わせと同じ挙動を再現するようになっている。

  1. 電源が入る.

  2. BIOS(UEFI)が起動し,ハードウェアが初期化される.

  3. MBRからブートローダが読み込まれ起動し,カーネルの読み込み・起動が行われる.

  4. モジュールのロード後,/sbin/init(systemd)が起動する.

  5. default.targetというUnitが処理される.

  6. システムの用途に適した(登録された?)ターゲットが処理される.

  7. ログイン受付開始(まずinitがgettyプロセスを作ってそこからgettyがlogin(1)にexecで良いはず.ちなみに login: のプロンプト表示まで?はgettyらしい?このへんちょい怪しい)

vmlinuzとかinitrd.imgとかがよくわからないので調べたやつ

vmlinuzは,ブートローダから実行されるカーネルの実行バイナリらしい. 簡単な初期化を行なった後にカーネル本体を解凍してメモリにロードする.

initrdは初期RAMディスクとかっていうらしい. カーネルが全ての初期化を終えた後,initrdを展開して仮のファイルシステム(ミニルート?)としてマウントする. 本番のルートファイルシステムが置いてあるディスクをマウントするために必要なドライバや, 各種ユーティリティが含まれる. initrd とinitramfsの2種類あるらしいが違いはよくわかってない. これあれか,init root directry か init ram disk って感じかななるほど. initrdのマウントに成功した後,initrdの中の/sbin/initを実行するらしい.

ちなみに,/boot/ いかにvmlinuzとinitrd.imgの他にSystem.mapみたいなファイルも転がってる. これはカーネルが使用するシンボルテーブルらしく,メモリ上でのシンボルとアドレスの対応関係を示したものである.したものである nmコマンドの出力結果そのままであるらしいが正直よくわからない.

https://wiki.gentoo.org/wiki/GRUB2/ja https://keichi.net/post/linux-boot/ https://0xax.gitbooks.io/linux-insides/content/index.html ←これ英語だけどめっちゃ詳しそうでやばい.

https://ja.wikipedia.org/wiki/Vmlinux https://ja.wikipedia.org/wiki/System.map

virt-install でubuntu2020がインストールできなかった話

題の通りのことになった調べた時のメモ 普段は location に http://jp.archive.ubuntu.com/ubuntu/dists/bionic/main/installer-amd64/ (2018, bionic) とかってしてインストールできてるんだけど, 2020(focali) で http://jp.archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/ ってしたらエラった. kvm

ググったら https://github.com/virt-manager/virt-manager/pull/101 こんなプルリクがvirt-managerにでてることがわかった. (これってマージされたらどっから見えるようになるんかな? これ見えなくなるんかな?) ちなみに内容は↓のような感じ

  1. (おそらく)locationで指定されたのの後に取得できたもののpathをみて,URL指定かpath指定かを判断しているところがあるが, URLだった時にcurrent/images/MANIFESTを見るようになっていて, ubuntu2020の場合だとそこが/current/legacy-images/MANIFESTだからmatchしなくなっているのでそれを足した.

  2. os_variantが2004以上?だった時にurl_prefixなるものをlagacy~~に書き換えること

プルリクのコメントや,実際に中をみてみた感じ,指定したpath以降の中身に差がないようだったのでこれでいけるらしい? (header.htmlとfooter.htmlが含まれているだけだった) ただ,このlagacy-imagesという命名,2020以前でもことある場面で何度か使われていて, 時々なぜかlagacyが付かなくなっていたり(1910とか)して,どういう分け方してるのかわからん. あとはこのlagacyな配布はしばらくしたら止める予定みたいなことが書いてある. プルリクのコメントではd-iなビルドに対応すべきみたいなこと書いてあるんだけどそれに移行すると言うことなのか... 「In the future, virt-manager will need to switch to cloud-images.ubuntu.com or maas.io images or live-server images, as d-i builds are going away.」 ちなみにd-iって多分debian installerのことじゃないかと思うんだけど,いまいちよくわかってない.↓ https://qiita.com/hidakanoko/items/c36ac5f1cc0eefbf8b84 http://ftp.gnome.org/pub/debian-meetings/2006/debconf6/slides/Debian_installer_workshop-Frans_Pop/paper/

なんかもうちょっと掘り下げたらインストーラーの仕組みとか一気にわかりそうな気がするんだけど 今は放置しておく.

ところで,virt-installでISOファイルを選ぶ話, インストールには,vmlinuxとinitrd (で正しいかちょっと正確ではないが)が必要で,それが含まれているISOイメージである必要がある. マウントして確かめろ. (virt-install can recognize certain distribution trees and fetches a bootable kernel/initrd pair to launch the install.) ちなみにこれらはubuntu2020だとlegacyとか言う名前がついてるISOファイルにあって,install/ に入ってた. ↑でlegacyとかd-iとかあったけど,これちょっと関係してそうな気がするよね