眼瞅着2020年马上就要到头了,承诺给大家的Linux移植三部曲还差最后一篇,这个拖延癌晚期恐怕今年是治不好了,不到最后的DL绝不妥协……

(这句话是年前写的,写了个开头就疫情了,封城,电脑丢在了公司,于是过上了老婆媳妇热炕头的性福生活,已无力码字……)

前面我们已经把U-Boot和Linux内核移植完成了,中间还加了个SDL2的移植过程,但其实看完我前面两篇的移植,Linux是不能跑起来的——没有根文件系统。

啥是根文件系统?根文件系统可以简单的理解为一个文件夹,或者目录,就是我们经常用到的“/”,这个目录中有包含了很多的子目录,我们系统运行所需要的库文件、命令、软件、配置、设备文件等等,都分类保存在不同的子目录中,这些文件统一叫做“根文件系统”。度娘说,根文件系统是Linux内核启动后挂载的第一个文件系统,Linux的内核镜像被保存在根文件系统中,呃……我不知道是我理解的有问题,还是度娘错了,我发现嵌入式Linux中镜像文件并没有保存在根文件系统中,而是保存在了另外一个分区,就是之前我们在SD卡中烧录的的0:1这个分区中,一般都会被存放在eMMC、SD卡、Flash、网络中某个地址,还记得U-Boot启动的时候加载的那些文件吗,一个是zImage,还有一个是设备树文件,就是从这些分区来的,但是我理解的他们并不属于根文件系统的一部分。

这些都瓦特艾沃了,直接拖鞋上炕吧!

  • 根文件系统介绍

本次我们构建系统用的是BusyBox,她是一个集成了三百多种常用Linux命令和工具的软件包,包含了一些简单的工具,例如ls、cat、echo等常用命令,还包含了例如grep、find、mount、telnet等更复杂更强大的的工具。类似BusyBox一类用于创建根文件系统的还有Yocto、Debian一类的,那些功能更强大,移植更简单,但耗时比较长,而且过于傻瓜,应用方便,不利于底层的学习。

在构建根文件系统之前,我们先卡一下根文件系统里都有啥,以Ubuntu为例,进入根目录,用ls看一下里面的文件夹:

目录

介绍

bin

用于存放系统可执行文件,如ls、mv一类的命令,此目录下的命令所有用户都可以使用

dev

device的缩写,里面的所有文件都与设备有关,Linux下一切接文件,硬件设备也是以文件方式体现的

etc

跟高速收费没啥关系,这个目录是用来存放各种配置文件的

lib

顾名思义,library的缩写,用来存放Linux所需要的库文件

mnt

临时挂载目录,用于临时设备的挂载,例如优盘插入后,会在这个目录下生成sd、usb一类的子目录,就是优盘的根目录

proc

此目录一般是空的,当 Linux系统启动以后会将此目录作为 proc文件系统的挂载点, proc是个虚拟文件系统,没有实际的存储设备。 proc里面的文件都是临时存在的,一般用来存储系

统运行信息文件。

usr

刚开始接触linux的时候,我一直以为这是用户目录,但后来发现丫不是user的缩写,是Unix Software Resource的缩写,这个目录用来存放软件,目录下也存放着很多软件,一般系统安装完成以

后此目录占用的空间最多。

var

存放数据的,比如日志、数据库文件、webroot一类的东西,都放在下面

sbin

不要从两个字母的看,容易不敢进去。此目录页用户存放一些可执行文件,但是此目录下的文件或者说命令只有管理员才能使用,

主要用户系统管理。

sys

系统启动以后此目录作为 sysfs文件系统的挂载点, sysfs是一个类似于 proc文件系统的特

殊文件系统, sysfs也是基于 ram的文件系统,也就是说它也没有实际的存储设备。此目录是系

统设备管理的重要目录,此目录通过一定的组织结构向用户提供详细的内核数据结构信息。

opt

可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中。之前一直SDL的时候我就放在这里了。

home

用户目录,存放这除root用户之外的其他用户工作目录,每创建一个用户就多一个子文件夹。咱们这次一直的是单用户的系统,这个目录用不到

root

root用户目录。

