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 工具链分发强加的。)
我使用的嵌入式内核 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 工具链分发强加的。)