指定 GCC 输出二进制文件的预期 Linux 版本

Specify the expected Linux version of the output binary of GCC

我正在帮助其他人做 "operating systems concepts" 课程的实验。实验任务是在QEMU中编译Linux2.6.26和运行

编译完Linux内核后,我们被告知要写一个最小的程序作为init程序。我们展示的(我们遵循的)示例是:

#include <stdio.h>

int main() {
    while (1) {
        puts("Hello!");
        sleep(2);
    }
}

编译命令为:

root@ubuntu:/home/vmware/oslab# gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@ubuntu:/home/vmware/oslab# gcc -static -o init hello.c

主机环境应该是全新安装的 Ubuntu 14.04.6 (i386)。


问题是,我的一位同学仔细按照说明操作,init程序执行失败。我向他询问了他的整个 initrd.img,并注意到他的 init 程序看起来有何不同:

vmware@ubuntu:~/oslab$ file mnt/init
mnt/init: ELF 32-bit LSB  executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=7365ac494ef1d924c171899c169dbd3195d2d209, not stripped

对我来说,这显然不是 运行 在 Linux 2.6.26 上可以做到的。使用 Ubuntu APT 存储库(可信)中提供的 GCC 4.8,我如何让 GCC 在 Linux 2.6.26 上输出 运行s 的内容?

仅供参考:在我自己的测试 VM 上(也是 Ubuntu 14.04.6、Linux 4.4,截至 2019 年 4 月 2 日来自 Ubuntu APT 存储库的最新 GCC 版本),编译后的程序在 file 输出中显示 Linux 2.6.24 。此外,his 二进制 运行 在 QEMU 中与我新编译的 2.6.32.37 内核完美结合。

Specify the expected Linux version of the output binary of GCC

在您的问题中,您谈到了 libc C 的版本,但这也可能涉及许多其他库,并且您可能还想生成 32b and/or 64b 可执行文件。

对我来说最安全的方法是使用 pbuilder,我用它来生成 BoUML debs for Ubuntu Cosmic (18.10) Bionic (18.04), Artful (17.10) Zesty (17.04) Yakkety (16.10) Xenial (16.04) Trusty (14.04) and Precise (12.04) 以及 32b 和 64b 中的所有内容,我都做了来自我的 Ubuntu Xenial 64b 只是执行适当的 pbuilder 命令序列(没有任何重启进入每个 Linux 版本)

这需要时间来生成一个版本,但是因为这是在相应的 Linux 版本中制作的,所以您可以确定结果。

提供的实验室环境是 Ubuntu 14.04,其中包 libc6 的版本是 2.19-0ubuntu6.14.

助教助教提供的实验说明中包含手动编辑/etc/apt/sources.list更改APT源的说明,其中有严重的灾难:"version" 字符串在编辑的示例中是 xenial 而不是 trusty,如果遵循它,将 factually 将您的系统更新到 Xenial (Ubuntu 16.04)。 libc6 的新版本是 2.23-0ubuntu11,这将导致 asld(来自 binutils,与 GCC 无关)输出带有最低 Linux 版本 2.6.32.

对于 glibc 2.19 版本,输出 ELF 与 Linux 2.6.24 兼容,但对于 glibc 2.23,输出仅与 Linux 2.6.32 兼容。

我通过在Ubuntu14.04下编译了一个测试程序并查看了ELF信息进行了测试验证,然后将所有trusty替换为xenial,做了apt-get update更新了binutils及其依赖(包括libc6),编译程序并再次检查