QEMU / gdb で Linux kernel の動きを確認する

# はじめに
QEMU / gdb で Linux kernel の動きを確認する方法を記載します。
OSはUbuntu14.04 / CPUはx86-64を使用しました。

# QEMU install
QEMUをinstallします。

```bash
sudo apt-get install -y qemu
qemu-system-x86_64 --version
QEMU emulator version 1.7.91 (Debian 2.0.0~rc1+dfsg-0ubuntu3), Copyright (c) 2003-2008 Fabrice Bellard
```

# kernel

## source codeの取得
次のコマンドでUbuntu14.04のkernelを取得します。

```bash
sudo apt-get install -y dpkg-dev
apt-get source linux-image-$(uname -r)
ls | grep linux
linux-3.13.0
linux_3.13.0-24.46.diff.gz
linux_3.13.0-24.46.dsc
linux_3.13.0.orig.tar.gz
```

kernelを設定します。サイズを小さくするためにallnoconfigを指定します。

```
make allnoconfig
```

allnoconfigにパッチを適用します。

```bash:console
patch .config minconfig.patch
```

minconfig.patchの内容です。

```:minconfig.patch
5,6c5,6
< # CONFIG_64BIT is not set
< CONFIG_X86_32=y
---
> CONFIG_64BIT=y
> CONFIG_X86_64=y
9,10c9,10
< CONFIG_OUTPUT_FORMAT="elf32-i386"
< CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
---
> CONFIG_OUTPUT_FORMAT="elf64-x86-64"
> CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
14a15
> CONFIG_NEED_DMA_MAP_STATE=y
17d17
< CONFIG_GENERIC_BUG=y
32,33c32,33
< # CONFIG_ZONE_DMA32 is not set
< # CONFIG_AUDIT_ARCH is not set
---
> CONFIG_ZONE_DMA32=y
> CONFIG_AUDIT_ARCH=y
36,37c36
< CONFIG_X86_32_LAZY_GS=y
< CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
---
> CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
79c78,79
< CONFIG_KTIME_SCALAR=y
---
> CONFIG_ARCH_CLOCKSOURCE_DATA=y
> CONFIG_GENERIC_TIME_VSYSCALL=y
81a82
> CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
96a98
> # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
110a113
> CONFIG_ARCH_SUPPORTS_INT128=y
112d114
< # CONFIG_CGROUPS is not set
122c124,131
< # CONFIG_BLK_DEV_INITRD is not set
---
> CONFIG_BLK_DEV_INITRD=y
> CONFIG_INITRAMFS_SOURCE=""
> CONFIG_RD_GZIP=y
> # CONFIG_RD_BZIP2 is not set
> # CONFIG_RD_LZMA is not set
> # CONFIG_RD_XZ is not set
> # CONFIG_RD_LZO is not set
> # CONFIG_RD_LZ4 is not set
126d134
< CONFIG_HAVE_UID16=y
129,130c137
< # CONFIG_EXPERT is not set
< CONFIG_UID16=y
---
> CONFIG_EXPERT=y
132c139
< CONFIG_KALLSYMS=y
---
> # CONFIG_KALLSYMS is not set
134,144c141,150
< CONFIG_BUG=y
< CONFIG_ELF_CORE=y
< CONFIG_PCSPKR_PLATFORM=y
< CONFIG_BASE_FULL=y
< CONFIG_FUTEX=y
< CONFIG_EPOLL=y
< CONFIG_SIGNALFD=y
< CONFIG_TIMERFD=y
< CONFIG_EVENTFD=y
< CONFIG_SHMEM=y
< CONFIG_AIO=y
---
> # CONFIG_BUG is not set
> # CONFIG_PCSPKR_PLATFORM is not set
> # CONFIG_BASE_FULL is not set
> # CONFIG_FUTEX is not set
> # CONFIG_EPOLL is not set
> # CONFIG_SIGNALFD is not set
> # CONFIG_TIMERFD is not set
> # CONFIG_EVENTFD is not set
> # CONFIG_SHMEM is not set
> # CONFIG_AIO is not set
151a158
> # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
156a164
> # CONFIG_SLOB is not set
171d178
< CONFIG_HAVE_DMA_CONTIGUOUS=y
186d192
< CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
187a194,195
> CONFIG_HAVE_CONTEXT_TRACKING=y
> CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
191,194c199,200
< CONFIG_MODULES_USE_ELF_REL=y
< CONFIG_CLONE_BACKWARDS=y
< CONFIG_OLD_SIGSUSPEND3=y
< CONFIG_OLD_SIGACTION=y
---
> CONFIG_MODULES_USE_ELF_RELA=y
> CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
199c205
< CONFIG_HAVE_GENERIC_DMA_COHERENT=y
---
> # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
201,202c207
< CONFIG_RT_MUTEXES=y
< CONFIG_BASE_SMALL=0
---
> CONFIG_BASE_SMALL=1
205d209
< # CONFIG_LBDAF is not set
237a242
> CONFIG_X86_MPPARSE=y
239d243
< # CONFIG_X86_32_IRIS is not set
244,254d247
< # CONFIG_M486 is not set
< # CONFIG_M586 is not set
< # CONFIG_M586TSC is not set
< # CONFIG_M586MMX is not set
< CONFIG_M686=y
< # CONFIG_MPENTIUMII is not set
< # CONFIG_MPENTIUMIII is not set
< # CONFIG_MPENTIUMM is not set
< # CONFIG_MPENTIUM4 is not set
< # CONFIG_MK6 is not set
< # CONFIG_MK7 is not set
256,265c249
< # CONFIG_MCRUSOE is not set
< # CONFIG_MEFFICEON is not set
< # CONFIG_MWINCHIPC6 is not set
< # CONFIG_MWINCHIP3D is not set
< # CONFIG_MELAN is not set
< # CONFIG_MGEODEGX1 is not set
< # CONFIG_MGEODE_LX is not set
< # CONFIG_MCYRIXIII is not set
< # CONFIG_MVIAC3_2 is not set
< # CONFIG_MVIAC7 is not set
---
> # CONFIG_MPSC is not set
268,272c252,254
< # CONFIG_X86_GENERIC is not set
< CONFIG_X86_INTERNODE_CACHE_SHIFT=5
< CONFIG_X86_L1_CACHE_SHIFT=5
< # CONFIG_X86_PPRO_FENCE is not set
< CONFIG_X86_USE_PPRO_CHECKSUM=y
---
> CONFIG_GENERIC_CPU=y
> CONFIG_X86_INTERNODE_CACHE_SHIFT=6
> CONFIG_X86_L1_CACHE_SHIFT=6
276c258
< CONFIG_X86_MINIMUM_CPU_FAMILY=5
---
> CONFIG_X86_MINIMUM_CPU_FAMILY=64
277a260
> # CONFIG_PROCESSOR_SELECT is not set
281,282c264
< CONFIG_CPU_SUP_TRANSMETA_32=y
< # CONFIG_HPET_TIMER is not set
---
> CONFIG_HPET_TIMER=y
283a266,267
> CONFIG_SWIOTLB=y
> CONFIG_IOMMU_HELPER=y
288c272,274
< # CONFIG_X86_UP_APIC is not set
---
> CONFIG_X86_LOCAL_APIC=y
> CONFIG_X86_IO_APIC=y
> # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
290,291d275
< CONFIG_VM86=y
< # CONFIG_TOSHIBA is not set
293d276
< # CONFIG_X86_REBOOTFIXUPS is not set
299,304c282,284
< # CONFIG_NOHIGHMEM is not set
< CONFIG_HIGHMEM4G=y
< # CONFIG_HIGHMEM64G is not set
< CONFIG_PAGE_OFFSET=0xC0000000
< CONFIG_HIGHMEM=y
< CONFIG_ARCH_FLATMEM_ENABLE=y
---
> CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
> CONFIG_ARCH_DMA_ADDR_T_64BIT=y
> CONFIG_DIRECT_GBPAGES=y
305a286
> CONFIG_ARCH_SPARSEMEM_DEFAULT=y
307c288
< CONFIG_ILLEGAL_POINTER_VALUE=0
---
> CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
309,313c290,296
< CONFIG_FLATMEM_MANUAL=y
< # CONFIG_SPARSEMEM_MANUAL is not set
< CONFIG_FLATMEM=y
< CONFIG_FLAT_NODE_MEM_MAP=y
< CONFIG_SPARSEMEM_STATIC=y
---
> CONFIG_SPARSEMEM_MANUAL=y
> CONFIG_SPARSEMEM=y
> CONFIG_HAVE_MEMORY_PRESENT=y
> CONFIG_SPARSEMEM_EXTREME=y
> CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
> CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
> CONFIG_SPARSEMEM_VMEMMAP=y
317a301
> # CONFIG_MEMORY_HOTPLUG is not set
319a304
> CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
321c306
< # CONFIG_PHYS_ADDR_T_64BIT is not set
---
> CONFIG_PHYS_ADDR_T_64BIT=y
333d317
< # CONFIG_HIGHPTE is not set
336d319
< # CONFIG_MATH_EMULATION is not set
356d338
< # CONFIG_COMPAT_VDSO is not set
378a361,365
> # Memory power savings
> #
> # CONFIG_I7300_IDLE is not set
> 
> #
384,389d370
< # CONFIG_ISA is not set
< # CONFIG_SCx200 is not set
< # CONFIG_OLPC is not set
< # CONFIG_ALIX is not set
< # CONFIG_NET5501 is not set
< # CONFIG_GEOS is not set
396c377
< # CONFIG_BINFMT_ELF is not set
---
> CONFIG_BINFMT_ELF=y
399,400c380
< CONFIG_HAVE_AOUT=y
< # CONFIG_BINFMT_AOUT is not set
---
> # CONFIG_HAVE_AOUT is not set
402,403c382,384
< CONFIG_COREDUMP=y
< CONFIG_HAVE_ATOMIC_IOMAP=y
---
> # CONFIG_COREDUMP is not set
> # CONFIG_IA32_EMULATION is not set
> CONFIG_X86_DEV_DMA_OPS=y
404a386
> CONFIG_HAVE_BPF_JIT=y
420a403,404
> # CONFIG_DEBUG_DRIVER is not set
> # CONFIG_DEBUG_DEVRES is not set
462a447
> # CONFIG_INTEL_MIC_CARD is not set
530c515,517
< # CONFIG_SERIAL_8250 is not set
---
> CONFIG_SERIAL_8250=y
> CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
> CONFIG_SERIAL_8250_CONSOLE=y
531a519,522
> CONFIG_SERIAL_8250_NR_UARTS=4
> CONFIG_SERIAL_8250_RUNTIME_UARTS=4
> # CONFIG_SERIAL_8250_EXTENDED is not set
> # CONFIG_SERIAL_8250_DW is not set
535a527,528
> CONFIG_SERIAL_CORE=y
> CONFIG_SERIAL_CORE_CONSOLE=y
541a535
> # CONFIG_TTY_PRINTK is not set
547,548d540
< # CONFIG_PC8736x_GPIO is not set
< # CONFIG_NSC_GPIO is not set
662d653
< CONFIG_CLKSRC_I8253=y
664d654
< CONFIG_I8253_LOCK=y
724a715
> # CONFIG_GFS2_FS is not set
765d755
< # CONFIG_TMPFS is not set
831a822
> # CONFIG_BOOT_PRINTK_DELAY is not set
835a827,828
> CONFIG_DEBUG_INFO=y
> # CONFIG_DEBUG_INFO_REDUCED is not set
839a833
> # CONFIG_READABLE_ASM is not set
845a840
> # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
847c842
< # CONFIG_DEBUG_KERNEL is not set
---
> CONFIG_DEBUG_KERNEL=y
851a847,848
> # CONFIG_DEBUG_PAGEALLOC is not set
> # CONFIG_DEBUG_OBJECTS is not set
855c852,856
< CONFIG_DEBUG_MEMORY_INIT=y
---
> # CONFIG_DEBUG_KMEMLEAK is not set
> # CONFIG_DEBUG_STACK_USAGE is not set
> # CONFIG_DEBUG_VM is not set
> # CONFIG_DEBUG_VIRTUAL is not set
> # CONFIG_DEBUG_MEMORY_INIT is not set
856a858
> # CONFIG_DEBUG_STACKOVERFLOW is not set
857a860,861
> # CONFIG_KMEMCHECK is not set
> # CONFIG_DEBUG_SHIRQ is not set
861a866,867
> # CONFIG_LOCKUP_DETECTOR is not set
> # CONFIG_DETECT_HUNG_TASK is not set
863a870,872
> CONFIG_SCHED_DEBUG=y
> # CONFIG_SCHEDSTATS is not set
> # CONFIG_TIMER_STATS is not set
868c877,890
< CONFIG_DEBUG_BUGVERBOSE=y
---
> # CONFIG_DEBUG_SPINLOCK is not set
> # CONFIG_DEBUG_MUTEXES is not set
> # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
> # CONFIG_DEBUG_LOCK_ALLOC is not set
> # CONFIG_PROVE_LOCKING is not set
> # CONFIG_LOCK_STAT is not set
> # CONFIG_DEBUG_ATOMIC_SLEEP is not set
> # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
> # CONFIG_DEBUG_KOBJECT is not set
> # CONFIG_DEBUG_WRITECOUNT is not set
> # CONFIG_DEBUG_LIST is not set
> # CONFIG_DEBUG_SG is not set
> # CONFIG_DEBUG_NOTIFIERS is not set
> # CONFIG_DEBUG_CREDENTIALS is not set
873a896,901
> # CONFIG_RCU_TORTURE_TEST is not set
> # CONFIG_RCU_TRACE is not set
> # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
> # CONFIG_NOTIFIER_ERROR_INJECTION is not set
> # CONFIG_FAULT_INJECTION is not set
> # CONFIG_LATENCYTOP is not set
874a903
> # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
883a913
> CONFIG_HAVE_FENTRY=y
890a921,923
> # CONFIG_TEST_LIST_SORT is not set
> # CONFIG_BACKTRACE_SELF_TEST is not set
> # CONFIG_RBTREE_TEST is not set
896a930
> # CONFIG_KGDB is not set
899a934,936
> # CONFIG_X86_PTDUMP is not set
> CONFIG_DEBUG_RODATA=y
> CONFIG_DEBUG_RODATA_TEST=y
900a938
> # CONFIG_DEBUG_TLBFLUSH is not set
911a950
> # CONFIG_CPA_DEBUG is not set
912a952,953
> # CONFIG_DEBUG_NMI_SELFTEST is not set
> # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
937a979
> CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
951a994
> CONFIG_ZLIB_INFLATE=y
953a997
> CONFIG_DECOMPRESS_GZIP=y
```

