Arm

為我的 ARM SoC 交叉編譯 GLIBC

  • October 1, 2017

我在 chroot-ed 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 也會出現同樣的問題——因為它比squeeze 更新——事實上從現在開始任何 Debian 版本都會發生,因為他們的 GLIBC 不能在我的 2.6.17 核心上工作。

起初我認為這是一個交易破壞者 - 但後來我意識到我理論上可以重新編譯 GLIBC 以使用我的 SoC 使用的舊核心……但我需要一個與用於建構 libc6 的環境相同的環境打包在例如 Debian 擠壓中。

我猜 GLIBC 的編譯和 libc6_2.11.3-4.deb 文件的準備是通過 Debian 之神發明的自動交叉編譯機器完成的。

我不是上帝……我也無法在 Google 中找到任何關於如何成為一體的資訊 - 即如何使用我的 Core i5 作為主機,使用與打包版本(在 Debian 內部squeeze)完全相同的設置來交叉編譯 GLIBC使用。

所以我欺騙了它——我想出瞭如何在我的 Core i5 上設置 Debian 的 ARM 版本擠壓(一種使用qemu-arm二進製文件的靜態版本的技術)。

在我的 x86 託管版本中 chroot 後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) 複製到了預設的壓縮文件上,並嘗試 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或者wheezeGLIBC來執行?

任何關於我做錯了什麼和/或如何進行的想法/指示將不勝感激……

我做到了 :-)

我基本上遵循了 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:.

我一路走過去,經過擠壓:我解除了 /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
...

…等等,確保我沒有錯過任何共享庫。

最後,我複制了lddldconfig二進製文件(也是 GLIBC 的一部分),並在我的 /wheezy 中進行了 chroot。

有效。

我只能假設從 x86 中的 chroot-ed ‘qemu-arm’ 仿真編譯 GLIBC,不知何故把事情搞砸了——也許該configure程序從執行環境中檢測到一些東西——而交叉編譯不能被誤導.

所以很自然地,我進入了下一步,並使用了一個busybox-static shell 將舊 lenny 的 {/bin,/sbin,…} 文件夾替換為 wheezy 文件夾 - 並重新啟動到我全新的 Wheezy :-)

我在此聲明我的 WD MyBook World Edition是地球上唯一執行 Debian Wheezy 的版本 :-) 如果其他人有興趣,我可以在某個地方上傳 libc 文件的 tarball。

引用自:https://unix.stackexchange.com/questions/163765