我使用的是嵌入式内核2.6.37。 现在,我们需要使用比构建映像所使用的更新gcc更多的更新gcc来更新rootfs(而不是4.3需要使用5.1,因为它将支持我们在应用程序中需要的c ++ 11)。
升级gcc时,是否意味着我们需要更新的工具链?
新的toolhcian使用更新的内核标头(4.0.0)。
因此,在升级gcc时,是否意味着我们需要一个新内核?还是也支持旧的内核头文件?
答案 0 :(得分:1)
通常,您可以使用新的内核标头编译软件,只要该软件不使用任何新的内核功能,它仍可以在较旧的内核上运行。
但是,许多程序都包含如下结构:
#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内核标头进行构建后无条件使用renameat2
,并且在2.6.37上运行时它将失败(除非已向后移植了对renameat2
系统调用的支持) )。在较旧的内核头文件中,使用了#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
,请使用(略有缺陷的)旧版界面。通常,这些更改很简单,但是找到所有需要这些更改的地方可能很乏味。
新内核标头不适用于旧内核的另一个领域涉及低级功能,例如iptables
命令行工具用于内核的数据结构。在这些方面,用户空间ABI稳定性的保证不适用。在这些情况下,不仅是头文件的内容,您还可能需要较新版本的用户空间工具,因为内核行为已更改,而某些数据结构的布局也已更改。
(请注意,GCC和大多数当前上游GNU工具链的其余部分仍使用较旧的内核头文件进行构建。唯一的例外是glibc,当前需要内核3.2进行构建和运行。使用内核4.0头文件的要求由您的GNU工具链分发强加。)