コンパイルします。

```
make -j4
```

コンパイル時間、Imageサイズは次の通りです。

```
real   4m51.728s
user   7m45.130s
sys    1m14.154s
$ ll -h vmlinux arch/x86/boot/bzImage 
-rw-rw-r-- 1   871K  4月 29 22:44 arch/x86/boot/bzImage
-rwxrwxr-x 1    29M  4月 29 22:44 vmlinux*
```

# busybox
rootfsを準備します。 busyboxを利用します。
ソースコードを取得します。

```
wget https://busybox.net/downloads/busybox-1.26.2.tar.bz2
tar jxvf busybox-1.26.2.tar.bz2 
```

コンパイルします。

```
TOP_BUSYBOX=~/busybox-1.26.2
cd $TOP_BUSYBOX
make defconfig
make -j4
```

rootfsを作成します。

```
make install
cd _install
mkdir proc sys dev etc etc/init.d
cat > "etc/init.d/rcS" <<- EOM
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
EOM
chmod +x etc/init.d/rcS  
mkdir -pv lib/x86_64-linux-gnu
mkdir -pv lib64
cp -av /lib/x86_64-linux-gnu/lib[mc].so.6 lib/x86_64-linux-gnu
cp -av /lib/x86_64-linux-gnu/lib[mc]-2.19.so lib/x86_64-linux-gnu
cp -av /lib/x86_64-linux-gnu/ld-2.19.so lib/x86_64-linux-gnu
cp -av /lib64/ld-linux-x86-64.so.2 lib64
find . | cpio -o --format=newc > ../rootfs.img
```

