カーネル再構築 2.6→4.3

## カーネル再構築 2.6→4.3
centos6.7のカーネルバージョンを2.6から4.3にアップしてみた。

### カーネルプログラムの分類
大きく２つに分けられる

* カーネル本体
* カーネルモジュール

#### 上の２つはどこに置いてあるの？？
##### カーネル本体
* /boot 
  - vmlinuz-2.6.32-573.el6.x86_64
  - ↑圧縮されてる

~~~txt
$ ls -ls
total 34310
  106 -rw-r--r--. 1 root root   107134 Jul 23 09:13 config-2.6.32-573.el6.x86_64
    2 drwxr-xr-x. 3 root root     1024 Nov 20 18:48 efi
    2 drwxr-xr-x. 2 root root     1024 Nov 20 19:50 grub
27335 -rw-------. 1 root root 27989384 Nov 20 18:55 initramfs-2.6.32-573.el6.x86_64.img
   13 drwx------. 2 root root    12288 Nov 20 18:38 lost+found
  203 -rw-r--r--. 1 root root   205998 Jul 23 09:14 symvers-2.6.32-573.el6.x86_64.gz
 2526 -rw-r--r--. 1 root root  2585052 Jul 23 09:13 System.map-2.6.32-573.el6.x86_64
 4123 -rwxr-xr-x. 1 root root  4220560 Jul 23 09:13 vmlinuz-2.6.32-573.el6.x86_64
~~~

#### カーネルモジュール
* /lib/modules/カーネルバージョン/kernel

~~~txt 
 $ pwd
/lib/modules/2.6.32-573.el6.x86_64/kernel
$ ls -ls
total 36
4 drwxr-xr-x.  3 root root 4096 Nov 20 18:45 arch
4 drwxr-xr-x.  3 root root 4096 Nov 20 18:45 crypto
4 drwxr-xr-x. 63 root root 4096 Nov 20 18:45 drivers
4 drwxr-xr-x. 30 root root 4096 Nov 20 18:45 fs
4 drwxr-xr-x.  3 root root 4096 Nov 20 18:45 kernel
4 drwxr-xr-x.  6 root root 4096 Nov 20 18:45 lib
4 drwxr-xr-x.  2 root root 4096 Nov 20 18:45 mm
4 drwxr-xr-x. 28 root root 4096 Nov 20 18:45 net
4 drwxr-xr-x.  9 root root 4096 Nov 20 18:45 sound
~~~

### 4.3にあげてみた
#### やった場所
~

#### カーネル設定の引き継ぎ
現在のカーネル設定を反映させる。その上で新しい設定を反映させる。そうしないと今までのやつが動かなくなる？？

~~~txt
cp config-2.6.32-573.el6.x86_64　.config
~~~

#### 最新の設定だけを反映
oldconfigを使用すると最新の設定だけをyse/noで聞かれる。
最新の設定はenter押してデフォルト設定にする。

~~~txt
make oldconfig
~~~

#### ビルド
~~~txt
make 
~~~

#### 怒られる
openssl.hがないみたいなメッセージ発生して途中で終わる。
openssl-develがないみたいだ。

#### そもそもxxx-develってなに？？
* develはdevelopmentの略
* 開発の際(ビルド)の時に必要になるもの。ヘッダファイルとかはいっている。
* CentOSなどではコンパイルに必要なファイルをまとめたパッケージには後ろに-develという名前が付くようになっている。ライブラリそのものはヘッダファイルがなくても動作するため、パッケージが分割された状態になっていることがほとんどらしい。


```sh
$ rpm -qi  openssl-devel

Description :
OpenSSL is a toolkit for supporting cryptography. The openssl-devel
package contains include files needed to develop applications which
support various cryptographic algorithms and protocols.
```
↑説明通り。

```bash
$ rpm -ql  openssl-devel
/usr/include/openssl
/usr/include/openssl/aes.h
/usr/include/openssl/asn1.h
/usr/include/openssl/asn1_mac.h
/usr/include/openssl/asn1t.h
/usr/include/openssl/bio.h
/usr/include/openssl/blowfish.h
/usr/include/openssl/bn.h
/usr/include/openssl/buffer.h
/usr/include/openssl/camellia.h
/usr/include/openssl/cast.h
/usr/include/openssl/cmac.h
/usr/include/openssl/cms.h
/usr/include/openssl/comp.h
/usr/include/openssl/conf.h
/usr/include/openssl/conf_api.h
/usr/include/openssl/crypto.h
/usr/include/openssl/des.h
/usr/include/openssl/des_old.h
/usr/include/openssl/dh.h
/usr/include/openssl/dsa.h
/usr/include/openssl/dso.h
・
・
```
↑やはりヘッダファイルあり。

