Uboot启动内核和根文件系统命令分析

  uboot有两种启动 Linux 内核和rootfs的方法,一种是直接从flash(nand或emmc)启动,一种是从网络启动。这里面用到了两个非常重要的环境变量bootcmd 和 bootargs。

一、bootcmd 和 bootargs 环境变量

  bootcmd 保存着 uboot 默认命令, uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核。可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值。
  bootargs 保存着 uboot 传递给 Linux 内核的参数。bootargs 就是设置了很多的参数的值,这些参数 Linux 内核会使用到,常用的参数有:

1、 console

  console 用来设置 linux 终端(或者叫控制台),也就是通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕?如果是串口的话应该是串口几等等。一般设置串口作为 Linux 终端,这样我们就可以在电脑上通过 SecureCRT 来和 linux 交互了。

2、 root

  root 用来设置根文件系统的位置,例如 root=/dev/mmcblk1p2 用于指明根文件系统存放在mmcblk1 设备的分区 2 中。root 后面有“rootwait rw”,rootwait 表示等待 mmc 设备初始化完成以后再挂载,否则的话mmc 设备还没初始化完成就挂载根文件系统会出错的。 rw 表示根文件系统是可以读写的,不加rw 的话可能无法在根文件系统中进行写操作,只能进行读操作。

3、 rootfstype

  此选项一般配置 root 一起使用, rootfstype 用于指定根文件系统类型,如果根文件系统为ext 格式的话此选项无所谓。如果根文件系统是 yaffs、 jffs 或 ubifs 的话就需要设置此选项,指定根文件系统的类型。

二、从 EMMC 启动 Linux 系统

  从 EMMC 启动也就是将编译出来的 Linux 镜像文件 zImage 和设备树文件保存在 EMMC中, uboot 从 EMMC 中读取这两个文件并启动,设置 bootargs 和 bootcmd这两个环境变量

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 Test.dtb; bootz 80800000 - 83000000;'
saveenv
boot

  首先两个命令setenv 和 saveenv,命令 setenv 用于设置或者修改环境变量的值。命令 saveenv 用于保存修改后的环境变量。另一个boot 命令是用来启动 Linux 系统的。
  uboot传给linux内核的参数保存在bootargs环境变量中,保存了linux 终端是什么和根文件系统的位置。
uboot的命令:

setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 Test.dtb; bootz 80800000 - 83000000;'

  用到的命令有:

1、mmc dev 命令

  mmc dev 命令用于切换当前 MMC 设备,命令格式如下:
  mmc dev [dev] [part]
  [dev]用来设置要切换的 MMC 设备号, [part]是分区号。如果不写分区号的话默认为分区 0。
  使用如下命令切换到 MMC 1:
  mmc dev 1 //切换到 MMC 1

2、fatload 命令

  fatload 命令用于将指定的文件读取到 DRAM 中,命令格式如下:
  fatload [<dev[:part]> [ [ [bytes [pos]]]]]
  interface 为接口,比如 mmc, dev 是设备号, part 是分区, addr 是保存在 DRAM 中的起始地址, filename 是要读取的文件名字。 bytes 表示读取多少字节的数据,如果 bytes 为 0 或者省略的话表示读取整个文件。 pos 是要读的文件相对于文件首地址的偏移,如果为 0 或者省略的话表示从文件首地址开始读取。我们将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的0X80800000 地址处,命令如下:
  fatload mmc 1:1 80800000 zImage

3、bootz 命令

  要启动 Linux,需要先将 Linux 镜像文件拷贝到 DRAM 中,如果使用到设备树的话也需要将设备树拷贝到 DRAM 中。可以从 EMMC 或者 NAND 等存储设备中将 Linux 镜像和设备树文件拷贝到 DRAM,也可以通过 nfs 或者 tftp 将 Linux 镜像文件和设备树文件下载到 DRAM 中。不管用那种方法,只要能将 Linux 镜像和设备树文件存到 DRAM 中就行,然后使用 bootz 命令来启动, bootz 命令用于启动 zImage 镜像文件, bootz 命令格式如下:
  bootz [addr [initrd[:size]] [fdt]]
  命令 bootz 有三个参数, addr 是 Linux 镜像文件在 DRAM 中的位置, initrd 是 initrd 文件在DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可, fdt 就是设备树文件在 DRAM 中的地址。

三、从网络启动 Linux 系统

  从网络启动 linux 系统的目的就是为了调试。也就是将 linux 镜像文件和根文件系统都放到 Ubuntu 下某个指定的文件夹中,这样每次重新编译 linux 内核或者某个 linux 驱动以后只需要使用 cp 命令将其拷贝到这个指定的文件夹中即可。我们可以通过 tftp 从 Ubuntu 中下载 zImage 和设备树文件,根文件系统的话可以通过 nfs 挂载。

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.250:/home/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off' //设置 bootargs
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 Test.dtb; bootz 80800000 - 83000000'
saveenv
boot