# QEMU 実行
-sオプションを指定します。gdb remote接続を待ち受けます。

> -S freeze CPU at startup (use 'c' to start execution)
> -s shorthand for -gdb tcp::1234

-s はgdbのremote接続を待ちます。
-Sを指定すると、gdbでcコマンドを入力するまでCPU起動直後に停止します。
起動時のデバッグに使えます。必要に応じて指定してください。

次のコマンドでQEMUでkernelを起動します。

```
TOP_LINUX=~/linux-3.13.0
TOP_BUSYBOX=~/busybox-1.26.2
qemu-system-x86_64 -s -nographic \
  -kernel $TOP_LINUX/arch/x86/boot/bzImage \
  -initrd $TOP_BUSYBOX/rootfs.img \
  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0"
```

別のterminalを起動します。
vmlinuxを指定してgdbを起動します。

```
gdb ./vmlinux 
```

停止中のQEMUにremote接続して処理を開始します。

```
target remote :1234
continue
```

**Ctrl-a + x**を入力して終了します。

# Remote 'g' packet reply is too long
-s -S指定でkernelを起動して、breakすると
Remote 'g' packet reply is too longというエラーが発生します。

再現手順は次の通りです。**-S**を指定します。

```bash
qemu-system-x86_64 -s -S -nographic \
  -kernel $TOP_LINUX/arch/x86/boot/bzImage \
  -initrd $TOP_BUSYBOX/rootfs.img \
  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0"
```

