背景
在开发自己项目的时候,需要针对自己的板子进行相关的移植工作。在完成初步的U-boot移植后,发现U-boot无法ping通host主机。
移植方法是参考的正点原子教程。会不会是因为硬件不一致导致的?如前面文中提到的,板载使用的是KSZ9031,并不是官方开发板使用的型号。
移植过程
整个的移植过程,其实按照正点原子的来不会有一点问题!说一下在这过程中遇到的问题,方便后续查阅。
一开始我有个疑问:zynq的Linux开发可以借助petalinux工具,可以说这个工具配置配置就可以,为什么还要自己手动移植?到目前为止,我只能理解到,自己移植可以加深对整个Linux以及U-boot的工作细节的理解。
就比如在petalinux中的petalinux-build
一句话就可以完成编译,如果不使用petalinux工具呢?就要使用make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
这样的编译命令。看到这个命令,你就要理解何为架构?何为交叉编译工具链?诸如此类。
再来熟悉一下三剑客:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- atk_7020_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
如果你不想每次都要搞这么复杂,输入这么长命令,那就要了解下“shell
”,即脚本。把以上命令写到一个脚本里面,那么每次就只要执行一次脚本就可以顺序执行上述三条命令。
执行完上述脚本,就会自动编译完成U-boot。
接下来是运行测试环节了,正常运行应该是使用SD卡进行启动,但是这样太费事了,所以就有了JTAG启动U-boot的方式。
xsct uboot.tcl
使用上述命令进行烧录,uboot.tcl这个文件是需要自己实现的,如下
connect
source hw-description/ps7_init.tcl
targets -set -filter {name =~"APU"}
loadhw hw-description/system.hdf
stop
ps7_init
targets -set -nocase -filter {name =~ "ARM*#0"}
rst -processor
dow u-boot
con
这个文件主要实现的连接仿真器,PS端初始化,U-boot烧录。当然,后面移植了Linux内核的时候还可以修改成烧录Linux Kernel。执行烧录命令后,如果报错,大概率是仿真器没有连上,就要考虑驱动什么的是不是装好了。
连不上JTAG信息如下
如果没什么问题,U-boot就会通过JTAG烧录好,对应的终端会打印U-boot的运行信息。
U-Boot 2018.01 (May 14 2024 - 11:21:19 +0800) Xilinx Zynq JYTLModel: Zynq JYTL Development Board
Board: Xilinx Zynq
Silicon: v3.1
I2C: ready
DRAM: ECC disabled 1 GiB
MMC: sdhci@e0100000: 0 (SD)
SF: Detected w25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
*** Warning - bad CRC, using default environmentIn: serial@e0001000
Out: serial@e0001000
Err: serial@e0001000
Net: ZYNQ GEM: e000b000, phyaddr 0, interface rgmii-id
we are now in phy_detection!
priv->phyaddr top is:0.
phy reg is 65535
PHY address is not setup correctly 0
phy_addr is:3!
eth0: ethernet@e000b000
Hit any key to stop autoboot: 0 //倒计时
相信这部分大家比较熟悉吧,U-boot就启动起来了,在倒计时结束前按会车,就进入U-boot的命令模式。
那么移植过程就算完成了。这里并没有详细的写U-boot的移植过程,有机会另开篇吧。
启动Linux内核
然后执行下面的命令
run netboot
这个命令是从网络启动Linux Kernel。因为我这里已经配置好了用网络的方式启动内核,并且把image.ub
放到对应的tftpboot
文件夹下下面了。执行完这句应该就会将tftpboot目录下的内核文件烧录到板子上,当然这里只是调试模式,掉电还是丢失的。执行这句命令后打印如下信息
Using ethernet@e000b000 device
TFTP from server 192.168.1.18; our IP address is 192.168.1.10
Filename 'image.ub'.
Load address: 0x2080000
Loading: *
ARP Retry count exceeded; starting again
可以看到,主机IP和板子的IP都是有的,但是不通,烧录执行失败。
执行ping
命令同样失败!!在这里脑子没转过弯,我是从板子ping ubuntu主机的,也从ubuntu主机ping板子,双向都不通。然后开始研究U-boot中的网络初始化这部分,搞了很久,未果。
然后我把板子烧录了一个已经投产的程序,确定是可以连接网络的,从ubuntu主机ping板子,还是不通。从windows主机ping板子是可以正常通的。那么问题就定位到了,就是ubuntu主机中的网络设置有问题了。
于是开始找ubuntu网络的设置,各种设置主机IP什么的,就是没用
然后找到了一个设置方法;按下图配置
在虚拟网络编辑器这里,如果第3步是灰色的没法选择,那就要点击后面的更改设置
使用管理员权限修改。按照上图更改完成后整个就通上了。这样说U-boot支持的驱动型号是真多啊。
Zynq> ping 192.168.1.18
we are now in zynq_gem_init!
phy detection again.
we are now in phy_detection!
priv->phyaddr top is:3.
phy reg is 31085
default phy address 3 is valid
Using ethernet@e000b000 device
host 192.168.1.18 is alive
当U-boot运行起来后,执行Ping命令,我这里增加了一个打印信息,可以看到,当执行某些网络的命令后,系统会进入zynq_gem_init
这个函数,去初始化网络以及phy。
网络通了后,接下来就可以使用网络启动Linux的方式来加载Linux了。
Zynq> run netboot
we are now in zynq_gem_init!
phy detection again.
we are now in phy_detection!
priv->phyaddr top is:3.
phy reg is 31085
default phy address 3 is valid
Using ethernet@e000b000 device
TFTP from server 192.168.1.18; our IP address is 192.168.1.10
Filename 'image.ub'.
Load address: 0x2080000
Loading: #########################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################2.3 MiB/s
done
Bytes transferred = 9985408 (985d80 hex)
## Loading kernel from FIT Image at 02080000 ...Using 'conf@system-top.dtb' configurationVerifying Hash Integrity ... OKTrying 'kernel@1' kernel subimageDescription: Linux kernelType: Kernel ImageCompression: gzip compressedData Start: 0x02080104Data Size: 3941038 Bytes = 3.8 MiBArchitecture: ARMOS: LinuxLoad Address: 0x00008000Entry Point: 0x00008000Hash algo: sha1Hash value: 159c85fff7741c8eb676474142e2a91c17c56695Verifying Hash Integrity ... sha1+ OK
## Loading ramdisk from FIT Image at 02080000 ...Using 'conf@system-top.dtb' configurationTrying 'ramdisk@1' ramdisk subimageDescription: petalinux-user-imageType: RAMDisk ImageCompression: gzip compressedData Start: 0x02445c3cData Size: 6028213 Bytes = 5.7 MiBArchitecture: ARMOS: LinuxLoad Address: unavailableEntry Point: unavailableHash algo: sha1Hash value: f96aa63e33de959042e47c5dd4768a3b592ddf6cVerifying Hash Integrity ... sha1+ OK
## Loading fdt from FIT Image at 02080000 ...Using 'conf@system-top.dtb' configurationTrying 'fdt@system-top.dtb' fdt subimageDescription: Flattened Device Tree blobType: Flat Device TreeCompression: uncompressedData Start: 0x024424b4Data Size: 14022 Bytes = 13.7 KiBArchitecture: ARMHash algo: sha1Hash value: fa2006ae42176645309c6c9752496f2ee5e080d7Verifying Hash Integrity ... sha1+ OKBooting using the fdt blob at 0x24424b4Uncompressing Kernel Image ... OKLoading Ramdisk to 1fa40000, end 1ffffbb5 ... OKLoading Device Tree to 1fa39000, end 1fa3f6c5 ... OKStarting kernel ...
一直到starting kernel这里,就已经成功从ubuntu中通过网络拿到内核镜像了。下面就是启动内核的内容了。