1、NFS挂在rootfs

  uboot 里面的 bootargs 环境变量会设置“root”的值,所以我们将 root 的值改为 NFS 挂载。格式如下:

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

  < server-ip>:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP地址,比如我的 Ubuntu 主机 IP 地址为192.168.1.250。
  < root-dir>: 根文件系统的存放路径,比如我的就是/home/nfs/rootfs。
  < nfs-options>: NFS 的其他可选选项,一般不设置。
  < client-ip>: 客户端 IP 地址,也就是我们开发板的 IP 地址, Linux 内核启动以后就会使用此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设备使用,在 Ubuntu 中使用 ping 命令 ping 一下就知道要设置的 IP 地址有没有被使用,如果不能ping 通就说明没有被使用,那么就可以设置为开发板的 IP 地址,比如我就可以设192.168.1.251。
  < server-ip>: 服务器 IP 地址,前面已经说了。
  < gw-ip>: 网关地址,我的就是 192.168.1.1。
  < netmask>:子网掩码,我的就是 255.255.255.0。
  < hostname>:客户机的名字,一般不设置,此值可以空着。
  < device>: 设备名,也就是网卡名,一般是 eth0, eth1….
  < autoconf>: 自动配置,一般不使用,所以设置为 off。
  < dns0-ip>: DNS0 服务器 IP 地址,不使用。
  < dns1-ip>: DNS1 服务器 IP 地址,不使用。
  另外:“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。

2、网络下载镜像文件 zImage 和设备树文件

  从网络下载可以使用tftp 命令或 nfs 命令

1、tftp 命令

  tftp 命令是用于通过网络下载东西到 DRAM 中,tftp 命令使用的 TFTP 协议。uboot 中的 tftp 命令格式如下:

tftpboot [loadAddress] [[hostIPaddr:]bootfilename]

  loadAddress 是 文 件 在 DRAM 中 的存 放 地 址 ,
[[hostIPaddr:]bootfilename]是要从 Ubuntu 中下载的文件。但是 tftp 命令不需要输入文件在 Ubuntu 中的完整路径,只需要输入文件名即可。比如我们现在将 tftpboot 文件夹里面的 zImage 文件下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
  tftp 80800000 zImage

2、nfs 命令

  nfs(Network File System)网络文件系统,通过 nfs 可以在计算机之间通过网络来分享资源,比如我们将 linux 镜像和设备树文件放到 Ubuntu 中,然后在 uboot 中使用 nfs 命令将 Ubuntu 中的 linux 镜像和设备树下载到开发板的 DRAM 中。这样做的目的是为了方便调试 linux 镜像和设备树,也就是网络调试,通过网络调试是 Linux 开发中最常用的调试方法。原因是嵌入式 linux开发不像单片机开发,可以直接通过 JLINK 或 STLink 等仿真器将代码直接烧写到单片机内部的 flash 中,嵌入式 Linux 通常是烧写到 EMMC、 NAND Flash、 SPI Flash 等外置 flash 中,但是嵌入式 Linux 开发也没有 MDK, IAR 这样的 IDE,更没有烧写算法,因此不可能通过点击一个“download”按钮就将固件烧写到外部 flash 中。虽然半导体厂商一般都会提供一个烧写固件的软件,但是这个软件使用起来比较复杂,这个烧写软件一般用于量产的。其远没有 MDK、 IAR的一键下载方便,在 Linux 内核调试阶段,如果用这个烧写软件的话将会非常浪费时间,而这个时候网络调试的优势就显现出来了,可以通过网络将编译好的 linux 镜像和设备树文件下载到 DRAM 中,然后就可以直接运行。
  我们一般使用 uboot 中的 nfs 命令将 Ubuntu 中的文件下载到开发板的 DRAM 中,在使用之前需要开启 Ubuntu 主机的 NFS 服务,并且要新建一个 NFS 使用的目录,以后所有要通过NFS 访问的文件都需要放到这个 NFS 目录中。uboot 中的 nfs 命令格式如下所示:

nfs [loadAddress] [[hostIPaddr:]bootfilename]

  loadAddress 是要保存的 DRAM 地址, [[hostIPaddr:]bootfilename]是要下载的文件地址。
  例如:使用 nfs 命令来将 zImage 下载到开发板 DRAM 的 0X80800000 地址处,命令如下:
  nfs 80800000 192.168.1.253:/home/nfs/zImage

猜你喜欢

转载自blog.csdn.net/xxxx123041/article/details/119938816