gcc 升级是否也需要更新的内核?

Does gcc upgrade requires a newer kernel too?

我使用的嵌入式内核 2.6.37 有点旧。 现在我们需要使用比构建映像时使用的更新更多的 gcc 更新 rootfs(而不是 4.3 需要使用 5.1,因为它将支持我们在应用程序中需要的 c++11)。

升级 gcc 是否意味着我们需要更新的工具链?

新的 toolhcian 使用更新的内核头文件 (4.0.0)。

那么,升级gcc是不是意味着我们需要一个新的内核?还是它也支持旧的内核头文件?

一般来说,您可以使用新内核 header 编译软件,并且它仍然会 运行 在旧内核上,只要该软件不使用任何新内核功能。

但是,很多程序都包含这样的结构:

#ifdef __NR_renameat2
  int ret = syscall (__NR_renameat2,
                     oldfd, oldpath, newfd, newpath, RENAME_NOREPLACE);
#else
  int ret = renameat (oldfd, oldpath, newfd, newpath);
#endif

这种情况下软件会在针对4.0内核headers构建后无条件使用renameat2,在2.6.37上运行ning时会失败(除非支持因为 renameat2 系统调用已被反向移植)。对于较旧的内核 headers,使用了 #else 部分,但不再编译。

解决方案是使用这样的东西:

#ifdef __NR_renameat2
  int ret = syscall (__NR_renameat2,
                     oldfd, oldpath, newfd, newpath, RENAME_NOREPLACE);
#else
  int ret = -1;
  errno = ENOSYS;
#endif
  if (ret == -1 && errno == ENOSYS)
    ret = renameat (oldfd, oldpath, newfd, newpath);

也就是说,如果您从内核中获取 ENOSYS,请使用(略有缺陷的)旧接口。通常,此类更改很简单,但找到所有需要它们的地方可能会很乏味。

新内核 header 无法与旧内核一起工作的另一个领域涉及 low-level 功能,例如内核的 iptables 命令行工具使用的数据结构。在这些领域,用户空间 ABI 稳定性的承诺并不适用。在这些情况下,不仅仅是 header 文件的内容,您可能还需要更新版本的用户空间工具,因为内核行为已经改变,并且只是一些数据结构的布局。

(请注意,GCC 和大多数其他上游当前 GNU 工具链仍然使用旧内核 headers 构建。唯一的例外是 glibc,它当前需要内核 3.2 来构建并且 运行. 使用内核 4.0 headers 的要求是由您的 GNU 工具链分发强加的。)