你好,游客 登录 注册 搜索
背景:
阅读新闻

tftp-nfs开发环境搭建 uboot环境变量设置

[日期:2016-12-04] 来源:Linux社区  作者:xiaojiang1025 [字体: ]

嵌入式开发通常使用主机-开发板的开发模式,在裸板开发中,我们通常使用串口调试工具传递文件,比如windows平台的超级终端,SecuCRT以及Linux平台的ckermit(题外话:ckermit比windows的那两个快多了)。但在OS的开发环境中,由于程序复杂,规模巨大,串口的低速和易错就不再适合我们开发了,而在这种环境下,基于网络的开发环境由于高速和准确受到了大家的青睐。

结构说明

在有OS的嵌入式系统中,SoC的启动过程有3个加载。

  1. 上电的第一个程序就是片上固化的启动代码,它负责把bootloader从Flash中加载到内存中并执行
  2. bootloader会从Flash中加载Linux内核以及设备树文件到内存,并对两者进行相关的配置。完成所有工作后跳转到内核的首地址
  3. 内核接管bootloader配置好的硬件资源,内核启动过程中非常重要的一件事就是挂载文件系统。

在开发过程中,由于bootloader通常都具有网络功能,而linux内核,设备树dts和文件系统fs都是不断迭代的,所以我们自然希望通过配置bootloader的网络功能使其直接通过服务器(开发主机)下载内核并进一步下载设备树文件(tftp),甚至直接挂接网络上的文件系统(nfs)。整个开发环境的结构框图如下:

tftp的安装和配置

tftp即tiny ftp,是一种轻型的ftp协议,Ubuntu下可以使用下面这个小脚本安装并配置。

#!/bin/bash
echo "Please input tftpdir"
read tftpdir
sudo mkdir $tftpdir        #创建用于传输文件的目录
sudo chmod 0777 $tftpdir
sudo apt-get install tftp-hpa tftpd-hpa xinetd -y
#sudo vi /etc/default/tftp-hpa
sudo touch /etc/default/tftpd-hpa
sudo chmod 0777 /etc/default/tftpd-hpa
sudo echo "TFTP_USERNAME=\"tftp\"" > /etc/default/tftpd-hpa
sudo echo "TFTP_DIRECTORY=\"$tftpdir\"" >> /etc/default/tftpd-hpa   #tftpd-hpa的服务目录,这个想建立在哪里都行
sudo echo "TFTP_ADDRESS=\"0.0.0.0:69\""     >> /etc/default/tftpd-hpa   #指定开发板地址,需要和主机的ip在同一个网段     
sudo echo "TFTP_OPTIONS=\"-l -c -s\""       >> /etc/default/tftpd-hpa   #-c是可以上传文件的参数,-s是指定tftpd-hpa服务目录,上面已指定

sudo service tftpd-hpa restart
echo -e '\n'

nfs的安装和配置

nfs即network filesystem,可以使客户端直接从服务器挂接文件系统,方便开发板直接访问我们的程序或文件。nfs的安装和配置脚本

#!/bin/bash
echo "nfs service"
echo "Please input nfs dir"
read nfsdir
sudo mkdir $nfsdir
sudo apt-get install nfs-kernel-server nfs-common portmap -y
#sudo vi /etc/exports
sudo touch /etc/exports
sudo chmod 0777 /etc/exports
sudo echo "$nfsdir  *(rw,sync,no_subtree_check,no_root_squash)" > /etc/exports
sudo service nfs-kernel-server restart
echo -e '\n'

export文件的属性选项

ro      只读访问
rw      读写访问
sync    所有数据在请求时写入共享
async   nfs在写入数据前可以响应请求
secure  nfs通过1024以下的安全TCP/IP端口发送
insecure    nfs通过1024以上的端口发送
wdelay      如果多个用户要写入nfs目录,则归组写入(默认)
no_wdelay   如果多个用户要写入nfs目录,则立即写入,当使用async时,无需此设置
hide        在nfs共享目录中不共享其子目录
no_hide     共享nfs目录的子目录
subtree_check   如果共享/usr/bin之类的子目录时,强制nfs检查父目录的权限(默认)
no_subtree_check    不检查父目录权限
all_squash      共享文件的UID和GID映射匿名用户anonymous,适合公用目录
no_all_squash   保留共享文件的UID和GID(默认)
root_squash     用户的所有请求映射成如anonymous用户一样的权限(默认)
no_root_squash  root用户具有根目录的完全管理访问权限
anonuid=xxx     指定nfs服务器/etc/passwd文件中匿名用户的UID
anongid=xxx     指定nfs服务器/etc/passwd文件中匿名用户的GID

安装完毕可以使用下面的命令测试一下

$sudo mount -t nfs localhost:/home/jiang/nfs /mnt/  #localhost后面接的是nfs共享目录
$ls /mnt/
1.txt       #如果能看到nfs里面的1.txt就表示挂接成功了,nfs服务器没有问题
$sudo unmount /mnt/

uboot环境配置

通过配置uboot让它在启动过程中从tftp获取内核和设备树,并从在加载内核之后把通过启动参数将"从nfs挂载根文件系统"传入内核。这个配置主要是通过uboot内建的"set 变量名 变量值+save"设置环境变量的方式进行配置,下面是我采用的uboot的环境变量,下面是我用的环境变量设置:

