# Cross compile mtd-utils ###### tags: `blog` 因為工作的 kernel only 環境沒有用整合好的 build system,像是 yocto 之類的。想要使用 mtd-utils 這類 busybox 沒有提供的工具,就只能自己來 build 了。 ## Target board 環境 使用的 cross-compile toolchain 是 gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu。 target board 上跑的是 busybox。 ## References 1. https://wiki.beyondlogic.org/index.php/Cross_Compiling_MTD_Utils_for_ARM 2. https://elinux.org/CompilingMTDUtils e2fsprogs 3. https://www.cnblogs.com/schips/p/porting_e2fsprogs_on_arm_linux_with_usage.html 4. https://tldp.org/LDP/lfs/LFS-BOOK-6.1.1-HTML/chapter06/e2fsprogs.html exec mtd-utils fail 5. https://busybox.busybox.narkive.com/rSkeBEdC/how-to-execute-binary-other-than-busybox linker information 7. https://medium.com/fcamels-notes/linux-%E5%9F%B7%E8%A1%8C%E6%99%82%E5%B0%8B%E6%89%BE-symbol-%E7%9A%84%E6%B5%81%E7%A8%8B%E4%BB%A5%E5%8F%8A-shared-library-%E7%9B%B8%E9%97%9C%E7%9F%A5%E8%AD%98-b0cf1e19cbf3 8. https://stackoverflow.com/questions/11524820/what-is-the-difference-between-ldd-and-objdump find linked libraries 9. https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f ## Source Links zlib-1.2.11 http://www.zlib.net/zlib-1.2.11.tar.gz lzo-2.10 http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz e2fsprogs 1.45.6 https://kernel.googlesource.com/pub/scm/fs/ext2/e2fsprogs.git mtd-utils v2.1.2 https://github.com/sigma-star/mtd-utils ## Prepare working folder 準備給 `make install` 安裝的 folder (`MTD_OUTPUT_PATH`)。 ~~~ mkdir -p ~/mtd-build/install cd ~/mtd-build export MTD_SRC_PATH=$PWD export MTD_OUTPUT_PATH=$PWD/install echo $MTD_SRC_PATH; echo $MTD_OUTPUT_PATH ~~~ 另外也記得把 toolchain 加入到 PATH 裡。 ~~~ echo PATH=<path to toolchain>/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH ~~~ ## Build zlib 參考 1. 裡面的步驟。 > Download, cross compile and install the zlib compression libraries. Configure doesn't accept the --host parameter (reports unknown option), so you need to hack the makefile. ~~~ wget http://www.zlib.net/zlib-1.2.11.tar.gz tar -xzf zlib-1.2.11.tar.gz cd zlib-1.2.11/ ./configure --prefix=$MTD_OUTPUT_PATH --host=aarch64-linux-gnu ~~~ > Edit the makefile and prefix the build tools with arm-none-linux-gnueabi-. 修改 Makefile,在底下這些參數前面加入 `aarch64-linux-gnu-`,下面是參數修改後的樣子。 ``` CC=aarch64-linux-gnu-gcc LDSHARED=arm-linux-gnueabi-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map CPP=aarch64-linux-gnu-gcc -E AR=aarch64-linux-gnu-ar RANLIB=aarch64-linux-gnu-ranlib ``` 改完 Makefile 後就可以 build 了。`make install` 如上面講的,會安裝到 `MTD_OUTPUT_PATH` 裡。 ``` make make install ``` ## Build LZO 同樣是參考 1. 裡面的步驟。 ``` cd $MTD_SRC_PATH wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz tar -xzf lzo-2.10.tar.gz cd lzo-2.10/ ./configure --host=aarch64-linux-gnu --prefix=$MTD_OUTPUT_PATH make make install ``` ## Build e2fsprogs 參考 1,2 裡面的步驟。這邊使用的是 clone git。 在做 configure 時,若只依照 1,2 的指令,在有鎖使用權限的 server 上 `make install` 會碰到如下的錯誤。 所以我需要也參考 3,4 去指定其他的安裝路徑。 ~~~ make[1]: Entering directory `<WORKING_PATH>/mtd-build/e2fsprogs/scrub' MKDIR_P /lib/udev/rules.d MKDIR_P /etc/cron.d MKDIR_P <WORKING_PATH>/mtd-build/install/lib/e2fsprogs MKDIR_P <WORKING_PATH>/mtd-build/install/sbin <WORKING_PATH>/mtd-build/install/share/man/man8 <WORKING_PATH>/mtd-build/install/etc INSTALL /lib/udev/rules.d/e2scrub.rules /usr/bin/install: cannot create regular file ‘/lib/udev/rules.d/96-e2scrub.rules’: Permission denied ~~~ 另外也有在 4 看到這個是必要的。 >--enable-elf-shlibs This creates the shared libraries which some programs in this package use. 如果有碰到這個 error 的話就先 `make clean` 後在試一次,可能是因為用別的 toolchain build 過。 ~~~ ../lib/libsupport.a: error adding symbols: File in wrong format collect2: error: ld returned 1 exit status make[2]: *** [e2fsck] Error 1 ~~~ 完整步驟如下。 :::warning 每次 configure 參數有改變時,先做 make clean 後在 make。 ::: ``` cd $MTD_SRC_PATH git clone https://kernel.googlesource.com/pub/scm/fs/ext2/e2fsprogs.git cd e2fsprogs git checkout v1.45.6 ./configure --host=aarch64-linux-gnu \ --prefix=$MTD_OUTPUT_PATH \ --with-udev-rules-dir=$MTD_OUTPUT_PATH \ --with-crond-dir=$MTD_OUTPUT_PATH \ --with-systemd-unit-dir=$MTD_OUTPUT_PATH \ --enable-elf-shlibs make make install cd lib/uuid/ make install ``` ## Build mtd-utils 在 v2.1.2 的 mtd-utils 有支援 configure 了。就不用像 1,2 的做法要去修改 Makefile。 build 的方式可以參考一下 make_a_relaease.sh 的作法。 `autogen.sh` 就直接 call 就可以了,沒有要傳參數。 因為需要用到上面 build 好的 library,所以需要在 configure 時把 MTD_OUTPUT_PATH 給傳進去。 `./configure --help` 可以看到我們有哪些參數可以用。 ``` cd $MTD_SRC_PATH git clone https://github.com/sigma-star/mtd-utils.git cd mtd-utils git checkout v2.1.2 export PREFIX=$MTD_OUTPUT_PATH export LDFLAGS=-L$PREFIX/lib export CPPFLAGS=-I$PREFIX/include ./autogen.sh ./configure --host=aarch64-linux-gnu \ --prefix=$MTD_OUTPUT_PATH \ --with-sysroot=$MTD_OUTPUT_PATH \ --without-xattr \ --without-zstd \ --without-crypto \ LDFLAGS=-L$MTD_OUTPUT_PATH/lib \ CPPFLAGS=-I$MTD_OUTPUT_PATH/include make make install ``` 這一步完 mtd-utils 就 build 成功了! 接下來就是要放到 target board 上面跑囉。 ## Copy mtd-utils to rootfs copy $MTD_OUTPUT_PATH/sbin 到 target board rootfs 的 /sbin。 $MTD_OUTPUT_PATH/lib 就 copy 到 /lib。 ## Copy necessary libraries 若跟我一樣 rootfs 是從零開始建,只有把 busybox 放進來的話,應該是甚麼 lib 都沒有的。 我推薦可以看一下 6,7 知道一下 link 相關的東西。 使用 8 的 script 來幫助我們檢查 cross-compile 出來的 binary 需要哪些 lib。 把 8 的 script 存成一個檔案後放到 toolchain 中的 bin,命名成 <toolchain>-ldd,來方便使用。 以我的環境來說,輸出如下。 ``` $ aarch64-linux-gnu-ldd sbin/flash_erase libc.so.6 => /lib/libc.so.6 (0xdeadbeef) ld-linux-aarch64.so.1 => /lib/ld-linux-aarch64.so.1 (0xdeadbeef) ```
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.