```bash
$ gdb vmlinux 
GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7
(snip)
(gdb) break start_kernel
Breakpoint 1 at 0xffffffff81ce3a95: file init/main.c, line 484.
(gdb) target remote :1234
Remote debugging using :1234
0x0000000000000000 in irq_stack_union ()
(gdb) c
Continuing.
Remote 'g' packet reply is too long: 000000
(snip)
```

エラーが発生します。
次のようにgdbをdisconnect / quitします。
その後、再接続することでデバッグを継続できます。

```
(gdb) disconnect
(gdb) quit
$ gdb vmlinux 
(snip)
(gdb) target remote :1234
Remote debugging using :1234
start_kernel () at init/main.c:484
484	{
(gdb) 
```

**-Sを指定しなければこのエラーは発生しません。
kernel起動時のデバッグが必要なければ-Sは指定する必要はありません。**

# SMP用のconfig
前に記載したmin_config.patchではSymmetric multiprocessing(SMP)が無効化されています。
有効にするpatchは以下です。

```:min_smp_config.patch
5,6c5,6
< # CONFIG_64BIT is not set
< CONFIG_X86_32=y
---
> CONFIG_64BIT=y
> CONFIG_X86_64=y
9,10c9,10
< CONFIG_OUTPUT_FORMAT="elf32-i386"
< CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
---
> CONFIG_OUTPUT_FORMAT="elf64-x86-64"
> CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
14a15
> CONFIG_NEED_DMA_MAP_STATE=y
17d17
< CONFIG_GENERIC_BUG=y
32,33c32,33
< # CONFIG_ZONE_DMA32 is not set
< # CONFIG_AUDIT_ARCH is not set
---
> CONFIG_ZONE_DMA32=y
> CONFIG_AUDIT_ARCH=y
36,37c36,38
< CONFIG_X86_32_LAZY_GS=y
< CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
---
> CONFIG_X86_64_SMP=y
> CONFIG_X86_HT=y
> CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
46d46
< CONFIG_BROKEN_ON_SMP=y
74a75
> CONFIG_GENERIC_PENDING_IRQ=y
79c80,81
< CONFIG_KTIME_SCALAR=y
---
> CONFIG_ARCH_CLOCKSOURCE_DATA=y
> CONFIG_GENERIC_TIME_VSYSCALL=y
81a84
> CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
89a93
> # CONFIG_NO_HZ_FULL is not set
96a101
> # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
103c108
< CONFIG_TINY_RCU=y
---
> CONFIG_TREE_RCU=y
105c110,114
< # CONFIG_RCU_STALL_COMMON is not set
---
> CONFIG_RCU_STALL_COMMON=y
> # CONFIG_RCU_USER_QS is not set
> CONFIG_RCU_FANOUT=64
> CONFIG_RCU_FANOUT_LEAF=16
> # CONFIG_RCU_FANOUT_EXACT is not set
106a116
> # CONFIG_RCU_NOCB_CPU is not set
110a121
> CONFIG_ARCH_SUPPORTS_INT128=y
112d122
< # CONFIG_CGROUPS is not set
122c132,139
< # CONFIG_BLK_DEV_INITRD is not set
---
> CONFIG_BLK_DEV_INITRD=y
> CONFIG_INITRAMFS_SOURCE=""
> CONFIG_RD_GZIP=y
> # CONFIG_RD_BZIP2 is not set
> # CONFIG_RD_LZMA is not set
> # CONFIG_RD_XZ is not set
> # CONFIG_RD_LZO is not set
> # CONFIG_RD_LZ4 is not set
126d142
< CONFIG_HAVE_UID16=y
129,130c145
< # CONFIG_EXPERT is not set
< CONFIG_UID16=y
---
> CONFIG_EXPERT=y
132c147
< CONFIG_KALLSYMS=y
---
> # CONFIG_KALLSYMS is not set
134,144c149,158
< CONFIG_BUG=y
< CONFIG_ELF_CORE=y
< CONFIG_PCSPKR_PLATFORM=y
< CONFIG_BASE_FULL=y
< CONFIG_FUTEX=y
< CONFIG_EPOLL=y
< CONFIG_SIGNALFD=y
< CONFIG_TIMERFD=y
< CONFIG_EVENTFD=y
< CONFIG_SHMEM=y
< CONFIG_AIO=y
---
> # CONFIG_BUG is not set
> # CONFIG_PCSPKR_PLATFORM is not set
> # CONFIG_BASE_FULL is not set
> # CONFIG_FUTEX is not set
> # CONFIG_EPOLL is not set
> # CONFIG_SIGNALFD is not set
> # CONFIG_TIMERFD is not set
> # CONFIG_EVENTFD is not set
> # CONFIG_SHMEM is not set
> # CONFIG_AIO is not set
151a166
> # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
156a172,173
> # CONFIG_SLOB is not set
> CONFIG_SLUB_CPU_PARTIAL=y
171d187
< CONFIG_HAVE_DMA_CONTIGUOUS=y
186d201
< CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
187a203,204
> CONFIG_HAVE_CONTEXT_TRACKING=y
> CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
191,194c208,209
< CONFIG_MODULES_USE_ELF_REL=y
< CONFIG_CLONE_BACKWARDS=y
< CONFIG_OLD_SIGSUSPEND3=y
< CONFIG_OLD_SIGACTION=y
---
> CONFIG_MODULES_USE_ELF_RELA=y
> CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
199c214
< CONFIG_HAVE_GENERIC_DMA_COHERENT=y
---
> # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
201,202c216
< CONFIG_RT_MUTEXES=y
< CONFIG_BASE_SMALL=0
---
> CONFIG_BASE_SMALL=1
205d218
< # CONFIG_LBDAF is not set
230a244
> CONFIG_MUTEX_SPIN_ON_OWNER=y
237c251,252
< # CONFIG_SMP is not set
---
> CONFIG_SMP=y
> CONFIG_X86_MPPARSE=y
239d253
< # CONFIG_X86_32_IRIS is not set
244,254d257
< # CONFIG_M486 is not set
< # CONFIG_M586 is not set
< # CONFIG_M586TSC is not set
< # CONFIG_M586MMX is not set
< CONFIG_M686=y
< # CONFIG_MPENTIUMII is not set
< # CONFIG_MPENTIUMIII is not set
< # CONFIG_MPENTIUMM is not set
< # CONFIG_MPENTIUM4 is not set
< # CONFIG_MK6 is not set
< # CONFIG_MK7 is not set
256,265c259
< # CONFIG_MCRUSOE is not set
< # CONFIG_MEFFICEON is not set
< # CONFIG_MWINCHIPC6 is not set
< # CONFIG_MWINCHIP3D is not set
< # CONFIG_MELAN is not set
< # CONFIG_MGEODEGX1 is not set
< # CONFIG_MGEODE_LX is not set
< # CONFIG_MCYRIXIII is not set
< # CONFIG_MVIAC3_2 is not set
< # CONFIG_MVIAC7 is not set
---
> # CONFIG_MPSC is not set
268,272c262,264
< # CONFIG_X86_GENERIC is not set
< CONFIG_X86_INTERNODE_CACHE_SHIFT=5
< CONFIG_X86_L1_CACHE_SHIFT=5
< # CONFIG_X86_PPRO_FENCE is not set
< CONFIG_X86_USE_PPRO_CHECKSUM=y
---
> CONFIG_GENERIC_CPU=y
> CONFIG_X86_INTERNODE_CACHE_SHIFT=6
> CONFIG_X86_L1_CACHE_SHIFT=6
276c268
< CONFIG_X86_MINIMUM_CPU_FAMILY=5
---
> CONFIG_X86_MINIMUM_CPU_FAMILY=64
277a270
> # CONFIG_PROCESSOR_SELECT is not set
281,282c274
< CONFIG_CPU_SUP_TRANSMETA_32=y
< # CONFIG_HPET_TIMER is not set
---
> CONFIG_HPET_TIMER=y
284c276,281
< CONFIG_NR_CPUS=1
---
> CONFIG_SWIOTLB=y
> CONFIG_IOMMU_HELPER=y
> # CONFIG_MAXSMP is not set
> CONFIG_NR_CPUS=8
> # CONFIG_SCHED_SMT is not set
> CONFIG_SCHED_MC=y
288c285,287
< # CONFIG_X86_UP_APIC is not set
---
> CONFIG_X86_LOCAL_APIC=y
> CONFIG_X86_IO_APIC=y
> # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
290,291d288
< CONFIG_VM86=y
< # CONFIG_TOSHIBA is not set
293d289
< # CONFIG_X86_REBOOTFIXUPS is not set
299,304c295,298
< # CONFIG_NOHIGHMEM is not set
< CONFIG_HIGHMEM4G=y
< # CONFIG_HIGHMEM64G is not set
< CONFIG_PAGE_OFFSET=0xC0000000
< CONFIG_HIGHMEM=y
< CONFIG_ARCH_FLATMEM_ENABLE=y
---
> CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
> CONFIG_ARCH_DMA_ADDR_T_64BIT=y
> CONFIG_DIRECT_GBPAGES=y
> # CONFIG_NUMA is not set
305a300
> CONFIG_ARCH_SPARSEMEM_DEFAULT=y
307c302
< CONFIG_ILLEGAL_POINTER_VALUE=0
---
> CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
309,313c304,310
< CONFIG_FLATMEM_MANUAL=y
< # CONFIG_SPARSEMEM_MANUAL is not set
< CONFIG_FLATMEM=y
< CONFIG_FLAT_NODE_MEM_MAP=y
< CONFIG_SPARSEMEM_STATIC=y
---
> CONFIG_SPARSEMEM_MANUAL=y
> CONFIG_SPARSEMEM=y
> CONFIG_HAVE_MEMORY_PRESENT=y
> CONFIG_SPARSEMEM_EXTREME=y
> CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
> CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
> CONFIG_SPARSEMEM_VMEMMAP=y
317a315
> # CONFIG_MEMORY_HOTPLUG is not set
319a318
> CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
321c320
< # CONFIG_PHYS_ADDR_T_64BIT is not set
---
> CONFIG_PHYS_ADDR_T_64BIT=y
329d327
< CONFIG_NEED_PER_CPU_KM=y
333d330
< # CONFIG_HIGHPTE is not set
336d332
< # CONFIG_MATH_EMULATION is not set
356c352
< # CONFIG_COMPAT_VDSO is not set
---
> # CONFIG_HOTPLUG_CPU is not set
378a375,379
> # Memory power savings
> #
> # CONFIG_I7300_IDLE is not set
> 
> #
384,389d384
< # CONFIG_ISA is not set
< # CONFIG_SCx200 is not set
< # CONFIG_OLPC is not set
< # CONFIG_ALIX is not set
< # CONFIG_NET5501 is not set
< # CONFIG_GEOS is not set
396c391
< # CONFIG_BINFMT_ELF is not set
---
> CONFIG_BINFMT_ELF=y
399,400c394
< CONFIG_HAVE_AOUT=y
< # CONFIG_BINFMT_AOUT is not set
---
> # CONFIG_HAVE_AOUT is not set
402,403c396,398
< CONFIG_COREDUMP=y
< CONFIG_HAVE_ATOMIC_IOMAP=y
---
> # CONFIG_COREDUMP is not set
> # CONFIG_IA32_EMULATION is not set
> CONFIG_X86_DEV_DMA_OPS=y
404a400
> CONFIG_HAVE_BPF_JIT=y
420a417,418
> # CONFIG_DEBUG_DRIVER is not set
> # CONFIG_DEBUG_DEVRES is not set
462a461
> # CONFIG_INTEL_MIC_CARD is not set
530c529,531
< # CONFIG_SERIAL_8250 is not set
---
> CONFIG_SERIAL_8250=y
> CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
> CONFIG_SERIAL_8250_CONSOLE=y
531a533,536
> CONFIG_SERIAL_8250_NR_UARTS=4
> CONFIG_SERIAL_8250_RUNTIME_UARTS=4
> # CONFIG_SERIAL_8250_EXTENDED is not set
> # CONFIG_SERIAL_8250_DW is not set
535a541,542
> CONFIG_SERIAL_CORE=y
> CONFIG_SERIAL_CORE_CONSOLE=y
541a549
> # CONFIG_TTY_PRINTK is not set
547,548d554
< # CONFIG_PC8736x_GPIO is not set
< # CONFIG_NSC_GPIO is not set
662d667
< CONFIG_CLKSRC_I8253=y
664d668
< CONFIG_I8253_LOCK=y
724a729
> # CONFIG_GFS2_FS is not set
765d769
< # CONFIG_TMPFS is not set
831a836
> # CONFIG_BOOT_PRINTK_DELAY is not set
835a841,842
> CONFIG_DEBUG_INFO=y
> # CONFIG_DEBUG_INFO_REDUCED is not set
839a847
> # CONFIG_READABLE_ASM is not set
845a854
> # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
847c856
< # CONFIG_DEBUG_KERNEL is not set
---
> CONFIG_DEBUG_KERNEL=y
851a861,862
> # CONFIG_DEBUG_PAGEALLOC is not set
> # CONFIG_DEBUG_OBJECTS is not set
855c866,871
< CONFIG_DEBUG_MEMORY_INIT=y
---
> # CONFIG_DEBUG_KMEMLEAK is not set
> # CONFIG_DEBUG_STACK_USAGE is not set
> # CONFIG_DEBUG_VM is not set
> # CONFIG_DEBUG_VIRTUAL is not set
> # CONFIG_DEBUG_MEMORY_INIT is not set
> # CONFIG_DEBUG_PER_CPU_MAPS is not set
856a873
> # CONFIG_DEBUG_STACKOVERFLOW is not set
857a875,876
> # CONFIG_KMEMCHECK is not set
> # CONFIG_DEBUG_SHIRQ is not set
861a881,882
> # CONFIG_LOCKUP_DETECTOR is not set
> # CONFIG_DETECT_HUNG_TASK is not set
863a885,887
> CONFIG_SCHED_DEBUG=y
> # CONFIG_SCHEDSTATS is not set
> # CONFIG_TIMER_STATS is not set
868c892,905
< CONFIG_DEBUG_BUGVERBOSE=y
---
> # CONFIG_DEBUG_SPINLOCK is not set
> # CONFIG_DEBUG_MUTEXES is not set
> # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
> # CONFIG_DEBUG_LOCK_ALLOC is not set
> # CONFIG_PROVE_LOCKING is not set
> # CONFIG_LOCK_STAT is not set
> # CONFIG_DEBUG_ATOMIC_SLEEP is not set
> # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
> # CONFIG_DEBUG_KOBJECT is not set
> # CONFIG_DEBUG_WRITECOUNT is not set
> # CONFIG_DEBUG_LIST is not set
> # CONFIG_DEBUG_SG is not set
> # CONFIG_DEBUG_NOTIFIERS is not set
> # CONFIG_DEBUG_CREDENTIALS is not set
873a911,918
> # CONFIG_RCU_TORTURE_TEST is not set
> CONFIG_RCU_CPU_STALL_TIMEOUT=21
> # CONFIG_RCU_CPU_STALL_INFO is not set
> # CONFIG_RCU_TRACE is not set
> # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
> # CONFIG_NOTIFIER_ERROR_INJECTION is not set
> # CONFIG_FAULT_INJECTION is not set
> # CONFIG_LATENCYTOP is not set
874a920
> # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
883a930
> CONFIG_HAVE_FENTRY=y
890a938,940
> # CONFIG_TEST_LIST_SORT is not set
> # CONFIG_BACKTRACE_SELF_TEST is not set
> # CONFIG_RBTREE_TEST is not set
896a947
> # CONFIG_KGDB is not set
899a951,953
> # CONFIG_X86_PTDUMP is not set
> CONFIG_DEBUG_RODATA=y
> CONFIG_DEBUG_RODATA_TEST=y
900a955
> # CONFIG_DEBUG_TLBFLUSH is not set
911a967
> # CONFIG_CPA_DEBUG is not set
912a969,970
> # CONFIG_DEBUG_NMI_SELFTEST is not set
> # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
937a996
> CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
951a1011
> CONFIG_ZLIB_INFLATE=y
953a1014
> CONFIG_DECOMPRESS_GZIP=y
```

次の手順で適用します。

```bash:console
make allnoconfig
patch .config min_smp_config.patch 
```

```
real	6m8.134s
user	9m47.475s
sys	1m24.813s
$ ll -h vmlinux arch/x86/boot/bzImage 
-rw-rw-r-- 1 user user 968K  5月 21 00:25 arch/x86/boot/bzImage
-rwxrwxr-x 1 user user  35M  5月 21 00:25 vmlinux*
```

-smpオプションを指定してQEMUを実行します。

```
TOP_LINUX=~/linux-3.13.0
TOP_BUSYBOX=~/busybox-1.26.2
qemu-system-x86_64 -smp 2 -s -nographic \
  -kernel $TOP_LINUX/arch/x86/boot/bzImage \
  -initrd $TOP_BUSYBOX/rootfs.img \
  -append "root=/dev/ram rdinit=/sbin/init console=ttyS0"
```

# references
- https://sourceware.org/bugzilla/show_bug.cgi?id=13984
- http://stackoverflow.com/questions/8662468/remote-g-packet-reply-is-too-long