以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
一、内容总结
本文讲述如何安装交叉编译工具链,与编译源码得到uboot、kernel、rootfs镜像文件。
(1)安装交叉编译工具链,主要是通过执行osdrv/opensource/toolchain/arm-hisiv300-linux/目录下的cross.install.v300脚本。
(2)编译完成后,在osdrv/pub/image_uclibc目录中有uboot、uImage、rootfs镜像文件。
root@ubuntu:/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/pub/image_uclibc# ls rootfs_hi3518ev200_128k.jffs2 rootfs_hi3518ev200_2k_128k_32M.img rootfs_hi3518ev200_64k.jffs2 uImage_hi3518ev200 rootfs_hi3518ev200_256k.jffs2 rootfs_hi3518ev200_2k_4bit.yaffs2 u-boot-hi3518ev200.bin root@ubuntu:/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/pub/image_uclibc#
(3)在osdrv/pub目录中有海思编译好的文件夹形式的根文件系统的压缩包。如果想单独把它制成镜像,需要先解压,然后执行以下命令。
root@ubuntu:/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0# ./osdrv/pub/bin/pc/mkfs.jffs2 -d osdrv/pub/rootfs_uclibc -l -e 0x10000 -o osdrv/pub/image_uclibc/rootfs_uclibc_64k.jffs2
二、环境搭建步骤
以普通用户进行以下操作时,总提示“arm-hisiv300-linux-gcc:command not found”,但其实我已经设置好PATH的内容。后来以root用户进行下面操作就可以了。
步骤一、下载海思SDK
下载链接见:Hi3518E_V200R001C01SPC030.rar
步骤二:解压缩SDK
将Hi3518E V200R001**/01.software/board/Hi3518E_SDK_V1.0.3.0.tgz拷贝到虚拟机合适的的位置,然后解压得到Hi3518E_SDK_V1.0.3.0目录。进入该目录后进一步解压SDK,即先执行“./sdk.cleanup”,再执行“./sdk.unpack”。
步骤三:安装交叉编译工具链
(1)根据第一季4:Hi3518E_SDK_Vx.x.x.x的SDK目录结构的内容信息,可知交叉编译工具链在osdrv/opensource/toolchain/目录中。该目录下有两个工具链目录,我们选择arm-hisiv300-linux目录,因为它对应着uclibc库,比gclibc库体积小得多。该目录下有脚本文件cross.install.v300,打开该脚本得知其指定了工具链的安装路径,我们在此目录下执行脚本“./cross.install.v300”。
xjh@ubuntu:~/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain$ ls arm-hisiv300-linux arm-hisiv400-linux xjh@ubuntu:~/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain$ cd arm-hisiv300-linux/ xjh@ubuntu:~/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain/arm-hisiv300-linux$ ls arm-hisiv300-linux.tar.bz2 cross.install.v300 runtime_lib xjh@ubuntu:~/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain/arm-hisiv300-linux$
#!/bin/bashTOP_DIR=/opt/hisi-linux/x86-arm TOOL_DIR=$TOP_DIR/arm-hisiv300-linux TAR_BIN_DIR=$TOOL_DIR/target/bin BIN_FILES=$TOOL_DIR/bin/arm-hisiv300-linux-uclibcgnueabi-* LN_FILE_NAME=arm-hisiv300-linux- TOOLS_PKG="`dirname $0`/arm-hisiv300-linux.tar.bz2"//省略部分
(2)将上述脚本TAR_BIN_DIR的值导入环境变量PATH,并用“echo $PATH”察看设置是否正确。为了让环境变量的更改设置永久生效,可以在~/.bashrc或者/etc/profile末行添加这条命令,然后重新执行该脚本“source /etc/profile”(否则会报错arm-hisiv300-linux-gcc:command not found)。
export PATH=/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH
步骤四:根据需求进行编译
参考文档readme_cn.txt。
(1)编译整个osdrv目录
在osdrv目录下输入以下命令,顺利的话得到uboot、kernel、根文件系统的镜像文件。
make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all
(2)清除整个osdrv目录的编译文件
make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 clean
(3)彻底清除整个osdrv目录的编译文件,包括编译文件外、已编译好的镜像
make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 distclean
(4)单独编译kernel
内核源码在SDK中的路径如上所示, 进入内核源代码目录后,执行以下操作。
cp arch/arm/configs/hi3518ev200_full_defconfig .config make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- menuconfig make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- uImage
(5)单独编译uboot
进入uboot源代码目录(见上面),执行以下操作。
make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- hi3518ev200_config
然后将生成的u-boot.bin复制到osdrv/tools/pc/uboot_tools/目录,在此目录下执行以下操作。此时生成的u-boot-ok.bin即为可用的u-boot镜像。
./mkboot.sh reg_info.bin u-boot-ok.bin
(6)制作文件系统镜像
在osdrv/pub/中有编译好的文件系统,因此不需要重新编译文件系统,根据开发板上flash的规格型号制作文件系统镜像即可。
本课程使用的开发板配置的存储器是spiflash,而spiflash适用于jffs2格式的镜像。制作jffs2镜像时,需要用到spiflash的块大小,这些信息会在uboot启动时会打印出来,如上所示。通过执行下面的命令,可以得到文件系统镜像。(64KB=0x10000)
osdrv/pub/bin/pc/mkfs.jffs2 -d osdrv/pub/rootfs_uclibc -l -e 0x10000 -o osdrv/pub/rootfs_uclibc_256k.jffs2
三、编译出错及解决方法
这里选择编译整个osdrv目录,即在osdrv目录下输入以下命令:
make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all
编译期间可能出现的错误以及解决方法如下:
1、报错,需要修改sh的命令链接,使其链接到bash。
root@ubuntu:/bin# ls -lh sh
lrwxrwxrwx 1 root root 4 Oct 18 07:43 sh -> dash
root@ubuntu:/bin# sudo dpkg-reconfigure dash //在弹出的窗口处选择no
Removing 'diversion of /bin/sh to /bin/sh.distrib by dash'
Adding 'diversion of /bin/sh to /bin/sh.distrib by bash'
Removing 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash'
Adding 'diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by bash'
root@ubuntu:/bin# ls -lh sh
lrwxrwxrwx 1 root root 4 Jan 3 19:18 sh -> bash
root@ubuntu:/bin#
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv#make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all
2、提示"mkimage" command not found - U-Boot images will not be built的解决方法。root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv#sudo apt-get install uboot-mkimage
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package uboot-mkimage is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
u-boot-tools
E: Package 'uboot-mkimage' has no installation candidate
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv# sudo apt-get install u-boot-tools
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
u-boot-tools
0 upgraded, 1 newly installed, 0 to remove and 674 not upgraded.
Need to get 59.7 kB of archives.
After this operation, 197 kB of additional disk space will be used.
Get:1 http://us.archive.ubuntu.com/ubuntu/ trusty/main u-boot-tools i386 2013.10-3 [59.7 kB]
Fetched 59.7 kB in 1s (51.7 kB/s)
Selecting previously unselected package u-boot-tools.
(Reading database ... 169087 files and directories currently installed.)
Preparing to unpack .../u-boot-tools_2013.10-3_i386.deb ...
Unpacking u-boot-tools (2013.10-3) ...
Processing triggers for man-db (2.6.7.1-1) ...
Setting up u-boot-tools (2013.10-3) ...
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv#
或者将osdrv/opensource/uboot/u-boot-2010.06/tools/的mkimage拷贝到/usr/local/bin目录下。
3、出现mkyaffs2image100错误提示。
出现错误的原因,是SDK中有在64位系统下编译的.o文件,而我用的是32位的ubuntu。
解决办法是进入tools/pc/mkyaffs2image/mkyaffs2image目录,使用“rm *.o”删除之前编译的痕迹即可,或者先make clean然后再make。我们的开发板使用的是spi flash,适用jffs2文件系统,所以不会做yaffs2文件系统,这个东西要不要都无所谓的。
/usr/bin/ld: i386:x86-64 架构于输入文件 mkyaffs2image.o 与 i386 输出不兼容
/usr/bin/ld: i386:x86-64 架构于输入文件 yaffs_ecc.o 与 i386 输出不兼容
/usr/bin/ld: i386:x86-64 架构于输入文件 yaffs_packedtags2.o 与 i386 输出不兼容
/usr/bin/ld: i386:x86-64 架构于输入文件 yaffs_tagsvalidity.o 与 i386 输出不兼容
collect2: error: ld returned 1 exit status
make[2]: *** [mkyaffs2image100] Error 1
make[2]: Leaving directory `/root/hisisdk/Hi3518E_S DK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image/mkyaffs2image'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/root/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image'
make: *** [hipctools] Error 2
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv# cd ./tools/pc/mkyaffs2image/mkyaffs2image
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image/mkyaffs2image#ls
devextras.h mkyaffs2image.o oob_config_v100.o oob_config_v400.c tar yaffs_ecc.o yaffs_packedtags2.c yaffs_tagsvalidity.c yaffs_trace.h
Makefile oob_config.h oob_config_v300.c oob_config_v504.c yaffs_ecc.c yaffs_guts.h yaffs_packedtags2.h yaffs_tagsvalidity.h yportenv.h
mkyaffs2image.c oob_config_v100.c oob_config_v301.c oob_config_v610.c yaffs_ecc.h yaffs_list.h yaffs_packedtags2.o yaffs_tagsvalidity.o
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image/mkyaffs2image#make clean
rm -f mkyaffs2image.o yaffs_ecc.o yaffs_packedtags2.o yaffs_tagsvalidity.o mkyaffs2image??? oob_config_v???.o
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image/mkyaffs2image# ls
devextras.h mkyaffs2image.c oob_config_v100.c oob_config_v301.c oob_config_v504.c tar yaffs_ecc.h yaffs_list.h yaffs_packedtags2.h yaffs_tagsvalidity.h yportenv.h Makefile oob_config.h oob_config_v300.c oob_config_v400.c oob_config_v610.c yaffs_ecc.c yaffs_guts.h yaffs_packedtags2.c yaffs_tagsvalidity.c yaffs_trace.h
root@ubuntu:~/hisisdk/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/mkyaffs2image/mkyaffs2image#make //这里的make只是对错误部分的make,其他部分已经是正确的。
4、bash: osdrv/pub/bin/pc/mkfs.jffs2: No such file or directory
[30]_bash: ./mkfs.jffs2: No such file or directory_ZHAITEACH的博客-CSDN博客
5、交叉工具链是32bit的而ubuntu是64bit的。
这里我的ubuntu就是32bit的,所以规避了这个问题
6、错误:compr_zlib.c:39:18: fatal error: zlib.h: No such file or directory
compr_zlib.c:39:18: fatal error: zlib.h: 没有那个文件或目录
#include <zlib.h>
^
compilation terminated.
make[2]: *** [/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/jffs2_tool/tmp/mtd-utils-1.5.0/compr_zlib.o] 错误 1
make[2]:正在离开目录 `/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/jffs2_tool/tmp/mtd-utils-1.5.0'
make[1]: *** [/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/jffs2_tool/tmp/sbin/mkfs.jffs2] 错误 2
make[1]:正在离开目录 `/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv/tools/pc/jffs2_tool'
make: *** [hipctools] 错误 2
root@ubuntu:/home/xjh/iot/hisi_development/Hi3518E_SDK/Hi3518E_SDK_V1.0.3.0/osdrv#
错误分析与解决:
(1)出现这个错误时,其实已经编译好uboot和kernel,只是rootfs的镜像文件还没有制作完成。为什么这么说呢?上面的错误提示是在make hipctool时出错,我们从osdrv/Makefile文件中可知,这个目标位于uboot和kernel之后。
(2)根文件系系统的镜像文件是如何制作的呢?根文件系统已经由海思提前编译好并以文件夹形式存放在osdrv\rootfs_scripts这个压缩包中。从Makefile的hirootfs_build可知,rootfs的镜像文件的制作,是以这个压缩包的解压文件为材料,利用mkfs.jffs2工具来完成的。如图所示。
(3)那mkfs.jffs2工具是怎样来的呢?回到上面(1)提到的hipctools,它利用tools/pc/jffs2_tool这个目录来制作mkfs.jffs2工具,如下图所示。
hipctools制作mkfs.jffs2时,因为找不到zlib.h而提示编译错误。zlib.h在tools/pc/zlib/tmp/include目录中,只需要复制到tools/pc/jffs2_tool/tmp/include目录中即可,注意同时要将zconf.h也复制过去的。还有要将tools/pc/zlib/tmp/lib目录下的libz.a、libz.so、libz.so.1和libz.so.1.2.7等4个文件复制到tools/pc/jffs2_tool/tmp/lib目录下。
(4)然后重新编译整个osdrv,如果顺利则会一直编译。如果此时提示其他工具的错误信息,则查看mkfs.jffs2脚本是否已经出现在/osdrv/tools/pc/jffs2_tool目录下,如果出现则手工把它复制到osdrv/pub/bin/pc目录下。同时,为了让编译继续运行,修改Makefile中hipctools的内容,如下图所示(因为手动复制了,所以图示里什么都不用执行,但是其实可以保留jff2有关的操作,这样就不用手动复制了)。这样修改的意思是,我们已经编译得到想要的mkfs.jffs2脚本,因此不需要再编译其他的工具,这样就不会提示其他工具的编译错误了。
(5)海思SDK并没有提供单独编译根文件系统的命令,接下来如果为了得到根文件系统的镜像文件而重新编译整个osdrv的话,很耗费时间。因此可以继续修改Makefile,把uboot和kernel编译的过程注释掉,因为前面已经完成这部分的工作。修改如下。(这步没有也没事,只是重新编译的时间比较长而已。)
(6)修改后重新整体编译整个osdrv,最后成功!