ArchLinux: カーネルを再ビルドする

ABS(Arch Build System)を使ってカーネルを再ビルドします。

 

1 ABSのインストールとカーネルのダウンロード

ABSをインストールします。

$ sudo pacman -S --noconfirm abs

core/linuxパッケージのビルドスクリプトをダウンロードします。

$ sudo abs core/linux

自分の作業ディレクトリへコピーします。

$ cp -a /var/abs/core/linux .
$ cd linux

2 ビルドに必要なパッケージのインストール

ビルドに必要なパッケージはPKGBUILDのmakedepends配列に格納されています。

PKGBUILDはbashスクリプトなので、bash上で以下を実行してください。

$ . PKGBUILD
$ sudo pacman -S --asdeps --noconfirm ${makedepends[@]}

makepkgに-sオプションを指定することで、ビルド時に必要なパッケージをインストールすることもできます。

3 GPGキー

makepkgに–skippgpcheckオプションをつけない場合は以下のGPGキーをインポートする必要があります。

$ gpg --keyserver keys.gnupg.net --recv-keys 79BE3E4300411886
$ gpg --keyserver keys.gnupg.net --recv-keys 38DBBDC86092693E

4 カーネル名の変更

PKGBUILDのpkgbaseを変更することでカーネル名を変更できます。

$ head PKGBUILD
# $Id: PKGBUILD 267890 2016-05-12 16:05:36Z tpowa $
# Maintainer: Tobias Powalowski <tpowa@archlinux.org>
# Maintainer: Thomas Baechler <thomas@archlinux.org>

pkgbase=linux               # Build stock -ARCH kernel
#pkgbase=linux-custom       # Build kernel with a different name
_srcname=linux-4.5
pkgver=4.5.4
pkgrel=1
arch=('i686' 'x86_64')

すでにlinux-customという名前が用意されているので、それを用います。

$ sed -i -e 's/^pkgbase=linux/#pkgbase=linux/g' \
-e 's/^#pkgbase=linux-custom/pkgbase=linux-custom/g' PKGBUILD

5 ソースコードの変更

ソースコードの展開、パッチの適用、.configファイルのコピーを実行します(prepare関数の実行)。

$ makepkg -o

この段階でsrc/linux-4.5のコードを変更すればパッケージへ反映されるようになります。

5.1 パッチを作成する

linux-4.5のソースツリーをコピーして、パッチを作成します。

$ cd src
$ cp -a linux-4.5{,.org}
$ # Change code in linux-4.5
$ diff -uprN linux-4.5{.org,} > ../hello.patch
$ cd ..

カーネルログに"Hello, World"と表示されるhello.patchという名前のパッチを作成しました。

