首先服务器需要配置好nfs和tftp,这两个在网上有很多资料,这里就省略了。在这个例子中我的服务器地址是:192.168.88.18,nfs跟文件系统目录为:/home/ubuntu/disk-2/nfs_rootfs,tftp目录为:/home/ubuntu/disk-2/tftpboot。tftp目录下已经放置了内核zImage和设备树文件lkf_am335x.dtb。
进入命令行之后设置开发板地址:

setenv ipaddr 192.168.88.16

设置好ip之后可以测试一下是否能正常ping得通服务器:

ping 192.168.88.18

window10 启用NFS失败 启动nfs命令_window10 启用NFS失败

返回“host xx.xx.xx.xx is alive”表明已经正常访问到了我服务器。

接下来设置服务器ip,服务器上的nfs目录:

setenv serverip 192.168.88.18
setenv rootpath /home/ubuntu/disk-2/nfs_rootfs

设置设备树文件名fdtfile(其实这一步本来uboot是设置好的了,但是由于我制作uboot的时候这里没写,所以得自己动手设置一下):

setenv fdtfile lkf_am335x.dtb

设置网络内核启动参数:

setenv netargs setenv bootargs console=ttyO0,115200n8 ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},nolock rw ip=192.168.88.16:192.168.88.18:192.168.88.1:255.255.255.0::eth0:on

这个netargs实际是设置了一个bootargs,这个就是最终要传给内核的参数,console=ttyO0,115200n8表示内核启动过程中信息输出端口,root=/dev/nfs跟文件系统位置为nfs,nfsroot=${serverip}:${rootpath},nolock rw ip=192.168.88.16:192.168.88.18:192.168.88.1:255.255.255.0::eth0:on。其中${serverip}就是前面设置的服务器ip 192.168.88.18${rootpath}就是前面我们设置的服务器上的nfs目录/home/ubuntu/disk-2/nfs_rootfsip=192.168.88.16:192.168.88.18:192.168.88.1:255.255.255.0::eth0:on其中第一个字段192.168.88.16是内核启动之后的静态ip地址,第二个字段192.168.88.18是服务器的ip地址,192.168.88.1是网关,255.255.255.0是掩码。
接下来下载内核了

tftp ${loadaddr} ${bootfile}

这条语句是从服务器的tftp目录下下载zImage文件。其中${loadaddr}是内核在内存上的地址,这里是0x82000000,${bootfile}在我的环境变量里面是zImage,所以这条语句实际是 tftp 0x82000000 zImage

window10 启用NFS失败 启动nfs命令_uboot_02


上图显示zImage已经正常下载下来。

接下来下载设备树文件:

tftp ${fdtaddr} ${fdtfile}

跟下载内核一样,${fdtaddr}是设备树地址,我这里是0x88000000${fdtfile} 是设备树文件,我这里是lkf_am335x.dtb,所以这条语句等价于tftp 0x88000000 lkf_am335x.dtb

window10 启用NFS失败 启动nfs命令_window10 启用NFS失败_03

接下來设置内核启动参数,前面我们已经设置好了环境变量,这里只需要短短的语句:

run netargs

最后启动内核:

bootz ${loadaddr} - ${fdtaddr}

其中${loadaddr}是前面下载下来的内核地址,${fdtaddr}是设备树地址。以下是内核启动的一些关键截图:

window10 启用NFS失败 启动nfs命令_u-boot_04


window10 启用NFS失败 启动nfs命令_uboot_05

window10 启用NFS失败 启动nfs命令_uboot_06


window10 启用NFS失败 启动nfs命令_内核_07


为了设置为开机之后自动以nfs方式启动,我们可以将以上设置保存到环境变量,以下我将前面的代码整理在一起:

setenv ipaddr 192.168.88.16
setenv serverip 192.168.88.18
setenv rootpath /home/ubuntu/disk-2/nfs_rootfs
setenv fdtfile lkf_am335x.dtb
setenv netloadimage  tftp ${loadaddr} ${bootfile}
setenv netloadfdt tftp ${fdtaddr} ${fdtfile}
setenv netargs setenv bootargs console=ttyO0,115200n8 ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},nolock rw ip=192.168.88.16:192.168.88.18:192.168.88.1:255.255.255.0::eth0:on
setenv netboot echo Booting from network ...\; run netloadimage\; run netloadfdt\; run netargs\; bootz ${loadaddr} - ${fdtaddr}
setenv bootcmd run netboot
saveenv

以上代码我们倒着看,bootcmd 就是uboot启动之后如果没有进入命令行那么uboot自动会执行的一条命令,它实际调用run netboot,而netboot做了:件事,下载内核、下载设备树、设置内核启动参数、启动内核。
以上这些环境变量,其实很多uboot就已经设置好了,如何去用你们可以print查看一下。