Armadilloフォーラム

linux.binについて

hikita

2015年3月18日 10時08分

いつもお世話になっております。

アマノ㈱疋田です。

カーネルビルドで生成されるバイナリlinux.binについて質問させてください。

linux.binはソースからビルドするたびに生成されるバイナリが変化します。
/proc/versionを参照するとビルド日時などが参照できることから、ビルドスクリプトで動的に取得する情報がカーネルに組み込
まれているため、これは当然なのだと思います。

生成したバイナリをcmpコマンドで比較すると、動的に組み込まれる情報はビルド日時以外にもありそうなのですが、具体的にど
れだけの情報がソースファイル以外から組み込まれているかご存知であればご教授おねがいします。

また、カーネルビルドスクリプトを変更して、同一ソースから同一バイナリを生成するようにすることは可能なのか、ご存知で
あれば教えてください。

RTOSを使用した組み込み開発では開発環境を再構築した場合などは、新しい開発環境でソースファイルから前回と同一のバ
イナリを生成できるかを確認して、開発環境が正常に動作しているかを確認する機会がよくあります。
また、同一バイナリを再生成できないとなると、ファームウェアを管理していく上でいろいろな問題が発生しそうです。

以下は同一ソースから生成したバイナリ linux.bin linux1.binをstatコマンド、cmpコマンドで比較したときの出力です。

atmark@atde3:~/atmark-dist/images$ ls
linux.bin linux1.bin

atmark@atde3:~/atmark-dist/images$ stat linux.bin
File: `linux.bin'
ls Size: 3461904 Blocks: 6776 IO Block: 4096 通常ファイル
Device: fe00h/65024d Inode: 695407 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ atmark) Gid: ( 1000/ atmark)
Access: 2015-03-18 09:21:59.000000000 +0900
Modify: 2015-03-18 09:20:51.000000000 +0900
Change: 2015-03-18 09:20:51.000000000 +0900

atmark@atde3:~/atmark-dist/images$ stat linux1.bin
File: `linux1.bin'
Size: 3461904 Blocks: 6776 IO Block: 4096 通常ファイル
Device: fe00h/65024d Inode: 695405 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ atmark) Gid: ( 1000/ atmark)
Access: 2015-03-18 09:21:12.000000000 +0900
Modify: 2015-03-18 08:44:01.000000000 +0900
Change: 2015-03-18 09:15:41.000000000 +0900

atmark@atde3:~/atmark-dist/images$ cmp -l linux.bin linux1.bin
111045 46 127
111046 304 273
111076 233 71
111077 30 231
111078 231 232
111079 241 243
111135 270 63
111136 172 270
111137 375 335
111138 242 105
111139 374 371
111140 374 371
111141 22 45
111142 144 310
111143 73 166
111144 11 22
111145 3 6
111146 142 304
111147 325 252
111148 241 103
111149 3 7
111150 47 116
111151 30 60
111152 43 106
111153 44 110
111154 310 220
111155 321 243
111156 323 247
111157 307 217
111158 65 153
111159 110 220
111160 121 242
111161 121 242
111162 221 42
111163 201 3
111164 10 21
111167 204 250
111168 347 67
111169 341 175
111170 53 340
2712709 71 70
2712710 60 71
2712732 71 70
2712734 62 64
2712735 60 63
2712738 63 61
3341254 71 70
3341255 60 71
3341277 71 70
3341279 62 64
3341280 60 63
3341283 63 61

以上 よろしくお願いします

コメント

at_takashi.sasayama

2015年3月18日 15時19分

> 生成したバイナリをcmpコマンドで比較すると、動的に組み込まれる情報はビルド日時以外にもありそうなのですが、
> 具体的にどれだけの情報がソースファイル以外から組み込まれているかご存知であればご教授おねがいします。

動的に組み込まれる情報には以下が存在します。

* ユーザー名
* ホスト名
* ビルド日時
* コンパイラのバージョン
* ビルドバージョン

> また、カーネルビルドスクリプトを変更して、同一ソースから同一バイナリを生成するようにすることは可能なのか、
> ご存知であれば教えてください。

ATDE5 (同じビルドツールチェーン) でビルドする場合において、
ビルドの度に変動するのは ビルド日時 と、ビルドバージョン です。

これらはカーネルビルド時に指定ができますので、
固定とすることで、同一ソースから、同一バイナリを生成できます。

例)ビルド日時を 2015/03/18 、ビルドバージョンを 1 に固定してビルド

make KBUILD_BUILD_TIMESTAMP=2015/03/18 KBUILD_BUILD_VERSION=1

※注意点

現在の最新である atmark-dist v20150223 には make image が実行される度に、
linux.bin の末尾にチェックデータが追加され続けてしまう問題があります。

この問題に該当すると生成されるバイナリは同じでも、
追加されるチェックデータで差が発生してしまい、同一のデータになりません。

現状の回避方法としては、ビルド時に都度 make clean を実行します。

また、次回の製品アップデートにて本問題は修正される予定です。

hikita

2015年3月18日 16時37分

ご回答ありがとうございます。

