我在前面已经编译好了Linux内核,UBoot,还有根文件系统(根文件系统是直接用现成的),当然这些都是华清远见已经移植好了的,我先用他们移植好的来进行测试,如果没有问题了,后面自己移植的时候相对来说就有个参照,遇到问题或者不会的地方可以看看他们怎么做的。
我这里使用从网络加载Linux内核和挂载根文件系统的方式来测试,因为我们在学习的过程中,会不断的修改代码,编译代码,然后测试运行,如果每次都烧录到SD卡或者EMMC的话,会很麻烦,所以直接从网络上加载是最方便的,等所有代码都没有问题了之后,再固化到板子上去。
这里从网络加载的意思是,UBoot在引导Linux系统的时候,不是从板子上的SD卡,或者EMMC去找内核镜像文件和设备树,而是通过TFTP网络协议,从局域网主机上(也就是我用于开发的Ubuntu)去下载镜像文件(uImage)和设备树文件(exynos4412-fs4412.dtb)。通过NFS网络协议,从局域网主机(也就是我用于开发的Ubuntu)去挂载根文件系统。我们会把uImage,设备树文件和根文件系统提前放到Ubuntu上,然后在uboot里面通过一些命令来设置内核启动的参数,让UBoot能够从局域网主机上加载这些东西到内存里面去运行,也就是通常说的,从网络启动和挂载。
我在以前学习Linux驱动的时候,就已经搭建好了一套网络加载的环境,包括TFTP和NFS这些服务,我的Ubuntu上都已经安装好了,相应的文件夹以及属性那些都已经设置好了,我就不再记录了,需要的可以参考正点原子出的Linux驱动课程。所以,我只需要把uImage,exynos4412-fs4412.dtb复制到TFTP的加载目录下,根文件系统(rootfs.tar.xz)复制到NFS的加载目录里面就可以了。
注意,rootfs.tar.xz需要进行解压缩。
好了,东西准备好了,接下来就是在UBoot里面配置一些跟网络相关的环境变量,以及设置启动命令了。跟网络相关的环境变量有如下几个:
ipaddr,表示板子的IP地址,需要和Ubuntu主机处于同一个局域网内。
ethaddr,表示板子的网卡地址,也就是MAC地址,随意设置,符合MAC地址格式即可。
gatewayip,网关地址。
netmask,子网掩码,要保证板子和主机处于同一个局域网内。
serverip,服务器的IP地址,这里的服务器就是Ubuntu主机。
我的板子和Ubuntu主机连到了同一个无线路由器(192.168.1.1),Ubuntu的IP是192.168.1.8。我们通过使用 setenv 命令来设置环境变量,首先板子上电,倒计时结束前按下Enter,进入uboot交互控制台,使用如下命令:
setenv ipaddr 192.168.1.100
setenv ethaddr 00:04:9f:04:d2:35
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.8
最后,使用 saveenv ,保存设置,不然上电后设置会丢失,如下图所示:
我们还可以使用 printenv 命令,查看环境变量的值。
设置好这些变量之后,我们的UBoot就可以通过网络访问到Ubuntu主机了,接下来就需要设置启动命令和启动参数,让UBoot从网络加载内核和设备树,并且从网络挂载根文件系统。启动命令通过变量 bootcmd 来设置,启动参数通过变量 bootargs 来设置,大概像下面这样子。
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.8:/samba/nfs/rootfs ip=192.168.1.100:192.168.1.8:192.168.1.1:255.255.255.0::eth0:off'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000'
这两个命令是我之前使用正点原子的板子的时候使用的,4412这个板子肯定要做一些更改,至于要怎么改,我明天在群里问下老师,然后在下篇文章的时候再贴出来,顺便解释下这两条命令。这个可不能自己摸索,先测试过了再说,反正也是八九不离十。