アンドロイド・カーネル３をビルドする

# 概要
本文android kernelをbuildする手順をご紹介する。

|ソフト|バージョン|
|:-----------------|------------------:|:------------------:|
|ビルド対象kernel version|3.4|
|ビルド環境のOS|ubuntu 14.04.6|
|gcc|4.8|

###### ※注意
- OSのバージョンが重要である。
 - 同じ手順は ubuntu 12.04.5 にもbuild成功
 - 同じ手順はubuntu 18.04.4 はbuild失敗した
- kernelのバージョンが重要である
 - ４系kernelはもっと便利な手順がある（はず）


# 準備
## OS上のツールインストール
OSインストール後、以下のコマンドを実施

```bash
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install git
```

## ソース取得

```bash
mkdir core
cd core
git clone https://android.googlesource.com/kernel/msm
cd msm
git checkout -b android-msm-flo-3.4-kitkat-mr2 origin/android-msm-flo-3.4-kitkat-mr2
```

## toolchain取得
android専用のgccと関連ツールは[ここ](https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/+archive/26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a.tar.gz)からダウンロード

```bash
mkdir toolchain
cd toolchain
tar xf arm-eabi-4.8-26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a.tar.gz
```

## ソース修正
以下のソースを修正が必要

```bash
-rw-r--r-- 1 20645 Feb 14 07:16 ./drivers/usb/gadget/f_qdss.c
-rw-r--r-- 1 19059 Feb 14 07:16 ./drivers/video/msm/mipi_novatek.c
-rw-r--r-- 1 34535 Feb 14 07:16 ./net/bluetooth/hci_conn.c
```

変更箇所はdiffで示す

```diff
diff ./drivers/usb/gadget/f_qdss.c ./drivers/usb/gadget/f_qdss.c.org
586c586
< if (!strncmp(name, ch->name, sizeof(*ch->name))) {
---
> if (!strncmp(name, ch->name, sizeof(ch->name))) {
740c740
< if (!strncmp(name, ch->name, sizeof(*ch->name))) {
---
> if (!strncmp(name, ch->name, sizeof(ch->name))) {
```

```diff
diff ./drivers/video/msm/mipi_novatek.c ./drivers/video/msm/mipi_novatek.c.org
683c683
<       return snprintf((char *)buf, sizeof(*buf), "%u\n", barrier_mode);
---
>       return snprintf((char *)buf, sizeof(buf), "%u\n", barrier_mode);
```

```diff
diff ./net/bluetooth/hci_conn.c ./net/bluetooth/hci_conn.c.org
396c396
< void hci_le_ltk_reply(struct hci_conn *conn, __u8 ltk[16])
---
> void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16])
406c406
<       memcpy(cp.ltk, ltk, sizeof(*ltk));
---
>       memcpy(cp.ltk, ltk, sizeof(ltk));
```

# ビルド実施

環境変数、必要に応じて修正

```bash
export CROSS_COMPILE="/mnt/disk2/toolchain/bin/arm-eabi-"
export ARCH=arm
export PATH=$PATH:/mnt/disk2/toolchain/bin
```

ビルド設定を指定する

```bash
make flo_defconfig
```

ビルド実施

```bash
make
```

うまくいけば、以下のようになる

```bash
  ...
  GZIP    arch/arm/boot/compressed/piggy.gzip
  AS      arch/arm/boot/compressed/piggy.gzip.o
  CC      arch/arm/boot/compressed/misc.o
  CC      arch/arm/boot/compressed/decompress.o
  CC      arch/arm/boot/compressed/string.o
  SHIPPED arch/arm/boot/compressed/lib1funcs.S
  AS      arch/arm/boot/compressed/lib1funcs.o
  SHIPPED arch/arm/boot/compressed/ashldi3.S
  AS      arch/arm/boot/compressed/ashldi3.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

```

```bash
/mnt/disk2/core/msm$ ll arch/arm/boot/
total 21144
drwxr-xr-x  5      4096 Feb 15 13:37 ./
drwxr-xr-x 87      4096 Feb 14 07:16 ../
drwxr-xr-x  2      4096 Feb 14 07:16 bootp/
drwxr-xr-x  2      4096 Feb 15 13:37 compressed/
drwxr-xr-x  3      4096 Feb 14 07:16 dts/
-rw-r--r--  1        46 Feb 14 07:16 .gitignore
-rwxrwxr-x  1  15977284 Feb 15 13:37 Image*
-rw-rw-r--  1       123 Feb 15 13:37 .Image.cmd
-rw-r--r--  1      1274 Feb 14 07:16 install.sh
-rw-r--r--  1      3335 Feb 14 07:16 Makefile
-rwxrwxr-x  1   6685688 Feb 15 13:37 zImage*
-rw-rw-r--  1       150 Feb 15 13:37 .zImage.cmd
```

# エラー対応
ビルドできるまで、いろんな罠に引っ掛かりました。以下にリストする。ご参考になったら嬉しい。

make時以下のエラー発生の場合。上に記載したソース修正を参考

