首先准备:
1.搭建环境 ubuntu 14.04(必须是这个版本,其他的很可能会有错误)
2.i.mx6ul的内核源码我是放在ubuntu下的、/home/ll/MYiR-iMX-Linux
目录下面显示如下图(就是内核的源码目录)
因为我的i.mx6ul开发板支持的内核是linux-4.1.15,而19.07的linux内核源码版本是4.14,不相同,所以在下面编译时需要替换自己的内核源码。
3.开发板内核源码关联的交叉编译工具,我在编译时如果选用开发板提供的交叉编译链,在编译openwrt源码时会报错,我最后就没有选用开发板的交叉工具链,而是选用了openwrt自带的交叉工具链,编译成功。由于没有使用外部工具链,这里就不仔细说明使用方法。
开始编译:
一,在ubuntu14.04搭建openwrt的开发环境
1.下载openwrt需要的依赖库
sudo apt-get install subversion g++ zlib1g-dev build-essential git python python3 libncurses5-dev gawk gettext unzip file libssl-dev wget libelf-dev ecj fastjar java-propose-classpath asciidoc bzip2 libz-dev libtool
(如果编译时提示还缺少其他的库,可根据提示下载)
2.下载openwrt源码
我用的是19.07版,其他版本没有试。
19.07地址https://github.com/openwrt/openwrt/archive/v19.07.2.tar.gz
3.修改配置openwrt源码
3.1配置信息
下载好之后解压,然后进入源码顶层目录,假设目录名为openwrt,即
cd openwrt
然后执行
./scripts/feeds update -a
./scripts/feeds install -a
再输入以下命令,检查哪些需要的包还没有安装:
make defconfig
make menuconfig
如果没有报错,此时应该会出现一个图形界面
(1)进去第一个Target System ---> 选择 (Freescale i.MX 6)。
因为openwrt默认没有i.mx6ul平台,我们可以增加i.mx6ul平台或者修改与它类似的Freescale i.MX 6平台。我这里选择的是修改Freescale i.MX 6平台,为i.mx6ul使用,这里选完成之后我们再去修改Freescale i.MX 6的信息。
(2)选择[*] Advanced configuration options (for developers) --->,然后进去
进去后会显示这样一个界面,并且选中红色框的选项,进去后把路径改为自己的开发板内核源码路径,我的就是上面那个。
(3)然后进入最下面
Toolchain Options --->选项,进去后如下图,
然后拉到下面,进入下图选项
,进入后选择glibc。
然后保存退出。
3.2修改源码
然后我们修改openwrt自带的Freescale i.MX 6平台的信息。
进入源码目录下,target/linux/imx6/目录,修改该目录下的Makefile
原Makefile内容
修改后的内容
红色框框为修改的内容,
第一个,源Freescale i.MX 6平台是cortex-a9架构,我们i.mx6ul是cortex-a7架构
第二个,源Freescale i.MX 6平台不支持浮点型,我们i.mx6ul要支持浮点型
第三个,源Freescale i.MX 6平台的linux内核是4.14版本,我们i.mx6ul是4.1.15版本,这里改为4.1就好。有说改为4.1.15会报错,我这里没有验证。改为4.1亲侧可用。
然后在target/linux/imx6/目录下还有一个config-4.14文件,我没要改为我们的。
我们的在我们的内核源码目录下的arch/arm/configs也就是我的/home/ll/MYiR-iMX-Linux/arch/arm/configs目录下,找到自己开发板对应的xxxxx_defconfig,然后把这个文件名称修改为config-4.1(这里的4.1数字是要根上面的Makefile里面内核源码版本一样),并且拷贝到target/linux/imx6/目录下,并把原来的config-4.14删除。然后再删除target/linux/generic/下面的config-4.14文件。
完成后,准备工作就完成了。
4.编译openwrt源码
编译错误:
错误1:
find /home/ll/openwrt-openwrt-19.07/build_dir/target-arm-linux-gnueabihf_glibc/libnl-tiny-0.1/ipkg-arm_cortex-a7_vfpv3-d16/libnl-tiny -name 'CVS' -o -name '.svn' -o -name '.#*' -o -name '*~'| xargs -r rm -rf
Package libnl-tiny is missing dependencies for the following libraries:
libc.so.6
make[3]: *** [/home/ll/openwrt-openwrt-19.07/bin/packages/arm_cortex-a7_vfpv3-d16/base/libnl-tiny_0.1-5_arm_cortex-a7_vfpv3-d16.ipk] Error 1
解决方法:
进入openwrt的更目录,然
cd staging_dir/target-mips_24kc_musl(这个应该是你自己的编译工具)/pkginfo/ 目录下
对libc.provides这个文件进行修改
在该文件增加 libc.so.6 这句内容(如果出现的不是 libc.so.6这个库,而是其他的库,则就名字替换成对应的名称修改)
错误2:
* * Restart config... * * Enable the block layer * Enable the block layer (BLOCK) [Y/?] y Support for large (2TB+) block devices and files (LBDAF) [Y/n/?] (NEW) ^Cscripts/kconfig/Makefile:36: recipe for target 'silentoldconfig' failed make[2]: *** [silentoldconfig] Interrupt
解决方法:
需要编译自己的内核源码,下面是我的内核源码编译方法。每个人的困难不一样。
先要配置交叉环境
(下面这些是我的开发板的厂家提供的)
tar -xvf 03-Tools/Toolchain/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz
export PATH=$PATH:$DEV_ROOT/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
进入我们内核源码顶层目录:
执行
make distclean
make myd_y6ulx_defconfig
make zImage dtbs
这里的myd_y6ulx_defconfig配置是自己开发板厂商提供的。
编译linux内核 出现错误
错误3:
/bin/sh: 1: bc: not found
kernel/time/Makefile:30: recipe for target 'kernel/time/timeconst.h' failed
make[2]: *** [kernel/time/timeconst.h] Error 127
解决方法:安装bc
#sudo apt install bc
编译linux内核 出现错误
错误4:
In file included from arch/arm/boot/dts/imx50-evk.dts:15:0:
arch/arm/boot/dts/imx50.dtsi:16:42: fatal error: dt-bindings/clock/imx5-clock.h: No such file or directory
#include <dt-bindings/clock/imx5-clock.h>
^
解决办法:
(1)执行命令
cd arch/arm/boot/dts/include
进入该目录。
(2)执行
ln -s ../../../../../include/dt-bindings/ ./
软连接文件。
错误5:
./scripts/Makefile.headersinst:55: *** Missing UAPI file
include/uapi/linux/netfilter
xt_DSCP.h
解决方法:
在该文件夹有xt_DSCP.h该头文件,不过大小写不一样,把对应的报错文件大写改为小写,或者小写改为大写。
错误6:
target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/image-imx6dl-gw551x.dtb.tmp /home/ll/openwrt-19.07/build_dir/target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/linux-4.1/arch/arm/boot/dts/imx6dl-gw551x.dts
arm-openwrt-linux-gnueabi-cpp: error: /home/ll/openwrt-19.07/build_dir/target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/linux-4.1/arch/arm/boot/dts/imx6dl-gw551x.dts: No such file or directory
arm-openwrt-linux-gnueabi-cpp: warning: '-x assembler-with-cpp' after last input file has no effect
arm-openwrt-linux-gnueabi-cpp: fatal error: no input files
compilation terminated.
解决方法:
提示 error: /home/ll/openwrt-19.07/build_dir/target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/linux-4.1/arch/arm/boot/dts/imx6dl-gw551x.dts: No such file or director,找不到文件。我们进入到对应的文件夹,把类似的文件拷贝一份改为它找不到的文件名字,这样就可以找到了。因为这些找不到的文件对我编译的内容不影响。
之后就可以编译完成了。
编译完成之后我们需要 rootfs zImage dtb这三个生成的文件
1、rootfs在openwrt源码下bin/targets/imx6/generic-glibc/目录下 文件名为openwrt-imx6-default-rootfs.tar.gz,我们生成的是这个文件,具体最后需要的格式如果跟这个不一样,则需要对他先解压,再压缩成需要的格式。
2、zImage在openwrt源码下build_dir/target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/目录下,有个zImage文件
3、dtb文件在build_dir/target-arm_cortex-a7+vfpv3-d16_glibc_eabi/linux-imx6/linux-4.1/arch/arm/boot/dts/目录下,该目录下有好多个文件,我需要的是imx6ul-14x14-evk.dtb。
最后说一下坑的地方:
我是用上面的三个文件方法是替换掉原厂商的对应三个文件,然后启动。
原厂商的zImage和dtb我都替换了我自己的,这个格式也没有什么问题。当我替换原厂商的rootfs问件时出了问题(刚开始我也不知道)。下面听我细细说来
厂商提供的源roofs的全名是core-image-base-myd-y6ul14x14.rootfs.tar.bz2。也就是说我要把我刚刚生成的文件先解压再压缩成.tar.bz2的后缀格式。查资料找不到在windows上压缩成tar.bz2格式的方法,说需要先将文件压缩成.tar后缀的格式,再用linux命令bzip2把.tar文件压缩成.tar.bz2格式。
我首先的做法是将我生成的文件openwrt-imx6-default-rootfs.tar.gz,在windows上解压然后在压缩成.tar格式,之后再在ubuntu上把这个.tar文件压缩成.tar.bz2格式。压缩完成后用电脑打开看着一切正常,根源厂商提供的内容也基本一致。就认为自己压缩的没有问题。但是在往开发板烧写完成后,启动时出现
devtmpfs: mounted
Freeing unused kernel memory: 428K (80a7f000 - 80aea000)
Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
---[ end Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
只能启动到这里。
刚开始认为是编译系统的时候内核有问题,因为编译系统时也编了一个星期左右,现在ubuntu16.04编,出现好多解决不了的错误,又在ubuntu14.04编,刚开始编的时候用了板子提供的交叉编译链,也出现了解决不了的问题,然后又抛弃板子的交叉编译链,直接用openwrt自己的编译工具。最终系统才编译成功,虽然编过了,但很怀疑编译好的系统能不能用。于是在出现开发板启动不成的错误的时候,就认为是系统编译的问题。然后又从新修改一些配置参数,再次编译。就这样编译好多次,也烧录的好多次,都是出现那个启动不成功的错误。这个过程持续了差不多两天,最后实在不知道修改什么的时候,才想着是不是压缩包的问题,于是就拿着原厂提供的可以成功启动的rootfs压缩包,就是core-image-base-myd-y6ul14x14.rootfs.tar.bz2。把他解压后再用我之前的方法去压缩,然后重新烧录开发板,发现出现同样的错误,what fuck?原厂可以启动的解压后在压缩都出问题。这时候就可以确定我的压缩方法是有问题的。虽然还是不确定编译的系统有没有问题,但是还是压缩方法可以确定是有问题的。
于是又继续查找怎么压缩成tar.bz2文件的方法。终于又找到了一种方法
05-.tar.bz2格式 解压:[*******]$ tar jxvf FileName.tar.bz2 压缩:[*******]$ tar jcvf FileName.tar.bz2 DirName
于是我吧原厂商文件先用上面命令解压后在压缩,然后再用这个新生成的压缩文件替换原厂的文件,烧写,启动,成功了。这个时候说明文档压缩方法是正确的了。
然后再把我之前生成的rootfs文件,openwrt-imx6-default-rootfs.tar.gz,用linux解压命令加压
tar zxvf openwrt-imx6-default-rootfs.tar.gz,
解压后会生成一堆小文件
我们新建一个空白文件夹rootfs,把刚刚生成的一堆小文件拷到rootfs文件夹里面,然后cd进入到rootfs目录里,执行压缩命令
tar jcvf FileName.tar.bz2 ./*
这个时候就会生成FileName.tar.bz2文件,然后再把名字改成core-image-base-myd-y6ul14x14.rootfs.tar.bz2,去替换原厂源码,再烧录,启动。居然成功了。。。
最后总结:
1.要用ubuntu14.04系统
2.内核要用板子提供的,工具链用的是openwrt默认的。
3.C语言库要用glibc不要用musl详见上面3.1配置信息(3)。
4.各种压缩和解压操作都要在linux平台上,不要再windows操作。