泰山派NAS-内核设备树适配以太网和SATA
(免责说明) 本人能力有限,且非电子专业,以下内容仅代表本人学习中的累计经验总结不保证完全100%没有错误,如介意请谨慎阅读或者离开。
未经允许禁止转载,博客地址:saisaiwa.com
1. SATA设备树使能配置
泰山派中引出的SATA引脚是SATA1所以我们使用的资源是SATA1,其中SATA1复用引脚也包含USB3.0我们需要配置屏蔽
1.1 检查内核配置(menuconfig)使能如下配置
1.2 设备树DTS修改
修改路径为: kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-core-v10.dtsi
搜索找到节点: usbhost_dwc3 修改内容
然后新增两个新的节点。
完整配置如下:
&usbhost_dwc3 {
phys = <&u2phy0_host>;
phy_names = "usb2_phy";
maximum_speed = "high-speed";
status = "okay";
};
&sata1 {
// assigned-clock-rates = <100000000>;
status = "okay";
};
&combphy1_usq {
rockchip,dis-u3otg1-port;
status = "okay";
};
1.3 举一反三,探索
一开始当我们不知道如何配的时候可以参考其他设备树的文件做参考。
我们在当前dts文件中全局搜索 &sata1 关键字排除*.dtb,*.tmp文件。观察其他设备树是如何使用配置stat节点的。
在下图中我们选择找到了满足的条件有两个,选择nvr-demo的设备树文件来做参考!
可以看到使能sata貌似很简单给个okay就行,但是我们配合文档可以看出,我们还需要配置PHY的节点(看上上图)。 SATA1的PHY节点是什么? 文档给出节点名叫 :combphy1_usq。
有了名字我们直接去搜一搜:
但是我们不需要SATA的reset引脚所以这两句可以去掉,然后添加到我们自己的设备树中。
上面说了USB3.0也是此引脚复用,但是我们需要拆分两个功能进行复用,USB2.0和SATA。那么SATA完成了,我们还需要设置下USB的配置
(看上图的序号2)到这一步那么控制器是什么? 要改哪里?
序号3描述了是节点USB3.0 HOST我们直接去找USB相关的文档,找到了如下图所示的描述的信息。
标记重点,DWC3控制器
然后我们继续分析看下面的文档讲述配置的部分,如下图。
这就是此配置将其USB3.0 HOST工作在USB2.0的模式。
END! 到这里我们应该知道为什么要修改和增加共三个节点的原因了。在配置我们不了解的外设时先探索其他设备树的配置做参考,然后配合官方文档+我们网上搜索的信息做汇总基本上就迎刃而解了。
1.4 调试挂载与测速
mSATA硬盘在上电之前先插入到底板上。
系统启动成功之后我们可以使用如下命令检查是否检测到硬盘!
sudo fdisk -l
sudo fdisk -l
Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk /dev/sda: 119.25 GiB, 128032974848 bytes, 250064404 sectors
Disk model: FORESEE 128GB SS
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 68E63DA8-1193-46BC-9779-27096A811DEE
Device Start End Sectors Size Type
/dev/sda1 2048 250062847 250060800 119.2G Linux filesystem
Disk /dev/mmcblk0: 14.57 GiB, 15634268160 bytes, 30535680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: FD350000-0000-474B-8000-1F580000307C
Device Start End Sectors Size Type
/dev/mmcblk0p1 16384 24575 8192 4M unknown
/dev/mmcblk0p2 24576 32767 8192 4M unknown
/dev/mmcblk0p3 32768 163839 131072 64M unknown
/dev/mmcblk0p4 163840 294911 131072 64M unknown
/dev/mmcblk0p5 294912 360447 65536 32M unknown
/dev/mmcblk0p6 360448 12943359 12582912 6G unknown
/dev/mmcblk0p7 12943360 13205503 262144 128M unknown
/dev/mmcblk0p8 13205504 30535615 17330112 8.3G unknown
由于我的mSATA是128G的大小,所以成功的检测到了 Disk /dev/sda: 119.25 GiB, 并且硬盘名称和品牌也打印出来了 FORESEE 128GB SS (江波龙128G固态SSD)
另外一个命令: sudo lslbk
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 119.2G 0 disk
`-sda1 8:1 0 119.2G 0 part
mmcblk0 179:0 0 14.6G 0 disk
|-mmcblk0p1 179:1 0 4M 0 part
|-mmcblk0p2 179:2 0 4M 0 part
|-mmcblk0p3 179:3 0 64M 0 part
|-mmcblk0p4 179:4 0 64M 0 part
|-mmcblk0p5 179:5 0 32M 0 part
|-mmcblk0p6 179:6 0 6G 0 part /
|-mmcblk0p7 179:7 0 128M 0 part /oem
`-mmcblk0p8 179:8 0 8.3G 0 part /userdata
mmcblk0boot0 179:32 0 4M 1 disk
mmcblk0boot1 179:64 0 4M 1 disk
可以观察到唯一的分区sda1以及存在。
查看sda1是否挂载到系统,使用命令:sudo df -h
sudo df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 5.9G 4.2G 1.5G 75% /
devtmpfs 977M 8.0K 977M 1% /dev
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 198M 2.8M 195M 2% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
tmpfs 986M 72K 986M 1% /tmp
/dev/mmcblk0p7 123M 13M 104M 11% /oem
/dev/mmcblk0p8 8.2G 23K 8.2G 1% /userdata
tmpfs 198M 0 198M 0% /run/user/0
tmpfs 198M 8.0K 198M 1% /run/user/111
tmpfs 198M 4.0K 198M 1% /run/user/1000
然而系统并没有自动挂载到系统上,接下来我们手动来挂载一下。
我们在 /mnt目录下新建一个ssd文件夹
sudo mkdir /mnt/ssd
执行挂载命令
sudo mount /dev/sda1 /mnt/ssd
我们要挂载的是sda1分区所以使用sda1,前缀是/dev
cd ssd
lckfb@linux:/mnt/ssd$ ls
lost+found readme.txt test1
由于我之前有在硬盘中存有文件所以进入到目录中可以看到硬盘内的文件。
然后在使用df命令查看下挂载情况
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 5.9G 4.2G 1.5G 75% /
devtmpfs 977M 8.0K 977M 1% /dev
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 198M 2.8M 195M 2% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
tmpfs 986M 72K 986M 1% /tmp
/dev/mmcblk0p7 123M 13M 104M 11% /oem
/dev/mmcblk0p8 8.2G 23K 8.2G 1% /userdata
tmpfs 198M 0 198M 0% /run/user/0
tmpfs 198M 8.0K 198M 1% /run/user/111
tmpfs 198M 4.0K 198M 1% /run/user/1000
/dev/sda1 118G 1.1G 111G 1% /mnt/ssd
在最后一行可以看到已经成功挂载到系统上了,挂载的目录也是正确的
接下来测个速看看
首先第一步我们先cd到ssd目录下
准备两个命令
sudo dd if=/dev/zero of=test1 bs=1M count=1024 conv=sync status=progress
sudo dd if=test1 of=/dev/null conv=sync status=progress
测试写入速度,写入大小为1GB
执行命令:sudo dd if=/dev/zero of=test1 bs=1M count=1024 conv=sync status=progress
sudo dd if=/dev/zero of=test1 bs=1M count=1024 conv=sync status=progress
996147200 bytes (996 MB, 950 MiB) copied, 5 s, 185 MB/s
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.71073 s, 188 MB/s
在5秒内写入1G完成平均速度188MB/S。 由于我买的是二手工控机拆机的固态128G所以速度并不快。
测试一下读取速度,就测试刚刚写入的1G文件
执行命令:sudo dd if=/dev/zero of=test1 bs=1M count=1024 conv=sync status=progress
sudo dd if=/dev/zero of=test1 bs=1M count=1024 conv=sync status=progress
997195776 bytes (997 MB, 951 MiB) copied, 5 s, 199 MB/s
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 6.18441 s, 174 MB/s
关于dd命令其实还有很多用法,比如不使用缓存,强制直接写入硬盘测试等,不同用法测试的速度各不相同。
2. 百兆以太网(RMII)设备树适配
打开设备树文件路径为: kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-gmac1-v10.dtsi
完整的配置如下:
// &gmac1 {
// phy-mode = "rgmii";
// clock_in_out = "output";
// snps,reset-gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>;
// snps,reset-active-low;
// /* Reset time is 20ms, 100ms for rtl8211f */
// snps,reset-delays-us = <0 20000 100000>;
// assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
// assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
// assigned-clock-rates = <0>, <125000000>;
// pinctrl-names = "default";
// pinctrl-0 = <&gmac1m1_miim
// &gmac1m1_tx_bus2
// &gmac1m1_rx_bus2
// &gmac1m1_rgmii_clk
// &gmac1m1_rgmii_bus>;
// tx_delay = <0x19>;
// rx_delay = <0x06>;
// phy-handle = <&rgmii_phy0>;
// status = "okay";
// };
// &mdio1 {
// rgmii_phy0: phy@0 {
// compatible = "ethernet-phy-ieee802.3-c22";
// reg = <0x0>;
// };
// };
&gmac1 {
phy-mode = "rmii";
clock_in_out = "output";
assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
assigned-clock-parents = <&cru SCLK_GMAC1_RMII_SPEED>;
assigned-clock-rates = <0>, <50000000>;
snps,reset-gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
pinctrl-names = "default";
pinctrl-0 = <&gmac1m1_miim &gmac1m1_clkinout &gmac1m1_rx_bus2
&gmac1m1_tx_bus2>;
phy-handle = <&rmii_phy1>;
status = "okay";
};
&mdio1 {
rmii_phy1: phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
};
};
请注释掉原先的千兆RGMII配置,然后增加新配置
2.1 配置项说明
由于泰山派的EXP引出的为gmac1所以我们要配置的节点为&gmac1
- phy-mode = "rmii"; 我们使用的是百兆RMII协议所以更改为rmii
- clock_in_out = "output"; 由于我们设计的电路是无晶振设计所以output输出模式
- assigned-clock-parents = <&cru SCLK_GMAC1_RMII_SPEED>; 内的参数值改为RMII,保持协议一致
- assigned-clock-rates = <0>, <50000000>; 时钟速率改为百兆时钟50Mhz。
- pinctrl-0 = <&gmac1m1_miim &gmac1m1_clkinout &gmac1m1_rx_bus2 &gmac1m1_tx_bus2>; 这里设置的引脚复用改为这种固定死的。和我们使用的引脚一一对应。。
- phy-handle = <&rmii_phy1>; 这个无所谓了你写0也可以,和下面的&mdio1对应即可,我也是复制官方的文档来的。
- &mdio1中reg = <0x0>; 还记得在百兆设计PCB的时候提到某个引脚悬空地址是0x0吗,就是它。
百兆的到此配置就结束了,开机ifconfig就可以看到eth0节点了。
2.2 调试测速
使用iperf3工具测试
lckfb@linux:~$ iperf3 -c 192.168.110.3 -f m -t 10 -b eth0
Connecting to host 192.168.110.3, port 5201
[ 5] local 192.168.110.167 port 33066 connected to 192.168.110.3 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.1 MBytes 93.0 Mbits/sec 0 137 KBytes
[ 5] 1.00-2.00 sec 10.7 MBytes 89.5 Mbits/sec 0 137 KBytes
[ 5] 2.00-3.00 sec 10.5 MBytes 88.4 Mbits/sec 0 137 KBytes
[ 5] 3.00-4.00 sec 10.7 MBytes 89.4 Mbits/sec 0 137 KBytes
[ 5] 4.00-5.00 sec 10.9 MBytes 91.5 Mbits/sec 0 160 KBytes
[ 5] 5.00-6.00 sec 10.8 MBytes 90.4 Mbits/sec 0 173 KBytes
[ 5] 6.00-7.00 sec 11.0 MBytes 92.0 Mbits/sec 0 173 KBytes
[ 5] 7.00-8.00 sec 11.3 MBytes 95.1 Mbits/sec 0 248 KBytes
[ 5] 8.00-9.00 sec 11.3 MBytes 95.1 Mbits/sec 0 248 KBytes
[ 5] 9.00-10.00 sec 11.0 MBytes 92.5 Mbits/sec 0 248 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 109 MBytes 91.7 Mbits/sec 0 sender
[ 5] 0.00-10.01 sec 109 MBytes 91.2 Mbits/sec receiver
iperf Done.
可以看到速度基本满足100M的带宽
3. 千兆以太网RGMII适配
这个其实没有什么好说的,在上面的基础上注释掉百兆的配置打开千兆的配置dts节点,这里配置为泰山派官方文档中默认写好的。
如下千兆的配置:
// &gmac1 {
// phy-mode = "rgmii";
// clock_in_out = "output";
// snps,reset-gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>;
// snps,reset-active-low;
// /* Reset time is 20ms, 100ms for rtl8211f */
// snps,reset-delays-us = <0 20000 100000>;
// assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
// assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
// assigned-clock-rates = <0>, <125000000>;
// pinctrl-names = "default";
// pinctrl-0 = <&gmac1m1_miim
// &gmac1m1_tx_bus2
// &gmac1m1_rx_bus2
// &gmac1m1_rgmii_clk
// &gmac1m1_rgmii_bus>;
// tx_delay = <0x19>;
// rx_delay = <0x06>;
// phy-handle = <&rgmii_phy0>;
// status = "okay";
// };
// &mdio1 {
// rgmii_phy0: phy@0 {
// compatible = "ethernet-phy-ieee802.3-c22";
// reg = <0x0>;
// };
// };
3.1 千兆RGMII的delayline扫描适配
来自:Rockchip_Developer_Guide_Linux_GMAC_RGMII_Delayline_CN.pdf
Rockchip 芯片具有千兆以太网的功能,使用 RGMII 接口,为了兼容各种不同硬件所带来的信号差异,芯片增加了调整 (TX/RX) RGMII delayline 功能,合适的 delayline 以达到千兆以太网性能最优速度。
进入目录:/sys/devices/platform/fe010000.ethernet 可以看到这几个节点
3.1.1 扫描 delayline 窗口
如果你使用的是 RTL8211E phy ,测试前需要拔掉网线。
通过 phy_lb_scan 节点扫描到一个窗口,会得到一个中间坐标,需要使用千兆速度 1000 来扫描。
echo 1000 > phy_lb_scan
中心点坐标在扫描窗口的最后也会打印出来:
如果你的执行没有打印请设置内核打印日志级别:
dmesg -n 8
如果你多次没有扫描出结果,大概率是信号太差了。
试试看100M的能不能扫描出来,此仅是测试硬件正常工作,检测结果不能直接用。
echo 100 > phy_lb_scan
请根据如下几点检查:
- 焊接问题例如虚焊,吃点焊油重新加焊
- 检查设备树配置
- 检查gmac启动是否失败: dmesg | grep gamc
- FPC排线是否过长?更换30~35mm左右的试试?
- PCB走线GMAC部分是否过长?
- 以太网晶振是否起振?
- PCB设计失败!
3.1.2 测试扫描出来的中间值
将扫描得到的值通过命令配置到 rgmii_delayline 节点,然后测试该配置下 TX/RX 数据传输是否正
常,通过 phy_lb 节点测试,至少这个测试需要先 pass。
echo (tx delayline) (rx delayline) > rgmii_delayline
cat rgmii_delayline
echo 1000 > phy_lb
测试 pass 后,将 delayline 分别填到 dts: tx_delay = <0x2e>; 和 rx_delay = <0x0f>; ,重新烧入固
件,接着继续测试 ping 或者 iperf 性能测试,一般情况下到这一步就可以了。
评论区