我有一个嵌入式 Linux 系统,带有 2 个内置串口,还有一块 PCI 板,另外还增加了 8 个串口。
内核以端口号最终交错的方式枚举设备,例如(来自dmesg
):
[ 5.964467] 0000:03:00.0: ttyS4 at MMIO 0xd0600000 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.964934] 0000:03:00.0: ttyS5 at MMIO 0xd0600400 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.965213] 0000:03:00.0: ttyS6 at MMIO 0xd0600800 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.965519] 0000:03:00.0: ttyS7 at MMIO 0xd0600c00 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.965879] 0000:03:00.0: ttyS8 at MMIO 0xd0601000 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.966755] 0000:00:1e.3: ttyS9 at MMIO 0xd091c000 (irq = 18, base_baud = 2764800) is a 16550A
[ 5.967123] 0000:03:00.0: ttyS10 at MMIO 0xd0601400 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.967411] 0000:03:00.0: ttyS11 at MMIO 0xd0601800 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.967705] 0000:03:00.0: ttyS12 at MMIO 0xd0601c00 (irq = 105, base_baud = 7812500) is a XR17V35X
[ 5.976690] 0000:00:1e.4: ttyS13 at MMIO 0xd091a000 (irq = 19, base_baud = 2764800) is a 16550A
这里,内置端口被分配了名称ttyS9
和ttyS13
,扩展端口被分配了名称ttyS4-8
和ttyS10-12
。下次重新启动时,分配将会有所不同。
由于端口名称会被打乱,因此我的内核命令行选项console=ttyS4,115200
或getty
.
我可以编写udev
创建稳定符号链接的规则,这些规则可能适用于内核命令行getty
,但不适用于内核命令行。
我尝试过在 Linux 命令行中使用 MMIO 地址,因为在console=uart,mmio32,0xd091c000,115200
系统启动时,我似乎没有收到任何内核输出。
如何稳定这些标识符?
答案1
我不确定,但如果您还没有尝试过,也许尝试更改内核的 biosdevname=0|1 参数?
它的值通常在 PC 上运行 grub2-mkconfig 之前在 GRUB_CMDLINE_LINUX 中更改,当然,该部分在您的嵌入式情况下可能会有所不同。
答案2
我的部分解决方法(不是理想的解决方案)是使用一个 udev 帮助程序脚本来查看内核的设备名称,例如 ,ttyS5
并通过解析符号链接来查找设备在 PCI 设备树中的位置/sys/class/tty/ttyS5
。然后它查看同一节点上的所有其他 TTY 设备,并获取指数该设备在同类设备中的排名。假设该节点内的设备顺序是稳定的,即使设备名称不稳定。
#!/usr/bin/env python3
import argparse
import os
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument("kernel_dev")
args = parser.parse_args()
# Find peer devices of this one
sysfspath = os.path.realpath(f"/sys/class/tty/{args.kernel_dev}")
peer_devices = os.listdir(os.path.dirname(sysfspath))
peer_devices.sort(key=lambda d: (len(d), d)) # natural sort
# Print the index of this device among its peers
print(peer_devices.index(args.kernel_dev) + 1)
udev 规则则变为:
... PROGRAM="/usr/bin/serial_device_index %k", SYMLINK+="ttyEXP%c" ...
该解决方案可能需要针对其他硬件配置进行调整。
我不喜欢什么
这只是产生稳定的符号链接名称,它不会产生稳定的名称,这对于将设备分配给内核参数console
或使用 Ubuntu 的getty
登录控制台 systemd 服务等可能有用。