其他目录都不用搭理了,有兴趣的找度娘问问吧。

  • 根文件系统移植

BusyBox可以去官网下载一份,https://busybox.net,找到最新版下载就行了,据说之前的版本中(V1.29)出现过DNS不可用的问题,不知道后面的版本解决了没有,我用的是1.32,最新版肯定没错,如果实在不行,就去NXP官网找一份。

首先修改Makefile文件,加入交叉编译的一些参数,否则每次make都得写,太麻烦。

修改以下参数:

CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ARCH ?= arm

Linux默认采用UTF8的编码格式,但是丫不支持中文,稍作修改即可。

找到libbb/printable_string.c 中的printtable_string函数,这里面当c>=0x7F的时候就跳出了,把这里改改,修改后的代码如下:

const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str){char *dst;const char *s;s = str;while (1) {unsigned char c = *s;if (c == '\0') {/* 99+% of inputs do not need conversion */if (stats) {stats->byte_count = (s - str);stats->unicode_count = (s - str);stats->unicode_width = (s - str);}return str;}if (c < ' ')break;/*if (c >= 0x7f)break; */s++;}#if ENABLE_UNICODE_SUPPORTdst = unicode_conv_to_printable(stats, str);#else{char *d = dst = xstrdup(str);while (1) {unsigned char c = *d;if (c == '\0')break;/*if (c < ' ' || c >= 0x7f)*/if(c < ' ')*d = '?';d++;}if (stats) {stats->byte_count = (d - dst);stats->unicode_count = (d - dst);stats->unicode_width = (d - dst);}}#endifreturn auto_string(dst);}

在libbb/unicode.c找到unicode_conv_to_printable2函数,做同样修改:

if (unicode_status != UNICODE_ON) {char *d;if (flags & UNI_FLAG_PAD) {d = dst = xmalloc(width + 1);while ((int)--width >= 0) {unsigned char c = *src;if (c == '\0') {do*d++ = ' ';while ((int)--width >= 0);break;}/* *d++ = (c >= ' ' && c < 0x7f) ? c : '?';*/*d++ = (c >= ' ') ? c : '?';src++;}*d = '\0';} else {d = dst = xstrndup(src, width);while (*d) {unsigned char c = *d;/*if (c < ' ' || c >= 0x7f)*/if (c < ' ')*d = '?';d++;}}if (stats) {stats->byte_count = (d - dst);stats->unicode_count = (d - dst);stats->unicode_width = (d - dst);}return dst;}

以上两部分是支持中文目录的,如果纯英文环境,不改也罢。

接下来开始配置busybox,和linux内核、uboot的移植一样,也可以通过menuconfig进行调整,官方带了三种支持,分别是:

1. defconfig:缺省配置,也就是默认的配置项

2. allyesconfig:全选配置,也就是选中busybox中所有功能

3. allnoconfig:最小配置

我们使用默认的配置。

make defconfig

然后对默认配置进行微调:

make menuconfig

1. Settings -> Build static binary(no shared libs) 不选中

不使用静态编译,胴体爱编译的话要根据文件系统中所有库文件,编译出来的busybox比较小,静态编译出来的文件较大,但是DNS可能会出问题(1.29出这个问题,不知道1.32解决了没有,待验证)

2. Settings -> vi-style line editing commands 选中

3. Linux Module Utilities -> Simplified modutils 取消勾选

4. Linux System Utilities -> mdev 确保下面全部选中

5. Settings -> Support Unicode -> Check $LC_All,$LC_CTYPE and $LANG environment variables 选中

以上配置基本就完成了。

最后编译和安装

makemake install CONFIG_PREFIX=/home/mars/Linux/nfs/rootfs

CONFIG_PREFIX指向的目录就是启动根文件系统要用到的目录,busybox会把编译好的根文件系统整体复制到这个目录中。

以上,基本完成了根文件系统的第一步,但此时还无法启动,需要再复制一些文件进去才行。

Linux中的应用程序一般都是需要动态库的,当然你也可以编译成静态的,但是静态的可执行文件会很大。如果编译为动态的话就需要动态库,所以我们需要先根文件系统中添加动态库。

创建好了,库文件从哪里来呢? lib库文件从交叉编译器中获取, 前面我们搭建交叉编译环境的时候将交叉编译器存放到了“/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf”中,arm/”目录中。交叉编译器里面有很多的库文件,这些库文件具体是做什么的我们作为初学者肯定不知道,既然我不知道那就简单粗暴的把所有的库文件都放到我们的根文件系统中。这样做出来的根文件系统肯定很大,但是我们现在是学习阶段,还做不了裁剪。

进入根目录(不是Ubuntu的根目录,/home/mars/Linux/nfs/rootfs,千万别搞错了,要不然一会搞完你Ubuntu也打不开了,我就干了次这种傻事),在根目录中创建lib子目录,把交叉编译器下的类库复制到这里,命令如下:

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/cp *so* *.a /home/mars/Linux/nfs/rootfs/lib/ -dcd /home/mars/Linux/nfs/rootfs/lib/rm ld-linux-armhf.so.3cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/cp ld-linux-armhf.so.3 /home/mars/Linux/nfs/rootfs/lib/cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libcp *so* *.a /home/mars/Linux/nfs/rootfs/lib/ -d

其中/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf这里就是Ubuntu下gcc交叉编译环境的位置。

在根目录下创建usr/lib子目录,把其中一些类库再拷进去

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/libcp *so* *.a /home/mars/Linux/nfs/rootfs/usr/lib/ -d

搞完之后,用du命令看一下两个目录的大小

du lib usr/lib -sh 

57M lib

67M usr/lib

如果大小差不多,基本上一步是没问题了,到此为止,我们的根文件系统基本就完备了,此时可以正常启动。

但是启动前,还是需要配置一下你的NFS服务器和BootLoader环境,NFS配置我记得前面讲过,如果没有就去问度娘吧,实在找不到留言,我再补充。

重启开发板,进入uboot,设置bootargs参数:

setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.31.128:/home/mars/Linux/nfs/rootfs,proto=tcp rw ip=192.168.31.100:192.168.31.128:192.168.31.1:255.255.255.0::eth0:off'saveenv

最后一步记得保存,上次发了Linux内核移植后,有很多人给我留言,说设置的参数重启后就丢了,可能是两种原因造成的,一个是没有调用saveenv,另外一种是烧在SD卡的时候保存不上,这时候还需要用U盘量产工具重新格式化一下SD卡就行了,没有洗分析原因,可能是存储格式导致的。其他导致无法保存的,各位大佬可以补充。

关于bootargs参数的格式顺带说一下:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>

root: 启动根文件系统的设备,/dev/nfs表示从nfs启动,如果充SD卡或者emmc启动,这里设置/dev/mmcblk1p2一类的参数即可。

<server-ip>: 服务器 IP地址,也就是存放根文件系统主机的 IP地址,那就是 Ubuntu的 IP地址,比如我的 Ubuntu主机 IP地址为 192.168.31.128。

<root-dir>: 根文件系统的存放路径,比如我的就是 /home/mars/Linux/nfs/rootfs。

<nfs-options>: NFS的其他可选选项,一般不设置。

<client-ip>: 客户端 IP地址,也就是我们开发板的 IP地址, Linux内核启动以后就会使用此 IP地址来配置开发板。此地址一定要和 Ubuntu主机在同一个网段内,并且没有被其他的设备使用,在 Ubuntu中使用 ping命令 ping一下就知道 要设置的 IP地址有没有被使用,如果不能ping通就说明没有被使用,那么就可以设置为开发板的 IP地址,比如我就可以设置为192.168.31.100。

<server-ip>: 服务器 IP地址,前面已经说了。

<gw-ip>: 网关地址,我的就是 192.168.31.1。

<netmask>:子网掩码,我的就是 255.255.255.0。

<hostname>:客户机的名字,一般不设置,此值可以空着。

<device>: 设备名,也就是网卡名,一般是 eth0 eth1….,野火开发板 的 ENET2为 eth0 ,ENET1为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。这里我们使用 ENET2,所以网卡名就是 eth0。

<autoconf>: 自动配置,一般不使用,所以设置为 off。

<dns0-ip>: DNS0服务器 IP地址,不使用。

<dns1-ip>: DNS1服务器 IP地址,不使用。

有些值可以空着,但是冒号要保留,冒号一定用英文的,中文的不认。

弄完后重启你的开发板,发现顺利加载根目录,但有可能提示“can't run '/etc/init.d/rcS': No such file or directory ”,下面就解决这个问题。

如果启动过程中出现乱码,看看bootargs是否配置正确。

如果启动过程中一直无法进入根文件系统,看看你的NFS配置是否正确,还有就网卡选择是否正确,网线接在左边口(野火的板子),网卡选择的是eth0,另外一个口是eth1。

另外一种可能就是NFS版本造成的,后面附加内容中我把NFS配置简单写一下。

  • 完善根文件系统

到这里,几本你就成功了。

但是根文件系统中还少rcS这个文件,这个文件就是个shell脚本,是Linux内核启动后需要启动的一些服务,这个脚本中我们需要设置PATH和LD_LIBRARY_PATH两个环境变量(前者是执行命令时查找命令的目录,后者是通用库文件的保存目录),挂载所有文件系统,管理热插拔设备等。

文件内容如下:

#!/bin/shPATH=/sbin:/bin:/usr/sbin:usr/bin:$PATHLD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/libexport PATH LD_LIBRARY_PATHmount -amkdir /dev/ptsmount -t devpts devpts /dev/ptsecho /sbin/mdev > /proc/sys/kernel/hotplugmdev -s

编写完成后,给这个文件777的权限。

如果启动后一些环境变量不起作用,尝试把两个环境变量的申明写在/etc/profile中,我移植SDL的时候发现的这个问题,但一直没有跟踪是哪出的问题。

其中在第七行中,我们使用 mount命令来挂载所有的文件系统,这些文件系统由文件 /etc/fstab来指定,所以我们一会还要创建 /etc/fstab这个文件。

fstab在Linux开机以后自动配置哪些需要自动挂载的分区,格式如下:<file system> <mount point> <type> <options> <dump> <pass>中间用空格或Tab键分割,

<file system>:要挂载的特殊的设备,也可以是块设备,比如 /dev/sda等等。

<mount point>:挂载点。

<type>:文件系统类型,比如 ext2、 ext3、 proc、 romfs、 tmpfs等等。

<options>:挂载选项,在 Ubuntu中输入“ man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项 defaults包含了 rw、 suid、 dev、 exec、 auto、 nouser和 async。

<dump>:为 1的话表示允许备份,为 0不备份,一般不备份,因此设置为 0。

<pass>:磁盘检查设置,为 0表示不检查。根目录‘ ‘/’设置为 1,其他的都不能设置为 1其他的分区从 2开始。一般不在 fstab中挂载根目录,因此这里一般设置为 0。

文件内容:

#<file system>  <mount point>   <type>  <options>       <dump>  <pass>proc            /proc           proc    defaults        0       0tmpfs           /tmp            tmpfs   defaults        0       0sysfs           /sys            sysfs   defaults        0       0

注意分隔符别多打了,否则你会很Happy!

做好文件后重启,发现原来那个找不到rcS的提示木有了,但是这事还没完,还差一个文件没创建。

Linux在完成核内引导(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式来启动其他用户级的进程或服务。所以,init始终是第一个进程,其PID始终为1(ps -aux | less),它是系统所有进程的父进程。

init程序需要读取配置文件/etc/inittab.inittab是一个不可执行的文本文件,它有若干行指令所组成,由若干条指令组成。每条指令的结构都是一样的,由以“ “:”分隔的 4个段组成,格式如下:

<id>:<runlevels>:<action>:<process>

<id>:每个指令的标识符,不能重复。但是对于 busybox的 init来说, ,<id>有着特殊意义。对于busybox而言 <id>用来指定启动进程的控制 tty,一般我们将串口或者 LCD屏幕设置为控制tty。

<runlevels>: 对busybox来说此项完全没用,所以空着。

<action>:动作,用于指定 <process>可能用到的动作。

<process>: 具体的动作,比如程序、脚本或命令等。

Busybox支持的动作如下表所示:

动作

描述

sysinit

在系统初始化的时候process才会执行一次。

respawn

当process终止以后马上启动一个新的。

askfirst

和respawn类似,在运行 process之前在控制台上显示“ Please press Enter to activate this console.”。只要用户按下 Enter”键以后才会执行 process。

wait

告诉init,要等待相应的进程执行完以后才能继续执行。

once

仅执行一次,而且不会等待process执行完成。

restart

当init重启的时候才会执行 procee。

ctrlaltdel

当按下ctrl+alt+del组合键才会执行 process。

shutdown

关机的时候执行process。

创建/etc/inittab文件,内容如下:

#etc/inittab::sysinit:/etc/init.d/rcSconsole::askfirst:-/bin/shtty1::askfirst:-/bin/sh::restart:/sbin/init::ctrlaltdel:/sbin/reboot::shutdown:/bin/umount -a -r::shutdown:/sbin/swapoff -a

重启开发板,顺利进入系统,并不断收到“random: nonblocking pool is initialized”的提示,表示一切都OK了!

如果想关闭这个提示,用cat /proc/sys/kernel/printk命令,输入7 4 1 7的密码即可,这是个数字分别表示了不同级别的Linux日志输出,不再业务范围,就不解释了,想了解的问度娘吧。

进入系统后ping一下百度,看是否能通,如果提示“ping: bad address 'www.baidu.com'”说明DNS有问题,要么是busybox版本问题,要么就是你DNS设置有问题,如果是版本的事,去官网下载一个最新的,我用的是1.32,没这个问题。

如果是DNS设置问题那就好办了,创建/etc/resolv.conf,里面写入:

nameserver 114.114.114.114nameserver 192.168.31.1

第二个地址是我网关的地址,换成你的就行。

最后要说一句,根文件系统一些目录中的内容需要在开发板的命令行中才能看到,Ubuntu中看不到这些虚拟文件,不用诧异。

  • 烧写文件系统

之前我们做的内核镜像和根文件系统都是在SD卡上,或者NFS、SFTP方式启动的,这个章节中,我要把U-Boot、Linux内核、根文件系统一并烧写到emmc上,实现独立运行。

烧写EMMC、NAND或者QSPIFlash到设备上,用的是NXP官方提供的MfgTool工具,这里只演示EMMC的烧写方式,其他的大同小异。这个工具可以去官网下载,或者去野火提供的工具包中找找看有没有,我直接用的隔壁家的。还有一点需要说明的是,这工具只有Windows版的,目前没找到Linux版本的。

工具下载后有两个版本,without-rootfs是不烧写根文件系统的,with-rootfs是烧写根文件系统的,第一次用的会后看似已用后面的,后面改动内核后再烧写可以用前面的,如果为了省事,推荐后一个。

解压文件包后,里面有一堆的.vbs文件,那就是启动文件,直接起exe是不好使的。

只需要关心mfgtool2-yocto-mx-evk-*.vbs即可,其他碍眼的都可以删除,后缀说明了是烧写哪类外设的,这里以mfgtool2-yocto-mx-evk-emmc.vbs为基础进行试用和修改。

首先把开发板拨码开关拨到USB启动,然后连接OTA线,在右边那个USB口,左边的是串口,连接好后启动xshell(或其他的串口工具)监听开发板输出,重启开发板。

然后双击运行mfgtool2-yocto-mx-evk-emmc.vbs,看到“提示”后表示连接成功。

单击Start开始烧录,烧录过程中PC上会出现一个U盘,不用理丫,也别乱动。等待烧录结束,软件上会提示Dane,并且进度条全变成绿色,表示烧录成功,如果过程中出现错误,可能是文件不全或者使用的vbs文件不对导致的,重新解压一份,官方提供的工具百分百可用。

烧录结束后别着急拔线,一定要点Stop和Exit,再拔线,否则就烧废了(烧废了重烧就行了,除非硬件被你搞坏了,一般情况不会变砖)。

关闭开发板电源,拔OTA线,把拨码开关调到eMMC启动,重新上电。此时你运行的系统就是在开发板中的了。

这里面有两个地方需要注意:

  1. 如果启动后发现还是原来的系统,断电重启试试,如果还是原来的系统,重新烧一次即可解决问题,这个问题我也不清楚申请情况,我自己做的内核没出现过此类问题(除非没有点Stop),但野火官方给的镜像出现过很多次此类灵异事件。
  2. U-Boot启动成功,但内核或者根文件系统加载不成功,这就需要修改U-Boot的启动参数了,内核启动不成功的修改bootcmd,根文件系统加载不成功修改bootargs,这连个参数在上两篇文章中有详细描述,出门左转。

上面是烧NXP官方提供的内核文件,一般第二个问题不会出现,启动后用户名是root,没有密码,进入命令行后表示启动成功。

前面说的只是个引子,体验一下MfgTool这个工具,下面开始移植自己的烧录工具。

首先是烧录的文件,在工具目录的Profiles/Linux/OS Firmware用来存放要烧录系统的固件,files、firmware两个子目录和ucl2.xml文件。

在具体看这三个文件和文件夹之前,我们先来简单了解一下 MfgTool烧写的原理, MfgTool其实是先通过 USB OTG先将 uboot、 kernel和 .dtb(设备树 )这是三个文件下载到开发板的 DDR中,注意不需要下载 rootfs。就相当于直接在开发板的 DDR上启动 Linux系统,等 Linux系统启动以后再向 EMMC中烧写完整的系统,包括 uboot、 linux kernel、 .dtb(设备树 )和 rootfs,因此 MfgTool工作过程主要分两个阶段:

  1. 将 firmware目录中的 uboot、 linux kernel和 .dtb(设备树 ),然后通过 USB OTG将这个文件下载到开发板的 DDR中,目的就是在 DDR中启动 Linux系统,为后面的烧写做准备。
  2. 经过第1步的操作,此时 Linux系统已经运行起来了,系统运行起来以后就可以很方便的完成对 EMMC的格式化、分区等操作。 EMMC分区建立好以后就可以从 files中读取要烧写的 uboot、 linux kernel、 .dtb(设备树 )和 rootfs这 4个文件,然后将其烧写到 EMMC中。

firmware目录中有很多个.imx的uboot文件,一个zImage内核镜像文件和好多个.dtb格式的设备树文件,这些文件是NXP官方对不同板子做的支持,其实我们只需要关组imx6ull-14x14-evk的文件即可。

u-boot-imx6ull14x14evk_emmc.imx:NXP官方针对EVK板子做的U-Boot文件。

zImage-imx6ull-14x14-evk-emmc.dtb:EVK板子的设备树文件。

zImage:Linux镜像文件。

我们做自己的移植需要修改的就是这三个文件,其他的都可以不搭理。

files文件夹真正最后要烧入emmc的文件系统,也就是第二阶段要干的事。这里面除了上面说的那三个文件之外,还有一个rootfs_nogpu.tar.bz2的归档文件,这是就是根文件系统。

ucl2.xml文件知名了我们在烧录的时候如何从众多的文件中选择指定的型号,这个xml以<UCL>开始,</UCL>结束,是个标准的xml文件,其中<CFG>标签包裹的内容就是配置项,<LIST>标签包裹的是针对不同存储芯片烧写的命令,如果想要了解的话,我后面会附上一个做完注释的文件,有兴趣可以看看,没啥难的。

首先制作u-boot-imx6ull14x14evk_emmc.imx、zImage-imx6ull-14x14-evk-emmc.dtb、zImage和rootfs_nogpu.tar.bz2四个文件,覆盖原来的文件,根文件系统打包用的命令是tar jcvf rootfs_nogpu.tar.bz2 rootfs,打包一定要在移植的根目录进行,如果根文件系统加载不成功,看看是不是把rootfs也打包进行了,多一层目录启动不成功。保证这几个文件的名称和原来的名字一样,第一步就成功了。剩下的烧录过程和上面操作烧录官方镜像的一样即可。

各位,这事还没完,我们最终要的是一个完全属于野火i.MX6ULL Pro开发板的烧录工具,仪式感还是要有的!

回到烧录工具根目录,复制mfgtool2-yocto-mx-evk-emmc.vbs,重命名为mfgtool2-embedfire-emmc.vbs,其他的碍眼就删了吧。

复制ucl2.xml修改(我负载后面了),里面的内容不多解释了,看注释。

ucl2.xml中我把上面烧录的四个文件名都改了,都打上了embedfire的标签,根官方evk彻底闹掰,具体文件名在配置文件中找吧,都备注了。

用mfgtool2-embedfire-emmc.vbs烧录即可。

但我们自己烧录完之后还需要修改U-Boot的启动参数:

setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-embedfire-emmc.dtb;bootz 80800000 - 83000000'setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw ip=192.168.31.100:192.168.31.128:192.168.31.1:255.255.255.0::eth0:off'

setenv

第一行让U-Boot去emmc中找Linux内核。

第二句让内核到emmc中找根文件系统。

如果不想每次设置,就该U-Boot源码,找到u-boot的include/configs/mx6ull_embedfire_emmc.h的CONFIG_EXTRA_ENV_SETTINGS标签,里面的findfdt修改为一下内容:

"findfdt="\"if test $fdt_file = undefined; then " \"setenv fdt_file imx6ull-embedfire-emmc.dtb; " \"fi;\0" \

完了,终于完了!

到此为止,Linux移植三部曲全整理完毕,谁也不欠谁了。

  • 关于NFS的一点补充

这个坑有必要填一下,因为我再折腾NFS的时候,一开始总是加载不上,找了很多资料,都说是NFS配置问题,后来到国外的一个论坛中才发现这个坑(初中毕业的时候就把英语原封不动的还给老师了,所以遇到英文资料直接关了不看)。

如果你NFS加载根文件系统不成功,试试在U-Boot中手动输入nfs 80800000 192.168.31.128:/home/mars/Linux/nfs/zImage,看看能否加载,然后排除网线接错问题、IP设置问题、服务器IP设置问题后,依然提示“ERROR: File lookup fail”的错误,那多半是NFS版本问题没走。

这是因为uboot中使用的NFS版本是V2,而ubuntu的NFS版本为V3或V4及以上版本,导致uboot不能在NFS服务器中找到文件,    所以需要修改ubuntu中NFS的兼容。

在Ubuntu下,找到/etc/default/nfs-kernel-server文件,修改成下面的内容:

# Number of servers to start up#RPCNFSDCOUNT=8RPCNFSDCOUNT="-V 2 8"# Runtime priority of server (see nice(1))RPCNFSDPRIORITY=0# Options for rpc.mountd.# If you have a port-based firewall, you might want to set up# a fixed port here using the --port option. For more information,# see rpc.mountd(8) or http://wiki.debian.org/SecuringNFS# To disable NFSv4 on the server, specify '--no-nfs-version 4' here#RPCMOUNTDOPTS="--manage-gids"RPCMOUNTDOPTS="-V 2 --manage-gids"# Do you want to start the svcgssd daemon? It is only required for Kerberos# exports. Valid alternatives are "yes" and "no"; the default is "no".NEED_SVCGSSD=""# Options for rpc.svcgssd.RPCSVCGSSDOPTS="--nfs-version 2,3,4 --debug --syslog"

然后重启NFS服务

sudo /etc/init.d/nfs-kernel-server restart

这问题基本就解决了。

好吧,这次真的写完了。

别人疫情封城后都会胖个十斤八斤的,我这咋还瘦了十几斤呢……

配置文件下载地址:

https://download.csdn.net/download/suolong123/15382715

野火i.MX6ULL Pro开发板构建根文件系统相关推荐

  1. 野火i.MX6ULL Pro开发板U-Boot移植

    之前一直用STM32跑RTT,最近想做一台游戏机,主屏采用960*640,但是发现STM32的运存实在着急,2M根本不够用,64M勉勉强强,但是看了看价格就呵呵了.于是在网上搜了搜发现i.MX6ULL ...

  2. 【经验分享】桥接网络无法联网、开发板挂载根文件系统问题解决

    文章目录 总结:开发板挂载根文件系统遇到的一些问题 一.桥接网络 1.简介 注意避坑: 2.解决办法: 二.开发板端测试: 总结:开发板挂载根文件系统遇到的一些问题 一.桥接网络 1.简介 是指需手动 ...

  3. 野火i.MX6ULL Linux开发板资料

    1.配套教程:<i.MX6UL Linux开发实战指南> i.MX6UL Linux开发实战指南在线文档 2.开发板云盘资料(硬件资料.其它软件) 百度云资料链接: https://pan ...

  4. [光速QA][linux学习篇]基于韦东山I.MX6ULL pro开发板的学习笔记

    #前言: CSDN上已经有了太多的教程,我决定使用一种很新的方式记录自己的学习过程,如果对你有帮助就点个赞吧!一篇博文但是会长期更新(争取). 光速QA,希望面试官和面试者都可以给我这里找到灵感,如果 ...

  5. Licheepi_nano开发板:根文件系统编译

    一.下载根文件系统源码 下载并解压 wget https://buildroot.org/downloads/buildroot-2021.02.4.tar.gz tar xvf buildroot- ...

  6. buildroot构建根文件系统

    buildroot构建根文件系统 一.简介 Buildroot是Linux平台上一个构建嵌入式Linux系统的框架.整个Buildroot是由Makefile脚本和Kconfig配置文件构成的.本文使 ...

  7. 基于ubuntu-base构建根文件系统并移植到RK3568开发板

    目录 前言 一.根文件系统是什么? 二.构建根文件系统的方法 1.debootstrap 2.builroot 3.busybox 4.ubuntu-base 三.进入主题--如何使用ubuntu-b ...

  8. 北京迅为i.mx6ull终结者开发板使用手册+嵌入式Linux开发指南+裸机手册下载地址

    i.MX6ULL终结者三大手册,加速学习和开发速度,一秒化无形! <嵌入式Linux开发指南>+<开发板使用手册>+<裸机使用手册> 详细手册点击链接下载:http ...

  9. 【D1 Dock Pro开发板】Lichee D1 Dock 开发板用户指南

    作者:深圳矽速科技有限公司 1. 概述 D1 Dock Pro 开发板是由深圳矽速科技有限公司研发,搭载了全志D1多媒体处理器,基于阿里平头哥RISC-V 64位C906核心,支持RVV,1GHz主频 ...

最新文章

  1. Scratch青少年编程能力等级测试模拟题(三级)
  2. linux服务器静态ip,Ubuntu Linux系统下设置静态IP的方法
  3. mac 多java环境变量配置_java_Mac安装多个JDK版本并设置环境变量
  4. neo4j / cypher:悬挂查询参数
  5. AOP (面向切面编程)
  6. Android Studio 导入OpenCV 并调试运行face-detection例子
  7. Jsoup爬虫之Java爬虫工具类
  8. PCQQ - 发送自定义的XML卡片消息
  9. Java彩信接口开发经验及具体开发实现
  10. 准备嵌入式Linux开发环境
  11. 用户扫码微信支付后自动默认关注微信公众号
  12. 【Linux入门】— 腾讯云服务器的搭建
  13. [关键字]volatile
  14. C++实现生产者消费者队列
  15. 适用于Java开发人员的微服务:持续集成和持续交付
  16. AVR USART接收中断程序
  17. Weex 的采坑指南
  18. Kindle 中文阅读终极优化指南
  19. 南通大学计算机科学与技术学院电话,2017年南通大学计算机科学与技术学院江苏省内第二批本科(院校代码:1301)...
  20. PixelBook 2017 安装Windows 10驱动程序,满足日常使用。

热门文章

  1. 大平神出的一道双向链表题
  2. mysql 提示The maximum column size is 767 bytes.
  3. Qt for python QChartView鼠标滚动放大缩小
  4. openwrt mwan3配置
  5. 硬件学习之路——STM32之TM1638
  6. wxwork和wx.qy判断企业微信小程序编译运行环境
  7. 去哪儿网支付系统架构演进(上)
  8. 爬虫爬取王者荣耀 英雄故事 和技能
  9. 实现按钮的长按监听(聂同学的作业)
  10. Haskell函数式编程学习笔记