我在 chroot 的 Debianarmel
环境中看到了一些非常奇怪的东西。
但首先,有一些背景故事......这很长,但问题很复杂,任何潜在的帮助都取决于了解完整的故事。
我有一个运行 Linux 的嵌入式 ARM SoC - 更具体地说,是运行armel
2.6.17 内核的 Debian Lenny。 Debian 发行版本身可以轻松升级到更高版本 ( sudo apt-get dist-upgrade
),因此可以加快速度,升级到armel
的版本
squeeze
,甚至wheezy
.
问题在于该内核是自定义内核...所讨论的 ARM SoC 不是主线内核的一部分,因此它在 2.6.17 中几乎被放弃了。
如果您知道 Linux 和 GLIBC 是如何工作的,您就已经可以看到问题了 - GLIBC 版本是使用支持的最低内核版本编译的……该版本已经远远超出了 2.6.17。因此,如果我们尝试 chroot 到 Debian 系统……
$ # From inside the little ARM machine running Debian Lenny
$ sudo debootstrap --arch armel squeeze /squeeze \
http://ftp.whateverCountry.debian.org/debian
$ sudo -i
# mount -t proc none /squeeze/proc
# mount -t sysfs none /squeeze/sys
# mount -t devpts none /squeeze/dev/pts
# chroot /squeeze
Fatal: Kernel too old
...我们看到一条来自 GLIBC 的消息squeeze
,告诉我们它未编译为可与旧内核 (2.6.17) 一起使用。
同样的问题也发生在 wheezy 上——因为它比挤压更新——而且实际上从现在开始任何 Debian 版本都会发生这种情况,因为它们的 GLIBC 无法在我的 2.6.17 内核上工作。
起初我认为这会破坏交易 - 但后来我意识到我可以理论上重新编译 GLIBC 以与我的 SoC 使用的旧内核一起工作...但是我需要一个与在例如 Debian squeeze 中构建 libc6 软件包所使用的环境相同的环境。
我猜测 GLIBC 的编译和 libc6_2.11.3-4.deb 文件的准备是通过 Debian 之神发明的自动交叉编译机器完成的。
我不是上帝...我也无法在 Google 中找到任何有关如何成为上帝的信息 - 即如何使用我的 Core i5 作为主机,使用与打包版本(在 Debian 内squeeze
)完全相同的设置来交叉编译 GLIBC使用。
所以我欺骗了它 - 我弄清楚了如何在我的 Core i5 上设置 ARM 版本的 Debian squeeze(一种使用静态版本二进制文件的技术qemu-arm
)。
一旦我 chroot 到我的 x86 托管版本中Debian-armel-squeeze
,我就能够简单地...
$ cd /var/tmp
$ apt-get source libc6
...
$ # edit this in - compile for my kernel...
$ vi eglibc-2.11.3/debian/sysdeps/linux.mk
...
MIN_KERNEL_SUPPORTED := 2.6.17
...
$ export DEB_BUILD_OPTS="nocheck parallel=1"
$ cd eglibc-2.11.3
$ dpkg-buildpackage -b -d -us -uc
...3 小时后(Core i5 托管的 chroot 版本
Debian-armel-squeeze
比本机机器慢得多...)我得到了我的 libc6 .deb 包。在我的 SoC 中完成此构建可能需要 3 个月的时间,所以我没有抱怨。
回到我的真实 ARM SoC 内部,我将新包的所有 libc 文件 (.so) 复制到 squeeze 的默认文件上,并尝试 chroot...
# chroot squeeze/
root@ttsiodras:/#
是的!有效! (或者看起来是这样)
我的自定义 libc 从 chroot 内部报告:
# /lib/libc.so.6
GNU C Library (Debian EGLIBC 2.11.3-4) stable release version 2.11.3, by Roland McGrath et al.
Copyright (C) 2009 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.
Compiled by GNU CC version 4.4.5.
Compiled on a Linux 2.6.26 system on 2014-10-23.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
Support for some architectures added on, not maintained in glibc core.
BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
事情似乎顺利 - 我复制了一个文件,调用了ls
......
但是当我尝试使用apt-get
从安装一些应用程序时squeeze
,我开始遇到......一些意外的错误:
# apt-get install indent
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
indent
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 110 kB of archives.
After this operation, 516 kB of additional disk space will be used.
Get:1 http://ftp.gr.debian.org/debian/ squeeze/main indent armel 2.2.11-1 [110 kB]
Fetched 110 kB in 0s (236 kB/s)
tar: ./control: Cannot utime: Function not implemented
tar: ./md5sums: Cannot utime: Function not implemented
tar: .: Cannot utime: Function not implemented
tar: Exiting with failure status due to previous errors
dpkg-deb: subprocess tar returned error exit status 2
dpkg: error processing /var/cache/apt/archives/indent_2.2.11-1_armel.deb (--unpack):
subprocess dpkg-deb --control returned error exit status 2
configured to not write apport reports
rm: cannot remove `/var/lib/dpkg/tmp.ci': Function not implemented
dpkg: error while cleaning up:
subprocess rm cleanup returned error exit status 1
Errors were encountered while processing:
/var/cache/apt/archives/indent_2.2.11-1_armel.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
噢噢……一堆Function not implemented
。这听起来就像 GLIBC 报告说基本的东西不起作用......
我设法进行 strace(不要问如何进行)并发现所有-at
功能都失败了:openat
、mkdirat
、renameat
等 - 它们都报告 ENOSYS。
看起来我只取得了部分成功——一些系统调用在我的新 GLIBC 中失败了。
难道在2.6.17下不能编译asqueeze
或者GLIBC来执行吗?wheeze
任何关于我做错了什么和/或如何继续的想法/指示将不胜感激......
答案1
我做到了 :-)
我基本上遵循了 Gilles 的建议并决定正确地执行:即管理 GLIBC 的完整交叉编译。我从 crosstool-ng 开始,最初很失望 - 发现它不支持我的旧内核。不过,我还是坚持了下来 - 手动编辑 crosstool-ng 保存的配置文件,对默认的 arm-gnueabi 构建配置进行如下更改:
$ ct-ng arm-unknown-linux-gnueabi
$ ct-ng menuconfig
...
$ vi .config
$ cat .config
...
CT_KERNEL_VERSION="2.6.17"
CT_KERNEL_V_2_6_17=y
CT_LIBC_VERSION="2.13"
CT_LIBC_GLIBC_V_2_13=y
CT_LIBC_GLIBC_MIN_KERNEL_VERSION="2.6.9"
CT_LIBC_GLIBC_MIN_KERNEL="2.6.9
...
$ ct-ng +libc
经过多次测试和失败的尝试后,上述更改做到了 - 我得到了可以与我的内核一起使用的 GLIBC 编译版本,并将生成的文件复制到我的 Debian Lenny ARM 机器上:
$ cd .build/arm-unknown-linux-gnueabi/build/build-libc-final/
$ tar zcpf newlibc.tgz $(find . -type f -iname \*.so)
$ scp newlibc.tgz root@mybook:.
我一路走来,超越了挤压:我debootstrapped /wheezy,然后 - 非常小心 - 用/wheezy
我自己的版本覆盖了armel-debootstrapped的GLIBC版本:
# # In the ARM machine
# cd /wheezy/lib/arm-linux-gnueabi/
# mv /var/tmp/ohMyGod/libc.so libc-2.13.so
# mv /var/tmp/ohMyGod/rt/librt.so librt-2.13.so
...
...等等,确保我没有错过任何共享库。
最后,我复制了ldd
和ldconfig
二进制文件(它们也是 GLIBC 的一部分),并在我的 /wheezy 中进行了 chroot。
有效。
我只能假设从 x86 内的 chroot-ed 'qemu-arm' 模拟编译 GLIBC,不知何故搞砸了 - 也许该configure
过程从运行环境中检测到一些东西 - 而交叉编译不能被误导。
所以很自然地我进入下一步,并使用 busybox-static shell 来代替我的旧 lenny 的 {/bin,/sbin,...} 文件夹和 wheezy 文件夹 - 并重新启动到我全新的 Wheezy :-)
本人特此声明我的 WD MyBook 世界版是地球上唯一运行 Debian Wheezy 的人:-) 如果其他人有兴趣,我可以在某个地方上传 libc 文件的 tarball。