blog
因為工作的 kernel only 環境沒有用整合好的 build system,像是 yocto 之類的。想要使用 mtd-utils 這類 busybox 沒有提供的工具,就只能自己來 build 了。
使用的 cross-compile toolchain 是 gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu。
target board 上跑的是 busybox。
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
準備給 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
參考 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
同樣是參考 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
參考 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
完整步驟如下。
每次 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
在 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_OUTPUT_PATH/sbin 到 target board rootfs 的 /sbin。
$MTD_OUTPUT_PATH/lib 就 copy 到 /lib。
若跟我一樣 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)