Ubuntu 16.10 Intel e1000e 驱动程序无法编译。错误:“struct net_device”没有名为“trans_start”的成员

Ubuntu 16.10 Intel e1000e 驱动程序无法编译。错误:“struct net_device”没有名为“trans_start”的成员

英特尔千兆以太网控制器的内置 e1000e 驱动程序在 Ubuntu 中不起作用,这是一个已知问题,有一个已知解决方案:从英特尔网站下载驱动程序,编译它,然后按照通常的内核模块安装说明安装内核模块。

我从https://downloadcenter.intel.com/download/15817/Intel-Network-Adapter-Driver-for-PCI-E-Gigabit-Network-Connections-under-Linux-?product=70831

解压后,运行时出现此错误make

cc1: error: code model kernel does not support PIC mode /bin/sh: 1: [:
-ge: unexpected operator
Makefile:181: *** *** Aborting the build. *** This driver is not supported on kernel versions older than 2.4.0.  Stop.

根据sourceforge 上的某个人,我应该gcc从 Ubuntu 的存储库 ( sudo apt remove gcc) 中删除,然后从其源重新安装。当然,这是不可能的,因为这也会卸载bbswitch-dkms build-essential dkms g++ gcc libcuda1-367 nvidia-367 nvidia-opencl-icd-367 nvidia-prime

我找到了一个链接关于 PIE 的此页面,但它不包含用于启用或禁用 PIE 的简单复制粘贴指令,或者编译此网络驱动程序模块需要执行的任何操作。

在 Unix Stack Exchange 上,我发现了一个可能相关也可能不相关的问题,并且它也没有包含关于如何修补需要修补的内容的明确说明:https://unix.stackexchange.com/questions/320470/apply-kernel-patch-to-support-pic-mode

我的uname -a

Linux kerbol 4.8.0-27-generic #29-Ubuntu SMP Thu Oct 20 21:03:13 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

更新日期 2016-12-02

有人建议我安装 gcc-4.8,rm gcc然后/usr/bin创建一个新的符号链接。虽然我很固执,但我还是这样做了(我认为这是推荐的“Ubuntu 方式”):

sudo apt install gcc-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives --config gcc

当我make再次运行时,我又遇到了一个错误。进步了!

make -C /lib/modules/4.8.0-27-generic/build SUBDIRS=/home/amedee/e1000e-3.3.4/src modules
make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-generic'
  CC [M]  /home/amedee/e1000e-3.3.4/src/netdev.o
gcc: error: unrecognized command line option ‘-fstack-protector-strong’
scripts/Makefile.build:289: recipe for target '/home/amedee/e1000e-3.3.4/src/netdev.o' failed
make[2]: *** [/home/amedee/e1000e-3.3.4/src/netdev.o] Error 1
Makefile:1489: recipe for target '_module_/home/amedee/e1000e-3.3.4/src' failed
make[1]: *** [_module_/home/amedee/e1000e-3.3.4/src] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.8.0-27-generic'
Makefile:247: recipe for target 'default' failed
make: *** [default] Error 2

如果你在 Google 上搜索“gcc: 错误: 无法识别的命令行选项‘-fstack-protector-strong’”,那么你会发现你不需要gcc-4.8但是gcc-4.9。所以我这样做了:

sudo apt install gcc-4.9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
sudo update-alternatives --config gcc

当我make再次运行时,又出现另一个错误:

make -C /lib/modules/4.8.0-27-generic/build SUBDIRS=/home/amedee/e1000e-3.3.4/src modules
make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-generic'
  CC [M]  /home/amedee/e1000e-3.3.4/src/netdev.o
In file included from ./include/linux/kernel.h:13:0,
                 from ./include/linux/list.h:8,
                 from ./include/linux/module.h:9,
                 from /home/amedee/e1000e-3.3.4/src/netdev.c:24:
/home/amedee/e1000e-3.3.4/src/netdev.c: In function ‘e1000e_dump’:
/home/amedee/e1000e-3.3.4/src/netdev.c:250:25: error: ‘struct net_device’ has no member named ‘trans_start’
    netdev->state, netdev->trans_start, netdev->last_rx);
                         ^