$ diff -uprN linux-4.5.org/init/main.c linux-4.5/init/main.c
--- linux-4.5.org/init/main.c   2016-03-14 04:28:54.000000000 +0000
+++ linux-4.5/init/main.c       2016-06-04 07:26:53.643333334 +0000
@@ -933,6 +933,8 @@ static int __ref kernel_init(void *unuse
 {
        int ret;

+       printk("Hello, World");
+
        kernel_init_freeable();
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();

パッチのsha256sumによるハッシュ値を取得します。

$ sha256sum hello.patch
a389f1bacf13a378993b96dce517f5b8465dbb59f9a11ba2bd12f12e2c99aab8  hello.patch

PKGBUILDを変更して、sources配列にhello.patchを加え、sha256sums配列にハッシュ値を加えます。sources配列n番目の要素のハッシュ値はsha256sums配列n番目の要素に格納されます。

$ diff -uprN PKGBUILD{.org,}
--- PKGBUILD.org        2016-06-04 10:31:34.003333329 +0000
+++ PKGBUILD    2016-06-04 10:34:47.213333334 +0000
@@ -20,7 +20,8 @@ source=("https://www.kernel.org/pub/linu
         'config' 'config.x86_64'
         # standard config files for mkinitcpio ramdisk
         'linux.preset'
-        'change-default-console-loglevel.patch')
+        'change-default-console-loglevel.patch'
+        'hello.patch')

 sha256sums=('a40defb401e01b37d6b8c8ad5c1bbab665be6ac6310cdeed59950c96b31a519c'
             'SKIP'
@@ -29,7 +30,8 @@ sha256sums=('a40defb401e01b37d6b8c8ad5c1
             '2355efbab340d16c1b60a7805b987a78e57266809ba6c986ceef68ef7ce71db0'
             'cee1781f96e55a909757c4533cdacb57c3ffe6f6f01f709e8a5a837dc4a68bba'
             'f0d90e756f14533ee67afda280500511a62465b4f76adcc5effa95a40045179c'
-            '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99')
+            '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99'
+            'a389f1bacf13a378993b96dce517f5b8465dbb59f9a11ba2bd12f12e2c99aab8')
 validpgpkeys=(
               'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds
               '647F28654894E3BD457199BE38DBBDC86092693E' # Greg Kroah-Hartman
@@ -51,6 +53,8 @@ prepare() {
   # (relevant patch sent upstream: https://lkml.org/lkml/2011/7/26/227)
   patch -p1 -i "${srcdir}/change-default-console-loglevel.patch"

+  patch -p1 -i "${srcdir}/hello.patch"
+
   if [ "${CARCH}" = "x86_64" ]; then
     cat "${srcdir}/config.x86_64" > ./.config
   else

6 カーネルコンフィグの変更

config.x86_64を.configにコピーして、make menuconfig経由でカーネルコンフィグを変更します。

$ cd src/linux-4.5
$ cp ../../config.x86_64 .config
$ make menuconfig
# Change kernel config
$ cp .config ../../config.x86_64
$ cd ../..

CONFIG_MESSAGE_LOGLEVEL_DEFAULTを4から7に変更しました。CONFIG_BMP085はmake menuconfigの延長でyからmに補正されています。

$ diff -uprN config.x86_64{.org,}
--- config.x86_64.org   2016-06-04 19:29:26.463333332 +0000
+++ config.x86_64       2016-06-04 19:29:52.260000000 +0000
@@ -1,6 +1,6 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Linux/x86 4.5.2-1 Kernel Configuration
+# Linux/x86 4.5.4-1 Kernel Configuration
 #
 CONFIG_64BIT=y
 CONFIG_X86_64=y
@@ -1929,7 +1929,7 @@ CONFIG_HMC6352=m
 CONFIG_DS1682=m
 # CONFIG_TI_DAC7512 is not set
 CONFIG_VMWARE_BALLOON=m
-CONFIG_BMP085=y
+CONFIG_BMP085=m
 CONFIG_BMP085_I2C=m
 # CONFIG_BMP085_SPI is not set
 CONFIG_USB_SWITCH_FSA9480=m
@@ -7180,7 +7180,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # printk and dmesg options
 #
 CONFIG_PRINTK_TIME=y
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
 # CONFIG_BOOT_PRINTK_DELAY is not set
 CONFIG_DYNAMIC_DEBUG=y

新たなconfig.x86_64のsha256sumによるハッシュ値を取得します。

$ sha256sum config.x86_64
eb057cc5c43c6ff7b572e5229e0916bd741f074c5286cf9b282c335ae5c95ab1  config.x86_64

PKGCONFIGにハッシュ値を反映させます。

$ diff -uprN PKGBUILD{.org,}
--- PKGBUILD.org        2016-06-04 19:30:29.386666644 +0000
+++ PKGBUILD    2016-06-04 19:34:10.796666667 +0000
@@ -28,7 +28,7 @@ sha256sums=('a40defb401e01b37d6b8c8ad5c1
             '6a9cfe691ac77346c48b7f83375a1880ebb379594de1000acad45da45d711e42'
             'SKIP'
             '2355efbab340d16c1b60a7805b987a78e57266809ba6c986ceef68ef7ce71db0'
-            'cee1781f96e55a909757c4533cdacb57c3ffe6f6f01f709e8a5a837dc4a68bba'
+            'eb057cc5c43c6ff7b572e5229e0916bd741f074c5286cf9b282c335ae5c95ab1'
             'f0d90e756f14533ee67afda280500511a62465b4f76adcc5effa95a40045179c'
             '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99'
             'a389f1bacf13a378993b96dce517f5b8465dbb59f9a11ba2bd12f12e2c99aab8')

7 ビルド

パッケージをビルドします(build関数の実行)。

$ makepkg -e

8 インストール

作成されたパッケージをインストールして、/boot/grub/grub.cfgを更新します。

$ sudo pacman -U --noconfirm linux-custom-4.5.4-1-x86_64.pkg.tar.xz
$ sudo grub-mkconfig -o /boot/grub/grub.cfg

linux-customのファイルが/bootにインストールされました。

$ ls /boot/
grub                                 initramfs-linux-fallback.img
vmlinuz-linux
initramfs-linux-custom-fallback.img  initramfs-linux.img
vmlinuz-linux-custom
initramfs-linux-custom.img           lost+found

9 動作確認

GRUBメニューのトップ画面は変わりありません。

0001_GRUB.png

"Arch Linux"はlinux-customを読み込むようになりました。

0002_ArchLinux-options.png

"Advanced options for Arch Linux"にlinux-customの項目が追加されました。

0003_Advanced-options.png

起動後、uname -rの出力も変わりました。

$ uname -r
4.5.4-1-custom

カーネルログに"Hello, World"と表示されました。

$ dmesg
[    0.027234] Freeing SMP alternatives memory: 24K
(ffffffff81a21000 - ffffffff81a27000)
[    0.029717] ftrace: allocating 23133 entries in 91 pages
[    0.050603] Hello, World
[    0.050738] x2apic enabled
[    0.050927] Switched APIC routing to physical x2apic.

CONFIG_MESSAGE_LOGLEVEL_DEFAULTも4から7へ変更されました。

$ zcat /proc/config.gz | grep CONFIG_MESSAGE_LOGLEVEL_DEFAULT
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7