#pri                    #即printenv  
baudrate=115200
bootargs=root=/dev/nfs nfsroot=192.168.0.50:/nfs rw console=ttySAC2,115200n8 init=/linuxrc ip=192.168.0.55 loglevel=7 clk_ignore_unused
bootcmd=tftp 41000000 uImage;tftp 42000000 exynos4412-origen.dtb;bootm 41000000 - 42000000
bootdelay=4
ethact=dm9000
ethaddr=11:22:33:44:55:66
fileaddr=41000000
filesize=26D213
gatewayip=192.168.2.1
ipaddr=192.168.0.55
netmask=255.255.255.0
serverip=192.168.0.50
stderr=serial
stdin=serial
stdout=serial

baudrate就是波特率,习惯上就设成115200,根据硬件的不同可以相应的修改

bootargs启动参数,这个参数除了uboot要用,启动内核之后还会传入内核。
其中,root=/dev/nfs表示开发板的根文件系统从nfs网络设备中加载,nfsroot=192.168.0.55:/nfs表示从网络中的ip是192.168.0.55的主机中的/nfs目录加载根文件系统,rw表示可读可写,console=ttySAC2表示使用的中端,115200表示波特率,init=/linuxrc表示启动的祖先进程的位置,显然这是给linux内核用的,ip=192.168.0.55是开发板的ip,需要和主机在同一个网段,loglevel=7就是登录等级,这个不设也行,clk_ignore_unused忽略时钟。这个参数的实质是uboot传入内核的,所以需要参考内核的启动参数的相关文件,我在下面做了简要的说明。除了启动参数,uboot还需要做一些其他的准备工作,并不是这个参数准备好了内核就可以工作了,比如,关于arm平台的linux内核启动条件,可以参考Linux内核源码中的Documentation/arm/Booting ,这里就不做说明了
bootcmd启动命令,tftp 41000000 uImage表示从tftp网络中下载uImage内核镜像到41000000地址处,tftp 42000000 exynos4412-origen.dtb表示下载从tftp网络中下载设备树文件到42000000地址处,bootm 41000000 - 42000000表示从41000000启动内核,我这没有randisk,用-代替,不是从41000000到42000000的意思!!!此外,一旦填入了ramdisk地址,内核就会从ramdisk挂载根文件系统而忽略nfs。最后,把设备树从42000000传入内核。
注意:多个命令之间用;分隔,所以为了在设置变量的时候不立即执行,应该写成set bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-origen.dtb\;bootm 41000000 - 42000000

bootdelay启动倒计时的秒数

gatewayip表示网关

ipaddr表示开发板的ip

serverip表示主机的ip

netmask表示子网掩码

stderrstdinstdout表示标准输入输出错误设备,基本都填串口serial

Linux内核启动参数

内核需要的启动参��在linux-4.8.5/Documentation/kernel-parameters.txt以及相应的文件中,这些参数就是uboot需要通过bootargs将他们准备好并传给内核,当然,这些参数都是有缺省值的,我们只需要对需要的参数进行配置,这里列出这里用到的几个

noinitrd    [RAM] Tells the kernel not to load any configured
            initial RAM disk.
            
root=       [KNL] Root filesystem
            See name_to_dev_t comment in init/do_mounts.c.

nfsroot=    [NFS] nfs root filesystem for disk-less boxes.
            See Documentation/filesystems/nfs/nfsroot.txt.

rw          [KNL] Mount root device read-write on boot

rootwait    [KNL] Wait (indefinitely) for root device to show up.
            Useful for devices that are detected asynchronously
            (e.g. USB and MMC devices).

ip=         [IP_PNP]
            See Documentation/filesystems/nfs/nfsroot.txt.

console=    [KNL] Output console device and options.
        。。。

init=       [KNL]
            Format: <full_path>
            Run specified binary instead of /sbin/init as init
            process.

loglevel=   All Kernel Messages with a loglevel smaller than the
            console loglevel will be printed to the console. 
            。。。
            
clk_ignore_unused
            [CLK]
            Prevents the clock framework from automatically gating
            clocks that have not been explicitly enabled by a Linux
            device driver but are enabled in hardware at reset or
            by the bootloader/firmware. 
            。。。
$grep ip=  Documentation/filesystems/nfs/nfsroot.txt -A 20
ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>

  This parameter tells the kernel how to configure IP addresses of devices and also how to set up the IP routing table. It was originally called 'nfsaddrs', but now the boot-time IP configuration works independently of NFS, so it was renamed to 'ip' and the old name remained as an alias for compatibility reasons.
。。。。
$grep nfsroot=  Documentation/filesystems/nfs/nfsroot.txt -A 20
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]

  If the 'nfsroot' parameter is NOT given on the command line,
  the default "/tftpboot/%s" will be used.
 。。。

搭建开发环境的细节很多,如有纰漏欢迎批评^-^交流

本文永久更新链接地址http://www.linuxidc.com/Linux/2016-12/137871.htm

linux
相关资讯       uboot环境变量  tftp-nfs 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款