Ubuntu 18.04 で通信が使えない問題の対応

新しく購入した作業用 PC に Ubuntu 18.04 LTS をインストールしたところ、通信が使えなくて非常に苦労しました。

どうにか通信ができるようになるところまで持っていけたので、備忘録として行ったことを残しておきます。

この記事で書いているのは、有線 LAN での接続ができない問題の対応となります。

一応、わたしはこの手順で通信できるようになっていて何も問題は発生していませんが、ドライバのソースをいじったりするので自己責任でお願いしますね。

環境

  • OS: Ubuntu 18.04
  • Kernel: 4.15.0-22-generic

症状

通信が一切できない。

  • 有線 LAN で接続
  • LAN の差し込み口のランプは点灯している(ハード的には接続できている)状態
  • ドライバのロードに失敗している模様。dmesg でNIC のドライバのロードに失敗したかのようなメッセージが確認できる
    $ dmesg | grep e1000e
    ...
    e1000e .... The NVM checksum is Not Valid

対処

チェックサムのチェック処理を無効化したドライバをビルドし、インストールする。

上記の通り、チェックサムの不一致でエラーとして弾かれてNIC のドライバがロードできないようでした。

調べてみると、これは Ubuntu 含め Linux では割とよくあることのようで、他の記事でもチェックサムを無効化したドライバのコンパイル、インストールの方法などが記載されています。

ただ、Ubuntu 18.04 になって Linux Kernel が 4.15 に上がったことで 2018年6月3日現在の最新のドライバのコードそのままだとビルド時にエラーが出ます。

以下に、私が行った手順を具体的に記載しておきます。

手順

  1. 一時的に通信が使える環境を準備
  2. ドライバのソースのダウンロード
  3. make、gcc 4.9 のインストール
  4. ドライバソースにパッチを適用
  5. チェックサムのチェック処理を無効化
  6. ドライバのインストール

1. 一時的に通信が使える環境を準備

上記の通り、これからドライバのソースを少しいじってからビルドするという手順を行うわけですが、通信が使えない状態だとソースコードやコンパイラをダウンロードするといったことさえできません。

というわけで、まずは代替の通信手段を確保します。

ドライバがロードできる Wi-Fi アダプタがあればそれを使うこともできますが、オススメは スマホの USBテザリング です。

スマホと PC を USBで接続し、スマホの設定で USB テザリングを有効にするだけで使えます。これ超便利。

わたしの Android 端末では、「設定」→「無線とネットワーク」→「テザリングとポータブルアクセス…」→「USBテザリング」で設定できました。USBテザリングの機能を持つ端末であれば同じような場所で設定できるかと思います。

2. ドライバのソースのダウンロード

通信が使えるようになったところで、ドライバのソースをダウンロードします。

Intel のドライバのページ からダウンロードしてきます。

わたしがダウンロードしたのは執筆時点で最新の 3.4.0.2 になります。

ダウンロードしたらファイルを適当な場所で解凍しておきます。

3. make、gcc 4.9 のインストール

すでに make が入っていれば問題ありませんが、make コマンドが使えない状態であれば make をインストールします。

次に、コンパイルするために gcc をインストールするのですが、ここでは gcc 4.9 を使います。

gcc 5 以上でビルドすると、下記のようなエラーが出てしまいます。

Ubuntu 18.04 で sudo apt-get install gcc でインストールされるのは gcc 7.3.0 だったので、わたしも最初このエラーに悩まされました。

エラーの内容をそのまま解釈すると、Kernel のバージョンが低すぎるということになるのですが、Ubuntu 18.04 で使っている Linux Kernel は 4.15 です。

どうも gcc 5 以上でビルドすると Kernel のバージョンが正しく取得できずにこのエラーが出てしまうそうです。

というわけで、gcc 5 より下のバージョンをインストールするのですが、Makefile で 4.9 から採用されているオプションを使っているので、ここではピンポイントで gcc-4.9 をインストールしてきます。

方法は こちらの投稿 に記載がありました。

  1. /etc/apt/sources.list に下記 2行を追記

  1. g++-4.9 を指定してインストール

これで gcc 4.9 はインストールされた状態になりますが、この状態ではまだ gcc コマンドでは標準でインストールした gcc 7.3.0 が使われている状態ですので、

update-alternatives を使って、gcc 4.9 を gcc コマンドとして使える状態にします。

とりあえずこれでコンパイラの方の準備は OK です。

試しにビルドしてみましょう。

はい、コンパイルエラーになりました。次の手順に進みます。

4. ドライバソースにパッチを適用

先程のコンパイルエラーですが、調べてみると Linux Kernel が 4.14 から 4.15 に上がったときのタイマ関連の API 変更によるもののようです。

つまり、このドライバのソースはまだ Linux Kernel の 4.15 に対応してなかったみたいでした。

ありがたいことにこの変更に追随したパッチを作成された方がいましたので、そのパッチを適用します。

パッチは こちら の投稿のコメントに添付されています。

ダウンロードした patch ファイルを下記のように e1000e-3.4.0.2 と同じディレクトリに配置し、patch コマンドで適用します。

一旦 e1000e-3.4.0.2/src で make を行い、ビルドができることを確認しておきます。

5. チェックサムのチェック処理を無効化

やっとこさ本題の、チェックサムの無効化処理を適用できます。

e1000e-3.4.0.2/src/nvm.c を gedit などで開き、e1000e_validate_nvm_checksum_generic 関数を return 0; 以外コメントアウトします。

6. ドライバのインストール

最後に、ドライバをビルドし、適用します。

下記手順でコマンドを実行し、一旦現在のドライバを無効化、今ビルドしたドライバを使うようにしてみます。

USB テザリングを外し、通信ができるか確認してみましょう!

これで通信できるようになっていれば、次回起動時に今ビルドしたドライバ使われるよう、下記コマンドを実行します。

これで完了です!

さいごに

Ubuntu 18.04 がリリースされてから1ヶ月ちょっとなので、少しイキりすぎましたね。

だいぶ情報がなくて苦労しました。

個人的には Ubuntu でも USB テザリングがすごく簡単にできるということが一番発見だったかもしれない。


最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。



この記事をシェアする




りゅーた
フリーランスのエンジニアしてます。Android、iOS アプリの開発、対向サーバの開発、C/C++のライブラリ開発が現在のメイン。趣味はテニス。3児の父。 もっと詳しく

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA