SD 跑起来之后,接着补网络和定时器。
网络:PHY 挂不上
Cadence GEM 是标准 IP,QEMU 自带 TYPE_CADENCE_GEM。接上去之后驱动能认到硬件:
macb e1618000.ethernet eth0: Cadence GEM rev 0x00020118 at 0xe1618000 irq 21
但一执行 ip link set eth0 up 就报错:
macb e1618000.ethernet eth0: validation of with support 00,… failed: -EINVAL macb e1618000.ethernet eth0: Could not attach PHY (-22)
Could not attach PHY。驱动找不到 PHY。
问题在设备树。我只写了 phy-mode = "rgmii",没有 MDIO 子节点。但 PHY 是挂在 MDIO 总线上的,光告诉它用什么接口模式不够,还得告诉它 PHY 在哪。
补上:
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@7 {
reg = <7>;
};
};再加一句 phy-handle = <&phy0>;。地址 7 是跟 QEMU 侧对齐的——创建 GEM 时设了 phy-addr = 7。
【09_01_网络链路】
补完之后:
macb e1618000.ethernet eth0: PHY [e1618000.ethernet-ffffffff:07] driver [Generic PHY] (irq=POLL) macb e1618000.ethernet eth0: Link is Up - 1Gbps/Full - flow control tx
千兆全双工。
ping 通了
配置地址,ping 网关:
~ # ip addr add 10.0.2.15/24 dev eth0 ~ # ip route add default via 10.0.2.2 ~ # ping -c 3 10.0.2.2 PING 10.0.2.2 (10.0.2.2): 56 data bytes 64 bytes from 10.0.2.2: seq=0 ttl=255 time=11.524 ms 64 bytes from 10.0.2.2: seq=1 ttl=255 time=5.634 ms 64 bytes from 10.0.2.2: seq=2 ttl=255 time=0.671 ms 3 packets transmitted, 3 packets received, 0% packet loss
【09_02_ping结果】
零丢包。
这里还踩过一个前置的坑:QEMU 编译时用了 --disable-slirp,-nic user 这个后端根本不存在,报 network backend 'user' is not compiled into this binary。装了 libslirp-dev 重新配置才有。
定时器:换成真的 PIT64B
之前为了修中断 bug,先借用了 ARM 架构定时器。但那是 CPU 自带的,不是这颗芯片的东西。
换成 PIT64B。它是 64 位周期定时器,寄存器不多:控制 CR(0x00)、模式 MR(0x04)、周期 LSB/MSB(0x08/0x0C)、中断使能 IER(0x10)、状态 ISR(0x1C)、计数 TLSBR/TMSBR(0x20/0x24)。
关键是计数速率:
速率 = 时钟 / (预分频 + 1)
驱动自己也算一遍,然后打印出来。两边一对:
PIT64B: using clk=pclk with prescaler 15, freq=6250000 [Hz]
【09_03_PIT64B】
模型按 100 MHz / (15 + 1) = 6.25 MHz 算,和驱动算的完全一致。这个数字对上,说明预分频、计数、周期中断这一套是对的。
一个 A/B 对比
设备树里留着 arm,armv7-timer 的时候,/proc/interrupts 是这样的:
16: 0 GICv2 29 Level arch_timer 17: 180 GICv2 30 Level arch_timer 20: 0 GICv2 98 Level pit64b_tick
PIT64B 注册了,但一次中断都没来。
把 arch timer 节点从设备树里去掉再启动:
16: 2560 GICv2 98 Level pit64b_tick
2560 次。系统真正跑在这颗芯片的定时器上了。
我要赚赏金
