首先准备:

1.搭建环境 ubuntu 14.04(必须是这个版本,其他的很可能会有错误)

2.i.mx6ul的内核源码我是放在ubuntu下的、/home/ll/MYiR-iMX-Linux

目录下面显示如下图(就是内核的源码目录)

imx6ull 移植 docker_imx6ull 移植 docker

因为我的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

如果没有报错,此时应该会出现一个图形界面

imx6ull 移植 docker_imx6ull 移植 docker_02

 

 

(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) --->,然后进去

imx6ull 移植 docker_imx6ull 移植 docker_03

进去后会显示这样一个界面,并且选中红色框的选项,进去后把路径改为自己的开发板内核源码路径,我的就是上面那个。

(3)然后进入最下面

Toolchain Options --->选项,进去后如下图,

imx6ull 移植 docker_c语言_04

然后拉到下面,进入下图选项

imx6ull 移植 docker_内核_05

,进入后选择glibc。

然后保存退出。

3.2修改源码

然后我们修改openwrt自带的Freescale i.MX 6平台的信息。

进入源码目录下,target/linux/imx6/目录,修改该目录下的Makefile

原Makefile内容

imx6ull 移植 docker_imx6ull 移植 docker_06

修改后的内容

imx6ull 移植 docker_imx6ull 移植 docker_07

红色框框为修改的内容,

第一个,源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,去替换原厂源码,再烧录,启动。居然成功了。。。

imx6ull 移植 docker_imx6ull 移植 docker_08

 

最后总结:

1.要用ubuntu14.04系统

2.内核要用板子提供的,工具链用的是openwrt默认的。

3.C语言库要用glibc不要用musl详见上面3.1配置信息(3)。

4.各种压缩和解压操作都要在linux平台上,不要再windows操作。