背景
在开发自己项目的时候,需要针对自己的板子进行相关的移植工作。在完成初步的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 JYTL
Model: 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 environment
In: 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' configuration
Verifying Hash Integrity ... OK
Trying 'kernel@1' kernel subimage
Description: Linux kernel
Type: Kernel Image
Compression: gzip compressed
Data Start: 0x02080104
Data Size: 3941038 Bytes = 3.8 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00008000
Entry Point: 0x00008000
Hash algo: sha1
Hash value: 159c85fff7741c8eb676474142e2a91c17c56695
Verifying Hash Integrity ... sha1+ OK
## Loading ramdisk from FIT Image at 02080000 ...
Using 'conf@system-top.dtb' configuration
Trying 'ramdisk@1' ramdisk subimage
Description: petalinux-user-image
Type: RAMDisk Image
Compression: gzip compressed
Data Start: 0x02445c3c
Data Size: 6028213 Bytes = 5.7 MiB
Architecture: ARM
OS: Linux
Load Address: unavailable
Entry Point: unavailable
Hash algo: sha1
Hash value: f96aa63e33de959042e47c5dd4768a3b592ddf6c
Verifying Hash Integrity ... sha1+ OK
## Loading fdt from FIT Image at 02080000 ...
Using 'conf@system-top.dtb' configuration
Trying 'fdt@system-top.dtb' fdt subimage
Description: Flattened Device Tree blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x024424b4
Data Size: 14022 Bytes = 13.7 KiB
Architecture: ARM
Hash algo: sha1
Hash value: fa2006ae42176645309c6c9752496f2ee5e080d7
Verifying Hash Integrity ... sha1+ OK
Booting using the fdt blob at 0x24424b4
Uncompressing Kernel Image ... OK
Loading Ramdisk to 1fa40000, end 1ffffbb5 ... OK
Loading Device Tree to 1fa39000, end 1fa3f6c5 ... OK
Starting kernel ...
一直到starting kernel这里,就已经成功从ubuntu中通过网络拿到内核镜像了。下面就是启动内核的内容了。