基于AM335X无SD,EMMC的LINUX TFTP,NFS启动记录

**硬件状态:**是以OSD335SM芯片模块,使用将AM335X,DDR3,PMIC,EEPROM在一颗单芯片中的模块产品。板子参考OSD-SM-RED开发板设计。而开发板是参照BegleBoneBlack设计,仅需要更改设备树。Uboot配置可直接参照BBB的Uboot配置,但想在Uboot中使用以太网,PHY地址不一样,需要更改源码中配置。参见:https://octavosystems.com/forums/topic/custom-u-boot-and-kernel-for-custom-board/。linux启动时需要的设备树,也需要更改。相关启动的硬件(EMMC,ARM,ETH0)已在裸机模式下测试通过。
1.UBOOT源码更改编译
2.UBOOT烧写EMMC
3.LINUX网卡PHY修改编译
4.TFTP,NFS环境搭建,UBOOT环境变量配置

1.UBOOT相关源码修改。
源下GIT及PATCH参见BBB编译步骤:https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black。PATCH打完后,源码会在相应部分做修改。
需修改的部分:
Bypass EEPROM检测,默认为BBB的开发板,会调用BBB的配置。
修改源码PHY寄存器部分
编译及启动验证

1.1源码下载及PATCH
Download:
user@localhost:~$
git clone -b v2019.04 https://github.com/u-boot/u-boot --depth=1
cd u-boot/

Patches:
user@localhost:~/u-boot$
wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0002-U-Boot-BeagleBone-Cape-Manager.patch
  
patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
patch -p1 < 0002-U-Boot-BeagleBone-Cape-Manager.patch

1.2 修改Bypass EEPROM检测
BBB的镜像源码需要读取EEPROM中的ID,根据ID配置PMIC,DDR等。如果ID不对,系统无法启动,而且串口不会有调试信息。
https://octavosystems.com/forums/topic/osd3358-boot/#post-4733
https://octavosystems.com/forums/topic/issues-booting-custom-board/#post-4608
https://octavosystems.com/app_notes/osd335x-eeprom-during-boot/
在源码u-boot/board/ti/am335x/board.h中更改如下

	
static inline int board_is_bone_lt(void)
{
        return 1;
}

1.3修改Uboot源码PHY寄存器
BBB的板子PHY使用的是MII接口,PHY地址为0;而我们板子用的是RGMII接口,PHY地址为4。
1. Replace MII initialization at https://github.com/eewiki/u-boot-patches/blob/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch#L300 with https://github.com/eewiki/u-boot-patches/blob/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch#L312
2. Replace PHY address 0x0 with 0x4 at https://github.com/u-boot/u-boot/blob/v2019.04/board/ti/am335x/board.c#L1006 and replace “board_is_evm_sk()” in https://github.com/u-boot/u-boot/blob/v2019.04/board/ti/am335x/board.c#L1002 with “board_is_bone_lt()”
3. Replace “mii1_pin_mux” with “rgmii1_pin_mux” at https://github.com/u-boot/u-boot/blob/v2019.04/board/ti/am335x/mux.c#L399
This is in addition to the PHY address change from 0 to 4 at https://github.com/u-boot/u-boot/blob/v2019.04/board/ti/am335x/board.c#L893
我们不改PATCH文件,直接更改PATCH后的源码。u-boot/board/ti/am335x/board.c修改结果如下:
int board_eth_init(bd_t *bis)函数修改,board_is_bone()分支中替换为RGMII模式

