UEFIで始める
Linux From Scratch
@yohgami
2017/09/18
自己紹介
●
大神 祐真
– http://yuma.ohgami.jp
●
組み込みCPUボードメーカーの技術営業
●
趣味: フルスクラッチでのOS自作
– OS5: QEMU(i386)上で動作
●
ブートローダー・カーネル・ユーザーランドをシンプルに実装
●
全体で3000行程度(内カーネル2000行程度)
– PoiOS(OS6): 実機のUEFIファームウェア上で動作
●
UEFIの機能を呼び出すだけでOSっぽいものが作れるのでは?
●
CUI・GUIでファイル操作が行える1000行弱の実行バイナリ
自己紹介
Ohgami's Commentary on OS5
フルスクラッチで作る!
UEFIベアメタルプログラミング
フルスクラッチ自作OS(OS5)の
全ソースコード+コメンタリー本
エディタとコンパイラのみで
UEFIファームウェアを叩き
OSっぽいもの(poiOS)を作る本
今日お話すること
●
UEFIだとLFSを簡単に始められる!
今日お話すること
●
UEFIだとLFSを簡単に始められる!
●
Linuxカーネルが起動し、
/bin/shが立ち上がるまでを
QEMUと実機でやってみる
QEMU
1. Linuxカーネルを用意
1.1. ダウンロード
https://www.kernel.org/
$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.13.2.tar.xz
$ tar Jxf linux-4.13.2.tar.xz
1. Linuxカーネルを用意
1.2. ビルド環境構築
$ sudo apt-get build-dep linux-image-$(uname -r)
$ sudo apt install libncurses5-dev-dev
1. Linuxカーネルを用意
1.3. カーネルコンフィグ設定
$ cd linux-4.13.2
$ make x86_64_defconfig
$ make menuconfig
=> CONFIG_EFI_STUB を有効化
1. Linuxカーネルを用意
1.4. ビルド
$ make -j $(nproc)
・・・
・・・
・・・
$ ls arch/x86/boot/bzImage
arch/x86/boot/bzImage
2. BusyBoxを用意
2.1. ダウンロード
https://busybox.net/
$ wget http://busybox.net/downloads/busybox-1.27.2.tar.bz2
$ tar jxf busybox-1.27.2.tar.bz2
2. BusyBoxを用意
2.2. ビルド環境構築
$ sudo apt-get build-dep busybox
2. BusyBoxを用意
2.3. コンフィグ設定
$ cd busybox-1.27.2
$ make defconfig
$ make menuconfig
=> CONFIG_STATIC を有効化
2. BusyBoxを用意
2.4. ビルド
$ make -j $(nproc)
・・・
・・・
・・・
$ ls busybox
busybox
3. 配置
3.1. パーティションと見なすディレクトリ作成
$ mkdir p1 p2
3.2. Linuxカーネルイメージと
  BusyBoxバイナリを配置
$ cp linux-4.13.2/arch/x86/boot/bzImage p1/bzImage.efi
$ mkdir p2/bin
$ cp busybox-1.27.2/busybox p2/bin/busybox
$ ln -s busybox p2/bin/sh
4. QEMUで起動
4.1. QEMUとUEFIファームウェアインストール
$ sudo apt install qemu-system-x86 ovmf
4.1. QEMU起動
$ qemu-system-x86_64 -bios OVMF.fd -hda fat:p1 -hdb fat:p2
4.1. UEFI ShellからLinux起動
Shell> fs0:
fs0> bzImage.efi root=/dev/sdb1 init=/bin/sh rootwait
終了はウィンドウを閉じてしまっても良いが、
Ctrl+Alt+2 でQEMUモニターへ入り、quitコマンドでも終了できる
実機
1. USBフラッシュメモリ準備
1.1. パーティション作成
$ sudo fdisk /dev/sdb
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1,2, default 2):
Partition 2 has been deleted.
Command (m for help): d
Selected partition 1
Partition 1 has been deleted.
Command (m for help): d
No partition is defined yet!
Could not delete partition 1
既存のパーティションを全て削除
1. USBフラッシュメモリ準備
1.1. パーティション作成
Command (m for help): o
Created a new DOS disklabel with disk identifier 0x4c953ff5.
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-31277055, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-31277055, default 31277055): +128M
Created a new partition 1 of type 'Linux' and of size 128 MiB.
UEFIファームウェア用パーティション作成
1. USBフラッシュメモリ準備
1.1. パーティション作成
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (264192-31277055, default 264192):
Last sector, +sectors or +size{K,M,G,T,P} (264192-31277055, default 31277055):
Created a new partition 2 of type 'Linux' and of size 14.8 GiB.
ルートファイルシステム用パーティション作成
1. USBフラッシュメモリ準備
1.1. パーティション作成
Command (m for help): t
Partition number (1,2, default 2): 1
Hex code (type L to list all codes): b
If you have created or modified any DOS 6.x partitions, please see the fdisk 
documentation for additional information.
Changed type of partition 'Linux' to 'W95 FAT32'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
パーティションタイプ設定、設定反映
1. USBフラッシュメモリ準備
1.2. フォーマット
$ sudo mkfs.vfat -F 32 /dev/sdb1
$ sudo mkfs.ext4 /dev/sdb2
2. 配置
2.1. マウント
$ mkdir mp1 mp2
$ sudo mount /dev/sdb1 mp1
$ sudo mount /dev/sdb2 mp2
2.3. アンマウント
$ sudo umount mp1
$ sudo umount mp2
2.2. Linuxカーネルイメージと
  BusyBoxバイナリを配置
$ sudo cp p1/* mp1/
$ sudo cp -r p2/* mp2/
2. 配置
2.3. UEFI Shellをダウンロード、配置
$ wget 
https://github.com/tianocore/edk2/raw/master/EdkShellBinPkg/FullShell/X64/Shell_Full.efi
2.3. アンマウント
$ sudo umount mp1
$ sudo umount mp2
https://github.com/tianocore/edk2/tree/master/EdkShellBinPkg/FullShell/X64
$ sudo mkdir -p mp1/EFI/BOOT
$ sudo cp Shell_Full.efi mp1/EFI/BOOT/BOOTX64.EFI
3. 実機で起動
3.1. 起動ディスクの優先順位を変更し、
  USBフラッシュメモリから起動
3.2. UEFI ShellからLinux起動
PCメーカー毎に、適宜行ってください
Shell> fs0:
fs0> bzImage.efi root=/dev/sdb2 init=/bin/sh rootwait
shutdown、haltコマンド等無いので、電源ボタンで終了させてください
ルートファイルシステム(USBフラッシュメモリ第2パーティション)は、
Read Onlyでマウントされているため、ファイルシステム破壊の問題はありません。
おまけ: debootstrap
LFSでは無くなりますが、
aptが使えるルートファイルシステムを
手っ取り早く構築するには、
debootstrap というツールがあります。
$ sudo mount /dev/sdb2 mp2
$ sudo debootstrap sid mp2
(Debianのunstableを構築)
その後、UEFI Shellから以下の様なコマンドで
起動できます
Shell> fs0:
fs0> bzImage.ef root=/dev/sdb2 rootwait
技術書典3に参加します!
配置: か13
新刊
【技術書典3】
日時: 2017/10/22(日)
   11:00〜17:00
場所: アキバ・スクエア

UEFIで始めるLinux From Scratch