问题摘要

无风扇主机板载 COM3 串口(UART 16550A)在 Ubuntu 16.04 下对应设备节点 /dev/ttyS4,但默认配置下 setserial -g /dev/ttyS4 显示 UART 为 unknown、端口与 IRQ 均为 0,串口无法收发数据。根因是 BIOS 中 COM3 的 IO=0x210、IRQ=10 与内核 8250 串口驱动的默认枚举结果不一致。修复方案:通过 GRUB 内核参数 8250.map=0x210,10 告知驱动真实端口,并使用 systemd oneshot 服务配合 setserial 在每次开机时持久化配置。

01故障现象

客户在某无风扇工业主机上部署 Ubuntu 16.04,需通过板载 COM3 串口与下游 RS-232 设备通信。现场反馈:应用程序打开 /dev/ttyS4 不报错,但收发数据全无响应,串口形同"死口"。

使用如下命令排查时可观察到典型异常:

$ setserial -g /dev/ttyS4
/dev/ttyS4, UART: unknown, Port: 0x0000, IRQ: 0

关键症状归纳如下:

02问题背景 · 硬件映射

该无风扇主机板载 4 个串口,BIOS 中的串口资源分配与本主板的 ttyS 映射关系如下表所示。需要特别注意的是:BIOS 中的 COM 编号与 Linux 下的 ttyS 编号并非一一对应,本主板 COM3 实际映射到 /dev/ttyS4。

BIOS 串口号 IO 端口 IRQ 模式 Linux 设备节点
Serial Port 1(COM1)0x3F84RS-232/dev/ttyS0
Serial Port 2(COM2)0x2F83RS-232/dev/ttyS1
Serial Port 3(COM3)0x21010RS-232/dev/ttyS4
Serial Port 4(COM4)0x21811RS-232/dev/ttyS5

BIOS 中 COM3 的端口配置如下图所示,IO 地址为 0x210、IRQ 为 10,与标准 PC AT 串口默认值(0x3E8 / IRQ4)完全不同:

BIOS · COM3 BIOS 中 COM3 串口 IO 0x210 IRQ 10 配置截图

03根因分析

Linux 8250 串口驱动在启动时会按标准 PC AT 端口地址(0x3F8、0x2F8、0x3E8、0x2E8 等)枚举串口。本主板 COM3 使用的 IO=0x210、IRQ=10 属于非标准端口,驱动在默认地址列表中找不到该串口,因此 ttyS4 虽被预留节点,却未绑定真实硬件资源,最终表现为 UART: unknown、Port: 0x0000、IRQ: 0。

解决思路有两个层面,缺一不可:

01

告知驱动真实端口

通过内核参数 8250.map=0x210,10 在驱动初始化时显式登记 COM3 的 IO 地址与 IRQ,让内核在正确地址探测到 16550A。

02

持久化串口属性

即便内核识别到设备,部分场景下 UART 类型仍需 setserial 显式指定为 16550A。通过 systemd oneshot 服务在每次开机自动执行,避免配置丢失。

03

幂等可重复执行

脚本需可安全重复执行:GRUB 参数只追加不覆盖、服务文件覆盖前自动备份、设备不存在时只 enable 不 start,首次运行与后续重跑都不报错。

04解决方案

综合上述分析,采用 "GRUB 内核参数 + setserial systemd 服务" 的双层修复方案:

  • 第一层 · 内核参数:GRUB_CMDLINE_LINUX_DEFAULT 追加 8250.map=0x210,10,执行 update-grub 后重启,让 8250 驱动在 0x210 地址正确识别 COM3 为 16550A。
  • 第二层 · 持久化服务:创建 setserial-ttys4.service oneshot 服务,开机后等待 /dev/ttyS4 出现,自动执行 setserial /dev/ttyS4 port 0x210 irq 10 uart 16550A
  • 安全策略:自动备份 GRUB 与服务文件、日志写入 /var/log/ubuntu_config.log、enable 与 start 失败时自动收集 systemd-analyze 与 journalctl 诊断信息。
修复后验证 setserial -g /dev/ttyS4 修复后输出 Port 0x0210 IRQ 10 UART 16550A

05一键配置脚本

下方为完整修复脚本 ubuntu_com3_setup.sh,封装了上述全部逻辑:GRUB 内核参数追加、systemd 服务创建、enable/start、状态校验与诊断信息收集。脚本可重复执行(幂等)、自动备份、完整日志记录,可直接复制或下载后部署到目标无风扇主机。

使用须知

1. 须以 root 执行:sudo bash ubuntu_com3_setup.sh;2. 内核参数需重启后生效,首次运行若 /dev/ttyS4 不存在属正常现象,脚本会自动 enable 服务并提示重启;3. Ubuntu 16.04 官方源已停止维护,若 apt-get install setserial 失败,请提前手动安装 setserial 包。

ubuntu_com3_setup.sh

                

06操作与验证

脚本执行与重启后的验证步骤如下:

1. 上传并执行脚本

$ sudo bash ubuntu_com3_setup.sh

脚本会自动完成 GRUB 参数追加、systemd 服务创建与 enable。首次运行若 /dev/ttyS4 尚未出现,脚本会提示"请重启",这是正常现象。

2. 重启使内核参数生效

$ sudo reboot

3. 重启后验证

$ cat /proc/cmdline # 应包含 8250.map=0x210,10
$ systemctl status setserial-ttys4.service # 应为 active (exited)
$ setserial -g /dev/ttyS4
/dev/ttyS4, UART: 16550A, Port: 0x0210, IRQ: 10

setserial -g /dev/ttyS4 输出 UART: 16550A, Port: 0x0210, IRQ: 10 时(如上图所示),即表明 COM3 已被正确识别并绑定真实硬件资源,串口可正常收发数据。

4. 故障排查

07方案价值与适用范围

结语

工业现场板载串口"节点在但用不了"是常见却隐蔽的故障,根因多在 BIOS 非标准端口与内核默认枚举地址的不匹配。本文方案已在某无风扇主机 Ubuntu 16.04 项目中验证生效,COM3(ttyS4)恢复稳定收发,为客户提供从硬件到操作系统的可靠串口通信保障。研威智能工业主机出厂前均经过严格串口测试,并提供完整的部署脚本与技术支持。