#ifdef CONFIG_DRIVER_TI_CPSW
if (!board_is_pb()) {
	if (board_is_bone() || (board_is_bone_lt() && !board_is_bben()) ||
	    board_is_idk() || board_is_beaglelogic()) {
		//puts("eth0: MII MODE\n");
		//writel(MII_MODE_ENABLE, &cdev->miisel);
		//cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
		//		PHY_INTERFACE_MODE_MII;
		puts("eth0: RGMII MODE\n");
		writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
		cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
				PHY_INTERFACE_MODE_RGMII;
	} else if (board_is_icev2()) {
PHY地址配置修改:	
static struct cpsw_slave_data cpsw_slaves[] = {
	{
		.slave_reg_ofs	= 0x208,
		.sliver_reg_ofs	= 0xd80,
		.phy_addr	= 4,
	},
	{
		.slave_reg_ofs	= 0x308,
		.sliver_reg_ofs	= 0xdc0,
		.phy_addr	= 1,
	},
};
写PHY寄存器的调用处地址修改:	
	miiphy_write(devname, 0x4, AR8051_PHY_DEBUG_ADDR_REG,
				AR8051_DEBUG_RGMII_CLK_DLY_REG);
	miiphy_write(devname, 0x4, AR8051_PHY_DEBUG_DATA_REG,
				AR8051_RGMII_TX_CLK_DLY);

第1532行board_is_evm_sk()替换为board_is_bone_lt():

#define AR8051_PHY_DEBUG_ADDR_REG	0x1d
#define AR8051_PHY_DEBUG_DATA_REG	0x1e
#define AR8051_DEBUG_RGMII_CLK_DLY_REG	0x5
#define AR8051_RGMII_TX_CLK_DLY		0x100

	if (board_is_bone_lt() || board_is_gp_evm() || board_is_bben()) 	{
		const char *devname;
		devname = miiphy_get_current_dev();

		miiphy_write(devname, 0x4, AR8051_PHY_DEBUG_ADDR_REG,
				AR8051_DEBUG_RGMII_CLK_DLY_REG);
		miiphy_write(devname, 0x4, AR8051_PHY_DEBUG_DATA_REG,
				AR8051_RGMII_TX_CLK_DLY);
	}

u-boot/board/ti/am335x/board.c的void enable_board_pin_mux(void)函数修改结果如下:
都改为RGMII模式

else if (board_is_bone_lt()) {
		if (board_is_bben()) {
			/* SanCloud Beaglebone LT Enhanced pinmux */
			configure_module_pin_mux(rgmii1_pin_mux);
		} else {
			/* Beaglebone LT pinmux */
			configure_module_pin_mux(rgmii1_pin_mux);
		}

1.4 uboot编译及启动验证
参照:https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black编译。从SPL目录下得到uboot-spl.bin,uboot目录下得到uboot.img。
Das U-Boot – the Universal Boot Loader: http://www.denx.de/wiki/U-Boot
eewiki.net patch archive: https://github.com/eewiki/u-boot-patches

git clone -b v2019.04 https://github.com/u-boot/u-boot --depth=1
cd u-boot/

wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0002-U-Boot-BeagleBone-Cape-Manager.patch
  
patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
patch -p1 < 0002-U-Boot-BeagleBone-Cape-Manager.patch

export CC=`pwd`/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

make ARCH=arm CROSS_COMPILE=${CC} distclean
make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig
make ARCH=arm CROSS_COMPILE=${CC}

由于eMMC白片,无SD卡,选择从串口启动。虚拟机串口工具为secureCRT。波特率:115200。
通过Xmoden协议传送SPL文件,注意不能是MLO文件
通过Ymoden协议,向串口传送u-boot.img文件

uboot命 令行使用mdio list命令查看PHY连接状态。mii命令可调试读取PHY寄存器。有以下信息,表示PHY已读取成功,工作正常。

=> mdio list
cpsw:
4 - AR8035 <--> cpsw
=> mii dump 4 1 
1.     (796d)                 -- PHY status register --
  (8000:0000) 1.15    =     0    100BASE-T4 able
  (4000:4000) 1.14    =     1    100BASE-X  full duplex able
  (2000:2000) 1.13    =     1    100BASE-X  half duplex able
  (1000:1000) 1.12    =     1    10 Mbps    full duplex able
  (0800:0800) 1.11    =     1    10 Mbps    half duplex able
  (0400:0000) 1.10    =     0    100BASE-T2 full duplex able
  (0200:0000) 1. 9    =     0    100BASE-T2 half duplex able
  (0100:0100) 1. 8    =     1    extended status
  (0080:0000) 1. 7    =     0    (reserved)
  (0040:0040) 1. 6    =     1    MF preamble suppression
  (0020:0020) 1. 5    =     1    A/N complete
  (0010:0000) 1. 4    =     0    remote fault
  (0008:0008) 1. 3    =     1    A/N able
  (0004:0004) 1. 2    =     1    link status
  (0002:0000) 1. 1    =     0    jabber detect
  (0001:0001) 1. 0    =     1    extended capabilities


=>

2.Uboot烧写EMMC
通过串口加载 MLO及u-boot.img到指定内存,然后调用mmc指令烧写。用的是RAW模式启动。从128k地址存放MLO启动。而不影响emmc分区表,及EXT4分区。EXT4第一分区从1M地址开始。0地址存放GPT分区表。
https://blog.csdn.net/sinat_33611142/article/details/103999996
http://software-dl.ti.com/processor-sdk-linux/esd/docs/04_03_00_05/linux/Foundational_Components.html#u-boot

UBOOT烧写EMMC命令如下(串口加载到DDR):

mmc dev 1//emmc连接在mmc 1接口,所以切换mmc命令默认设备
loady	//ymodel 加载MLO
mmc write ${loadaddr} 0x100 0x100	//写MLO到128k地址
mmc write ${loadaddr} 0x200 0x100	//写MLO到256k地址备份
loady	//ymodel加载 u-boot.img
mmc write ${loadaddr} 0x300 0x400	//写u-boot.img到394k地址,这些地址不与分区表和EXT4文件系统冲突。

烧完完验证:
命令行输入:reset指令 ,如果UBOOT自动启动,则说明烧写成功。
TI教程里的命令如下:

//TI的示例指令
U-Boot # mmc dev 0
U-Boot # mmc rescan
U-Boot # mmc dev 1
U-Boot # fatload mmc 0 ${loadaddr} MLO
U-Boot # mmc write ${loadaddr} 0x100 0x100
U-Boot # mmc write ${loadaddr} 0x200 0x100
U-Boot # fatload mmc 0 ${loadaddr} u-boot.img
U-Boot # mmc write ${loadaddr} 0x300 0x400
U-Boot # fatload mmc 0 ${loadaddr} rootfs.ext4
U-Boot # mmc write ${loadaddr} 0x1000 ...rootfs.ext4 size in bytes divided by 512, in hex...

3.LINUX网卡PHY修改编译
linux系统中网卡PHY地址,只需要改设备树文件即可。由于按BBB教程中的LINUX编译,到内核源码下载一步,尝试很久,源码都下载断掉。无奈只能使用Ti-PSDK中的源码。找到目录/board-support/linux-4.19.94+gitAUTOINC+be5389fd85-gbe5389fd85/arch/arm/boot/dts中的am335x-boneblack.dts,通过查阅可读,该DTS包含:

#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi"
#include "am335x-boneblack-common.dtsi"

而网卡相关的配置在am335x-bone-common.dtsi中,CPSW的引脚配置由MODE1改为MODE2。修改如下的配置:

&cpsw_emac0 {
	phy_id = <&davinci_mdio>, <4>;
	phy-mode = "rgmii-txid";
};
cpsw_default: cpsw_default {
		pinctrl-single,pins = <
			/* Slave 1 */
			AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxerr.mii1_rxerr */
			AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txen.mii1_txen */
			AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxdv.mii1_rxdv */
			AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd3.mii1_txd3 */
			AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd2.mii1_txd2 */
			AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd1.mii1_txd1 */
			AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd0.mii1_txd0 */
			AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_txclk.mii1_txclk */
			AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxclk.mii1_rxclk */
			AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxd3.mii1_rxd3 */
			AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxd2.mii1_rxd2 */
			AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxd1.mii1_rxd1 */
			AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE2)	/* mii1_rxd0.mii1_rxd0 */
		>;
	};

编译:在PSDK根目录下。执行
make linux_clean
make linux
等待编译结果,从DTS的目录下,把am335x-boneblack.dtb拷贝出来即可。/board-support/linux-4.19.94+gitAUTOINC+be5389fd85-gbe5389fd85/arch/arm/boot/目录中把zImage拷贝出来。

4.TFTP,NFS环境搭建,UBOOT环境变量配置
该步骤包含:
TFTP服务器搭建及文件准备
NFS环境搭建及文件准备
UBOOT环境变量设置
其中TFPT,NFS环境搭建及文件准备,只要运行PSDK目录下的setup.sh自动完成所有的环境搭建。
自己手动搭建参考以下教程:
TFTP服务器配置
NFS服务器配置
BBB板子TFTP启动及NFS挂载教程:https://www.itdaan.com/blog/2014/09/15/13497c4a37725415181b05a5804a4808.html

要使用TFTP启动及NFS挂载,主要涉及UBOOT环境变量配置。本身UBOOT都是支持的。首先分析UBOOT的环境变量。

U-Boot# printenv
arch=arm
autoconf=off
baudrate=115200
board=am335x
board_name=A335BNLT
board_rev=t\
ue
boot_fdt=try
bootcmd=gpio set 53; i2c mw 0x24 1 0x3e; run findfdt; setenv mmcdev 0; setenv bootpart 0:1; run mmcboot;gpio clear 56; gpio clear 55; gpio clear 54; setenv mmcdev 1; setenv bootpart 1:1; run mmcboot;run nandboot;
bootcount=2
bootdelay=1
bootenv=uEnv.txt
bootfile=zImage
bootm_size=0x10000000
bootpart=0:2
bootscript=echo Running bootscript from mmc ...; source ${loadaddr}
console=ttyO0,115200n8
cpu=armv7
device=eth0
dfu_alt_info_emmc=rawemmc mmc 0 3751936
dfu_alt_info_mmc=boot part 0 1;rootfs part 0 2;MLO fat 0 1;MLO.raw mmc 0x100 0x100;u-boot.img.raw mmc 0x300 0x400;spl-os-args.raw mmc 0x80 0x80;spl-os-image.raw mmc 0x900 0x2000;spl-os-args fat 0 1;spl-os-image fat 0 1;u-boot.img fat 0 1;uEnv.txt fat 0 1
dfu_alt_info_nand=SPL part 0 1;SPL.backup1 part 0 2;SPL.backup2 part 0 3;SPL.backup3 part 0 4;u-boot part 0 5;u-boot-spl-os part 0 6;kernel part 0 8;rootfs part 0 9
dfu_alt_info_ram=kernel ram 0x80200000 0xD80000;fdt ram 0x80F80000 0x80000;ramdisk ram 0x81000000 0x4000000
eth1addr=c8:a0:30:ac:7f:d1
ethact=cpsw
ethaddr=c8:a0:30:ac:7f:cf
fdt_addr_r=0x88000000
fdtaddr=0x88000000
fdtdir=/dtbs
fdtfile=undefined
findfdt=if test $board_name = A335BONE; then setenv fdtfile am335x-bone.dtb; setenv fdtbase am335x-bone; fi; if test $board_name = A335BNLT; then setenv fdtfile am335x-boneblack.dtb; setenv fdtbase am335x-boneblack; fi; if test $board_name = A33515BB; then setenv fdtfile am335x-evm.dtb; fi; if test $board_name = A335X_SK; then setenv fdtfile am335x-evmsk.dtb; fi; if test $fdtfile = undefined; then echo WARNING: Could not determine device tree to use; fi; 
gw_ip=192.168.1.1
importbootenv=echo Importing environment from mmc ...; env import -t -r $loadaddr $filesize
kernel_addr_r=0x82000000
loadaddr=0x82000000
loadbootenv=load mmc ${bootpart} ${loadaddr} ${bootenv}
loadbootscript=load mmc ${bootpart} ${loadaddr} ${scriptfile};
loadfdt=echo loading ${fdtdir}/${fdtfile} ...; load mmc ${bootpart} ${fdtaddr} ${fdtdir}/${fdtfile}
loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
loadramdisk=load mmc ${mmcdev} ${rdaddr} ramdisk.gz
loadrd=load mmc ${bootpart} ${rdaddr} ${bootdir}/${rdfile}; setenv rdsize ${filesize}
mmcargs=setenv bootargs console=${console} ${optargs} ${cape_disable} ${cape_enable} root=${mmcroot} rootfstype=${mmcrootfstype} ${cmdline}
mmcboot=mmc dev ${mmcdev}; if mmc rescan; then gpio set 54;echo SD/MMC found on device ${mmcdev};setenv bootpart ${mmcdev}:1; echo Checking for: /uEnv.txt ...;if test -e mmc ${bootpart} /uEnv.txt; then if run loadbootenv; then gpio set 55;echo Loaded environment from ${bootenv};run importbootenv;fi;if test -n ${cape}; then if test -e mmc ${bootpart} ${fdtdir}/${fdtbase}-${cape}.dtb; then setenv fdtfile ${fdtbase}-${cape}.dtb; fi; echo using: $fdtfile...; fi; echo Checking if uenvcmd is set ...;if test -n ${uenvcmd}; then gpio set 56; echo Running uenvcmd ...;run uenvcmd;fi;echo Checking if client_ip is set ...;if test -n ${client_ip}; then if test -n ${dtb}; then setenv fdtfile ${dtb};echo using ${fdtfile} ...;fi;gpio set 56; echo Running nfsboot ...;run nfsboot;fi;fi; echo Checking for: /${script} ...;if test -e mmc ${bootpart} /${script}; then gpio set 55;setenv scriptfile ${script};run loadbootscript;echo Loaded script from ${scriptfile};gpio set 56; run bootscript;fi; echo Checking for: /boot/${script} ...;if test -e mmc ${bootpart} /boot/${script}; then gpio set 55;setenv scriptfile /boot/${script};run loadbootscript;echo Loaded script from ${scriptfile};gpio set 56; run bootscript;fi; echo Checking for: /boot/uEnv.txt ...;for i in 1 2 3 4 5 6 7 ; do setenv mmcpart ${i};setenv bootpart ${mmcdev}:${mmcpart};if test -e mmc ${bootpart} /boot/uEnv.txt; then gpio set 55;load mmc ${bootpart} ${loadaddr} /boot/uEnv.txt;env import -t ${loadaddr} ${filesize};echo Loaded environment from /boot/uEnv.txt;if test -n ${dtb}; then setenv fdtfile ${dtb};echo Using: dtb=${fdtfile} ...;fi;echo Checking if uname_r is set in /boot/uEnv.txt...;if test -n ${uname_r}; then gpio set 56; echo Running uname_boot ...;setenv mmcroot /dev/mmcblk${mmcdev}p${mmcpart} ro;run uname_boot;fi;fi;done;fi;
mmcdev=0
mmcloados=run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcpart=1
mmcroot=/dev/mmcblk0p2 ro
mmcrootfstype=ext4 rootwait fixrtc
mtdids=nand0=omap2-nand.0
mtdparts=mtdparts=omap2-nand.0:128k(SPL),128k(SPL.backup1),128k(SPL.backup2),128k(SPL.backup3),1792k(u-boot),128k(u-boot-spl-os),128k(u-boot-env),5m(kernel),-(rootfs)
nandargs=setenv bootargs console=${console} ${optargs} root=${nandroot} rootfstype=${nandrootfstype}
nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} u-boot-spl-os; nand read ${loadaddr} kernel; bootz ${loadaddr} - ${fdtaddr}
nandroot=ubi0:rootfs rw ubi.mtd=7,2048
nandrootfstype=ubifs rootwait=1
netargs=setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=dhcp
netboot=echo Booting from network ...; setenv autoload no; dhcp; tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} ${fdtfile}; run netargs; bootz ${loadaddr} - ${fdtaddr}
netmask=255.255.255.0
nfs_options=,vers=3
nfsargs=setenv bootargs console=${console} ${optargs} ${cape_disable} ${cape_enable} root=/dev/nfs rw rootfstype=${nfsrootfstype} nfsroot=${nfsroot} ip=${ip} ${cmdline}
nfsboot=echo Booting from ${server_ip} ...; setenv nfsroot ${server_ip}:${root_dir}${nfs_options}; setenv ip ${client_ip}:${server_ip}:${gw_ip}:${netmask}:${hostname}:${device}:${autoconf}; setenv autoload no; setenv serverip ${server_ip}; setenv ipaddr ${client_ip}; tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} dtbs/${fdtfile}; run nfsargs; bootz ${loadaddr} - ${fdtaddr}
nfsopts=nolock
nfsrootfstype=ext4 rootwait fixrtc
partitions=uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
ramargs=setenv bootargs console=${console} ${optargs} root=${ramroot} rootfstype=${ramrootfstype}
ramboot=echo Booting from ramdisk ...; run ramargs; bootz ${loadaddr} ${rdaddr} ${fdtaddr}
ramdisk_addr_r=0x88080000
ramroot=/dev/ram0 rw
ramrootfstype=ext2
rdaddr=0x88080000
root_dir=/home/userid/targetNFS
rootpath=/export/rootfs
script=boot.scr
scriptfile=${script}
server_ip=192.168.1.100
soc=am33xx
spiargs=setenv bootargs console=${console} ${optargs} root=${spiroot} rootfstype=${spirootfstype}
spiboot=echo Booting from spi ...; run spiargs; sf probe ${spibusno}:0; sf read ${loadaddr} ${spisrcaddr} ${spiimgsize}; bootz ${loadaddr}
spibusno=0
spiimgsize=0x362000
spiroot=/dev/mtdblock4 rw
spirootfstype=jffs2
spisrcaddr=0xe0000
static_ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off
stderr=serial
stdin=serial
stdout=serial
uname_boot=setenv bootdir /boot; setenv bootfile vmlinuz-${uname_r}; if test -e mmc ${bootpart} ${bootdir}/${bootfile}; then echo loading ${bootdir}/${bootfile} ...; run loadimage;setenv fdtdir /boot/dtbs/${uname_r}; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /usr/lib/linux-image-${uname_r}; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /lib/firmware/${uname_r}/device-tree; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /boot/dtb-${uname_r}; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /boot/dtbs; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /boot/dtb; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else setenv fdtdir /boot; if test -e mmc ${bootpart} ${fdtdir}/${fdtfile}; then run loadfdt;else echo; echo unable to find ${fdtfile} ...; echo booting legacy ...;run mmcargs;bootz ${loadaddr}; fi;fi;fi;fi;fi;fi;fi; setenv rdfile initrd.img-${uname_r}; if test -e mmc ${bootpart} ${bootdir}/${rdfile}; then echo loading ${bootdir}/${rdfile} ...; run loadrd;if test -n ${uuid}; then setenv mmcroot UUID=${uuid} ro;fi;run mmcargs;bootz ${loadaddr} ${rdaddr}:${rdsize} ${fdtaddr}; else run mmcargs;bootz ${loadaddr} - ${fdtaddr}; fi;fi;
usbnet_devaddr=c8:a0:30:ac:7f:d1
vendor=ti
ver=U-Boot 2014.07-00016-g329fca9 (Jul 28 2014 - 12:35:02)