```bash
  CC      drivers/usb/core/hcd-pci.o
  CC      drivers/usb/core/inode.o
  LD      drivers/usb/core/usbcore.o
  LD      drivers/usb/core/built-in.o
  CC      drivers/usb/gadget/udc-core.o
  CC      drivers/usb/gadget/ci13xxx_msm.o
  CC      drivers/usb/gadget/android.o
In file included from drivers/usb/gadget/android.c:48:0:
drivers/usb/gadget/f_qdss.c: In function 'qdss_bind_config':
drivers/usb/gadget/f_qdss.c:586:38: warning: argument to 'sizeof' in 'strncmp' call is the same expression as the second source; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
error, forbidden warning: f_qdss.c:586
make[3]: *** [drivers/usb/gadget/android.o] Error 1
make[2]: *** [drivers/usb/gadget] Error 2
make[1]: *** [drivers/usb] Error 2
make: *** [drivers] Error 2
```

make時以下のエラー発生の場合。上に記載したソース修正を参考

```bash
  CC      drivers/video/msm/mipi_dsi_host.o
  LD      drivers/video/msm/msm_mipi.o
  CC      drivers/video/msm/mipi_novatek.o
drivers/video/msm/mipi_novatek.c: In function 'mipi_dsi_3d_barrier_read':
drivers/video/msm/mipi_novatek.c:683:37: warning: argument to 'sizeof' in 'snprintf' call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess]
error, forbidden warning: mipi_novatek.c:683
make[3]: *** [drivers/video/msm/mipi_novatek.o] Error 1
make[2]: *** [drivers/video/msm] Error 2
make[1]: *** [drivers/video] Error 2
make: *** [drivers] Error 2
```

make時以下のエラー発生の場合。上に記載したソース修正を参考

```bash
  LD      net/802/built-in.o
  CC      net/bluetooth/af_bluetooth.o
  CC      net/bluetooth/hci_core.o
  CC      net/bluetooth/hci_conn.o
net/bluetooth/hci_conn.c: In function 'hci_le_ltk_reply':
net/bluetooth/hci_conn.c:406:28: warning: argument to 'sizeof' in 'memcpy' call is the same pointer type '__u8 *' as the destination; expected '__u8' or an explicit length [-Wsizeof-pointer-memaccess]
error, forbidden warning: hci_conn.c:406
make[2]: *** [net/bluetooth/hci_conn.o] Error 1
make[1]: *** [net/bluetooth] Error 2
make: *** [net] Error 2
```

make時以下のエラー発生の場合。上に記載したOSのバージョンを確認ください。Ubuntu 18.04.4 はこのエラー発生し、[ここ](https://www.linuxquestions.org/questions/linux-general-1/failing-to-build-an-older-kernel-on-a-newer-system-4175644095/)はOSのバージョンを変えると薦める。私も成功した実績がない。

```bash
  CC      kernel/exit.o
  CC      kernel/itimer.o
  TIMEC   kernel/timeconst.h
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
/home/zxd/core/msm/kernel/Makefile:129: recipe for target 'kernel/timeconst.h' failed
make[1]: *** [kernel/timeconst.h] Error 255
Makefile:949: recipe for target 'kernel' failed
make: *** [kernel] Error 2
```

make時以下のエラー発生の場合。PATHにtoolchain/arm-eabi/bin があるかどうかを確認。正しいPATH設定は toolchain/bin/ である、ここではない。

```bash
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
  HOSTCC  scripts/basic/fixdep
scripts/basic/fixdep.c:106:23: fatal error: sys/types.h: No such file or directory
 #include <sys/types.h>
                       ^
compilation terminated.
make[1]: *** [scripts/basic/fixdep] Error 1
make: *** [scripts_basic] Error 2
```

git 2.10.5が必要の時 ここ( https://github.com/git/git/releases?after=v2.15.1 ) からダウンロードして、以下の要点でコンパイルする。

```bash
unzip /tmp/git-2.10.5.zip
cd git-2.10.5/
sudo apt-get install build-essential libssl-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip
make prefix=/usr/local all
sudo make prefix=/usr/local install
```


# 参考
1. 手動でカーネルをビルド（https://source.android.com/setup/build/building-kernels-deprecated）
1. ビルドのビデオ（https://www.youtube.com/watch?v=5q9Cn3ixRns）
1. ソース修正の例（https://github.com/LiquidSmooth-Devices/android_kernel_motorola_msm8960dt-common/commit/a465d392c84869a22866317a277b6dc3c3b241f2）
1. コンパイルにはUbuntu14が必要（https://www.linuxquestions.org/questions/linux-general-1/failing-to-build-an-older-kernel-on-a-newer-system-4175644095/）
1. エラー対策議論（http://xdabloger.blogspot.com/2016/07/commit-aosp-justarchis-archidroid_49.html#）
1. エラー対策議論（https://forum.xda-developers.com/showthread.php?t=2581659&page=12）
1. 事前コンパイル済みのツール群（https://android.googlesource.com/platform/prebuilts/）
1. AndroidカーネルはLinuxカーネル（https://source.android.com/devices/architecture/kernel）
1. Androidカーネル構成（https://source.android.com/devices/architecture/kernel/android-common）
1. Linuxカーネル（https://www.kernel.org/category/releases.html）
1. NDK必要ないけど（https://developer.android.com/ndk/guides?hl=ja）