同一ユーザーが同一コンソールから時間をずらして
make cleanを実行してから、
make KBUILD_BUILD_TIMESTAMP=2015/03/18 KBUILD_BUILD_VERSION=1
でカーネルビルドしてみましたが、やはり異なるバイナリが生成されます。

atmark@atde3:~/atmark-dist/images$ stat linux.bin
File: `linux.bin'
Size: 3461904 Blocks: 6776 IO Block: 4096 通常ファイル
Device: fe00h/65024d Inode: 695406 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ atmark) Gid: ( 1000/ atmark)
Access: 2015-03-18 16:25:02.000000000 +0900
Modify: 2015-03-18 16:25:02.000000000 +0900
Change: 2015-03-18 16:25:02.000000000 +0900

atmark@atde3:~/atmark-dist/images$ stat linux1.bin
File: `linux1.bin'
Size: 3461904 Blocks: 6776 IO Block: 4096 通常ファイル
Device: fe00h/65024d Inode: 695405 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ atmark) Gid: ( 1000/ atmark)
Access: 2015-03-18 16:20:34.000000000 +0900
Modify: 2015-03-18 16:20:34.000000000 +0900
Change: 2015-03-18 16:20:47.000000000 +0900

atmark@atde3:~/atmark-dist/images$ cmp -l linux.bin linux1.bin
28361 105 106
111045 225 230
111046 47 46
111077 133 131
111078 232 132
111079 242 240
111087 340 114
111088 352 141
111089 365 14
111090 123 375
111091 122 224
111092 313 324
111093 30 62
111094 30 6
111095 14 6
111096 220 3
111097 355 144
111098 64 73
111099 2 215
111100 123 300
111101 206 224
111102 26 241
111103 70 5
111104 264 16
111105 32 255
111106 30 6
111107 22 206
111108 151 104
111109 247 332
111110 51 151
111111 32 212
111112 337 306
111113 5 167
111114 331 101
111115 116 266
111116 375 123
111117 344 77
111118 374 71
111119 274 77
111120 342 257
111121 374 70
111122 234 77
111123 124 47
111124 64 25
111125 273 315
111126 215 156
111127 41 143
111128 376 210
111129 165 177
111130 66 235
111131 240 15
111132 262 250
111133 177 354
111134 315 137
111135 340 63
111136 166 270
111137 27 335
111138 345 105
111139 347 371
111140 227 371
111141 40 45
111142 333 310
111143 111 166
111144 30 22
111145 20 6
111146 253 304
111147 16 252
111148 35 103
111149 70 7
111150 301 116
111151 30 60
111152 41 106
111153 101 110
111154 216 220
111155 236 243
111156 76 247
111157 256 217
111158 101 153
111159 212 220
111160 212 242
111161 212 242
111162 14 42
111163 104 3
111164 0 21
111166 57 0
111167 346 75
111168 44 154
111169 267 212
111170 0 202
111171 2 0
111172 0 2
2805965 105 106

※linux1.binは先にビルドしたlinux.binをリネームしたものです。

タイムスタンプには時分の設定も必要なのでしょうか。
カーネルビルドの際に実行されるスクリプトを自分で調べてみます。

at_takashi.sasayama

2015年3月19日 12時55分

笹山です。

> 同一ユーザーが同一コンソールから時間をずらして
> make cleanを実行してから、
> make KBUILD_BUILD_TIMESTAMP=2015/03/18 KBUILD_BUILD_VERSION=1
> でカーネルビルドしてみましたが、やはり異なるバイナリが生成されます。

大変失礼しました。
先の回答内容ですが linux-3.4-at で確認をしていました。
atde3 でビルドされていますから linux-2.6.26-at ですね。

linux-2.6.26-at の場合は、
ビルド時に変動する要素として、
更に initramfs_data.cpio.gz が存在します。

このファイルには タイムスタンプ情報が含まれる為、
ビルド毎に毎回違うファイルになります。

linux-3.4-at では参考情報に挙げるパッチが取り込まれている為、
KBUILD_BUILD_TIMESTAMP を固定にすると initramfs_data.cpio.gz
は同じものが毎回生成されます。

参考までに linux-2.6.26-at22 用のパッチを添付します。
このパッチを適用することで、以下のコマンドで生成される linux.bin は
毎回同じものとなります。

make clean
make KBUILD_BUILD_TIMESTAMP=2015/03/19 KBUILD_BUILD_VERSION=1

パッチは以下のコマンドで適用できます。

cd linux-2.6.26-at22
patch -p0 < linux-2.6.26-at22-kbuild-initramfs-timestamp.patch

参考情報

initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/…

kbuild: Call gzip with -n
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/…

ファイル ファイルの説明
linux-2.6.26-at22-kbuild-initramfs-timestamp.patch linux-2.6.26-at22 用 ビルドタイムスタンプ パッチ

hikita

2015年3月19日 13時26分

笹山様

いつもお世話になっております。
アマノ㈱ 疋田です。

添付いただいたパッチを当てたところ、同一バイナリを生成できるようになりました。
また、貴重な情報をご教授いただき感謝いたします。

ありがとうございました。