Environment size: 8541/131068 bytes

既然是研究如何将网络文件系统NFS挂载为根文件系统,那么把其中59-63行的环境变量摘取出来进行分析,为了便于阅读和分析,整理成如下格式:

#定义变量nfs_options的值为,vers=3
nfs_options=,vers=3

#定义变量nfsargs为一个动作,该动作设置bootargs启动参数内容包括
#(1)console:用于让内核打印输出信息,Documentation/serial-console.txt找到相关描述
#(2)root:用于说明根文件系统是基于NFS。
#(3)rootfstype:指定根文件系统类型,此处指定的是ext4
#(4)nfsroot:指定根文件系统所在NFS服务器的IP以及服务器上的路径
#(5)ip:本目标板IP(必须的,其他可不写)、TFTP和NFS服务器IP、网关IP、子网掩码、主机名、网卡设备、

nfsargs=
setenv bootargs console=${console} ${optargs} ${cape_disable} ${cape_enable} 
                root=/dev/nfs rw 
                rootfstype=${nfsrootfstype} 
                nfsroot=${nfsroot} 
                ip=${ip} ${cmdline}

#定义变量nfsboot为一系列动作,动作之间以;隔开
nfsboot=
echo Booting from ${server_ip} ...; //回显信息“从服务器IP处启动系统...”
setenv nfsroot ${server_ip}:${root_dir}${nfs_options}; //指定根文件系统所在NFS服务器的IP以及服务器上的路径
setenv ip ${client_ip}:${server_ip}:${gw_ip}:${netmask}:${hostname}:${device}:${autoconf}; //设定IP
setenv autoload no; //仅仅对相关配置进行查询(比如本机被分配到的IP地址),而不会同时产生去通过TFTP下载任何镜像的动作。
setenv serverip ${server_ip};//设置TFTP和NFS服务器IP地址,两个服务器可以在配置同一台电脑上,一般属于这种情况,但也可以配置在不同的电脑上。 
setenv ipaddr ${client_ip};//本机目标板地址 
tftp ${loadaddr} ${bootfile}; //从TFTP服务器的目录中下载bootfile文件放到内存loadaddr处
tftp ${fdtaddr} dtbs/${fdtfile}; //从TFTP服务器的dtbs/目录下载fdtfile文件,存放到内存的fdtaddr处
run nfsargs; //执行nfsargs定义的一系列动作,解释见上。
bootz ${loadaddr} - ${fdtaddr}//bootz表示执行内存中的zImage文件,后面跟三个参数,第一个参数表示内核在内存中的地址,第二个参数表示initrd的地址,如果没有initrd就用"-"表示,第三个表示设备树二进制文件内存地址