./include/linux/printk.h:283:34: note: in definition of macro ‘pr_info’
  printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
                                  ^
/home/amedee/e1000e-3.3.4/src/netdev.c: In function ‘e1000_xmit_frame’:
/home/amedee/e1000e-3.3.4/src/netdev.c:6545:8: error: ‘struct net_device’ has no member named ‘trans_start’
  netdev->trans_start = jiffies;
        ^
scripts/Makefile.build:289: recipe for target '/home/amedee/e1000e-3.3.4/src/netdev.o' failed
make[2]: *** [/home/amedee/e1000e-3.3.4/src/netdev.o] Error 1
Makefile:1489: recipe for target '_module_/home/amedee/e1000e-3.3.4/src' failed
make[1]: *** [_module_/home/amedee/e1000e-3.3.4/src] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.8.0-27-generic'
Makefile:247: recipe for target 'default' failed
make: *** [default] Error 2

现在事情变得有趣了,因为我觉得我发现从 4.7 内核开始有些变化。谷歌搜索error: ‘struct net_device’ has no member named ‘trans_start’告诉我必须更改行6545

-netdev->trans_start = jiffies;
+netif_trans_update(netdev);

确实,这消除了第 6545 行的错误。但第 249-250 行仍然有错误。这是当前代码:

pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
  netdev->state, netdev->trans_start, netdev->last_rx);

我知道我需要用netdev->trans_start其他东西替换,但我不知道该替换什么。用作netif_trans_update(netdev)第 4 个参数pr_info不起作用,因为这会给我

/home/amedee/e1000e-3.3.4/src/netdev.c: In function ‘e1000e_dump’:
/home/amedee/e1000e-3.3.4/src/netdev.c:249:3: error: invalid use of void expression
   pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
   ^

那么我需要在那里放什么呢?

显然 pr_info用于日志记录目的,所以我想,如果我把第 249-250 行放在注释中会怎么样?结果是驱动程序终于构建好了(耶!)但是如果你不知道代码的作用,注释掉它感觉不对. 特别是内核驱动代码。

即使驱动程序编译通过,我仍然无法上网

sudo rmmod e1000e
sudo modprobe e1000e

更新:双启动系统的解决方案是启动 Windows,进入网卡驱动程序设置,禁用与电源管理相关的所有内容。然后启动 Linux,重新启动 Linux(是的,两次!)并使用内核提供的默认驱动程序。

答案1

谷歌搜索 netif_trans_update 给出以下代码:

/* legacy drivers only, netdev_start_xmit() sets txq->trans_start */
 static inline void netif_trans_update(struct net_device *dev)
 {
         struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);

        if (txq->trans_start != jiffies)
                 txq->trans_start = jiffies;
 }

这表明,在 pr_info 中重新获取 trans_start 的一个好方法是替换

netdev->trans_start

netdev_get_tx_queue(netdev,0)->trans_start.

但是你是对的,这是一个日志功能,修复它可能无法修复你的驱动程序。

答案2

sudo apt install gcc-4.9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
sudo update-alternatives --config gcc

搭配e1000e-3.3.5.3.tar.gz

tar -xzvf e1000e-3.3.5.3.tar.gz
cd e1000e-3.3.5.3/src
sudo make install
sudo rmmod e1000e;sudo modprobe e1000e

在带有内核的 Ubuntu 16.10 上完美构建和安装,无需任何修改4.8.0-37-generic

不要忘记将 e1000e 添加到 /etc/modules 以使其永久生效:

sudo echo e1000e>>/etc/modules

答案3

根据您的主板,当使用名为 e1000e-3.3.5.3 源时,您可能需要在使用内核版本 4.4.* 或 4.8.* 时修改 netdev.c 源代码,通过删除 NVM CRC 校验功能。

相关内容