## なんでヘッダファイルがないとビルドできないのか？
今回のビルドエラーはヘッダファイルをinclude指定しているがそのヘッダがないのでエラー。

## ヘッダファイルを利用しない
* あるファイルの関数から別ファイルの関数を呼び出す場合、その呼び出す関数の引数、戻り値を知っていないといけない。それを知るために、呼び出し側ではその関数の宣言を利用する。
* 利用側で宣言を知ることができない場合、暗黙の宣言が利用される。
* 宣言が定義と合致しているかはちぇっくなし。
* 別ファイルの関数などを使う場合に都度、自分で宣言を書かないといけない

## 暗黙の宣言
* 呼び出し側で例えば関数の情報(宣言)を知ることができない場合int型を返す、引数なしの関数としてみなされる。
* 自分で宣言を書いて定義と異なっていたとしても同じ
* コンパイラの気持ちとしては別ファイルにあるはずなので`リンク時`にみつかるやろ～

## エラー
* 発覚するのはリンク時。`コンパイル時`にエラー見つけたい。

## ヘッダファイルを利用
* 宣言を一つにまとめられる。再利用できる。
* ヘッダファイルに、関数、変数の宣言かく。`コンパイル時`に例えば関数の呼び出し側、定義側、とヘッダファイルにかかれている宣言が正しい(引数、戻り値の型)などをチェックしてくれる。`コンパイル時`にみつかる。

 

#### 色々試してみた

##### 別ファイルに関数ある場合
main

~~~C
#include <stdio.h>

int main()
{
  printf("answer=%f\n", add(3.0, 4.0) );
  return 0;
}
~~~

↓別ファイル

~~~c
double add(double a, double b)
{
  return a+b;
}
~~~
mainでadd()の宣言していないのでコンパイラは勝手にint addで暗黙宣言して思い込む。よって-Wallつきでコンパイルすると

~~~txt
gcc test.c test2.c -c -Wall
test.c: In function ‘main’:
test.c:5: warning: implicit declaration of function ‘add’
~~~

その様な警告でる。ただ-Wallをつけているから警告でるだけなのでコンパイルは通るし、リンクもされる。実行もされる。

##### 同じファイルに関数ある場合

~~~c
#include <stdio.h>

int main()
{
  printf("answer=%f\n", add(3.0, 4.0) );
  return 0;
}

double add(double a, double b)
{
  return a+b;
}
~~~

- 同じファイルにあると警告でなくエラーがでてコンパイルに失敗する↓

~~~txt
gcc test3.c 
test3.c:9: error: conflicting types for ‘add’
test3.c:5: note: previous implicit declaration of ‘add’ was here
~~~

- 同じファイルにあるとコンパイラが使用するのは下のaddと確定させるから??
- 別ファイルにある関数を使用する場合、暗黙の宣言した関数の情報と実際の使用する関数の情報が異なっていてもエラーにならずに(-Wallをつけるとduplicateの警告でるが)リンクまで正常にできた

#### 結果
- この結果からヘッダ(宣言)なくてもリンクまで行ける。自分が使い方させ間違えなければOK。ただし、間違えた場合、リンク時エラー、最悪、実行時にエラーすると思われる。
- だからきっと-Wallをつけて警告は全て排除する必要あり(コンパイラが宣言をチェックしてくれて頑張ってるから)。そのためにも宣言必要。ヘッダファイルで使用する関数を宣言して定義と使用箇所をコンパイル時にチェック。再利用可能。
- ヘッダファイル(宣言)はコンパイラにコンパイル時点で間違いを気づかせてもらうためにあるはず。


## カーネル再構築の続き

* モジュールをシステムにインストール

~~~txt
make modules_install
~~~

* カーネル本体をインストール？

~~~txt
make install 
~~~

* インストール完了
  - grubには自動で新カーネルが追加で設定される。再起動後↓

~~~txt
uname -r
4.3.0
~~~

### 感想
再構築は本を見てやりかたしっていたけど、やっぱり実際に手を動かしてみると色々試行錯誤が生まれて勉強になる。実際に試してみることが大切だと実感させられました。