#定义变量nfsopts的值为nolock
nfsopts=nolock

#定义变量nfsrootfstype的值为ext4 rootwait fixrtc
nfsrootfstype=ext4 rootwait fixrtc
从以上环境变量可以得出,这几个变量均是为了nfsboot而服务的,也就是说进入u-boot命令行后,我们输入run nfsboot,那么nfsboot里面的动作(回显信息、设置环境变量、下载内核镜像、设备树二进制文件、设置启动参数、执行镜像文件)全部都会被执行。那么系统也就自动开始启动了。


        为了确保所有相关的环境变量都是正确无误的,现在u-boot下面从nfsboot入手把各个尚未知的环境变量依次打印出来,查看一下情况如何,得到结果如下,

----------------------------------------------------------------------------------------------------------------------------------------------------------

U-Boot# printenv server_ip root_dir client_ip gw_ip netmask hostname device autoconf loadaddr bootfile fdtaddr fdtfile
server_ip=192.168.1.100                //实际中我的TFTP、NFS服务器都在虚拟机中,虚拟机IP192.168.1.106
root_dir=/home/userid/targetNFS     //NFS服务器的目录为/home/username/zynfs/
## Error: "client_ip" not defined      //目标板连接在同一个局域网中,获得的IP为192.168.1.105
gw_ip=192.168.1.1                        //路由器IP为192.168.1.1,故此项无需在设置
netmask=255.255.255.0                 //子网掩码也正确,故此项无需在设置
## Error: "hostname" not defined    //主机名无需设置留空即可
device=eth0                                 //u-boot默认已经设置好,设置为目标板系统的第一块以太网网卡,故此项无需设置
autoconf=off                                //保留默认设置,故此项无需设置
loadaddr=0x82000000                   //保留默认设置,故此项无需设置
bootfile=zImage                           //保留默认设置,故此项无需设置,如果想用其他名字自己,记得到时候TFTP服务器目录下的文件名与此保持一致,否则会找不到内核
fdtaddr=0x88000000                     //保留默认设置,故此项无需设置
fdtfile=undefined                         //u-boot没有设置,需要手动设置,可以先运行run findfdt,该命令读取板子信息,根据板子信息自动设置好fdtfile。如何读取的请printenv findfdt

根据以上教程信息,我们配置自己板子的环境变量如下:

setenv serverip 192.168.1.122
setenv server_ip 192.168.1.122
setenv gw_ip 192.168.1.1
setenv client_ip 192.168.1.2
setenv root_dir /home/ping58/ti/ti-processor-sdk-linux-am335x-evm-06.03.00.106/targetNFS/
setenv fdtfile am335x-boneblack.dtb


printenv server_ip client_ip root_dir fdtfile

确认环境变量OK后,命令行执行:run nfsboot自动加载内核启动,并挂载文件系统。
插由,如果加截内核后,未提示错误,但无其他任何提示信息。可能是因为环境变量配置错误,linux内核启动,控制台配置错误导致。如下配置:
setenv console /dev/ttyS0,115200n8

其他参考链接:
https://www.itdaan.com/blog/2014/09/17/37e841b03f3b.html
https://www.itdaan.com/blog/2017/05/12/46fee3d687da8fbc7b32230e34c06f2b.html
https://www.itdaan.com/blog/2017/08/01/18d2dad637f8.html
https://www.itdaan.com/keywords/Beaglebone+Black+%E7%90%86%E8%AE%BA%E7%AF%87beaglebone+black%E5%90%AF%E5%8A%A8+%E4%BB%8E%E4%B8%B2%E5%8F%A3%E8%8E%B7%E5%BE%97SPL+U+BOOT+TFTP%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%8E%B7%E5%BE%97%E5%86%85%E6%A0%B8+NFS%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8C%82%E8%BD%BD%E6%A0%B9%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F.html

https://www.itdaan.com/blog/2014/09/15/13497c4a37725415181b05a5804a4808.html
USB启动文件系统制作:https://octavosystems.com/app_notes/programming-emmc-with-usb/
挂载RAMDISK:http://blog.chinaunix.net/uid-27134408-id-5059318.html
TFTP,NFS环境搭建:https://www.linuxidc.com/Linux/2016-12/137871.htm
BBB UBOOT,LINUX编译:https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值