---
title: "修正 systemd-hwdb 元数据后，Krita检测到 VEIKK A15 Pro 触控笔输入"
canonical: "https://siyuanailab.com/curation/translations/580a765c9a16450aae6941feafda49b3-163d1b70c738078e5312cf89fd4e1796e0cbe23e53af45ed36ead7d296250255/"
dateModified: "2026-10-03"
datePublished: "2026-10-03"
---

[返回日报条目](https://siyuanailab.com/curation/#entry/580a765c9a16450aae6941feafda49b3)

 

资料节译

 

# 修正 systemd-hwdb 元数据后，Krita检测到 VEIKK A15 Pro 触控笔输入

 

[阅读原文](https://dev.to/prachi_awesome_jha/how-i-fixed-my-drawing-tablet-by-patching-systemds-hardware-database-2d75)

 

现有资料无法确认原文完整，本页只翻译已取得的材料。

 

原图转存失败，失败位置已标注。

 

我决定暂时离开科技领域，尝试一些新东西，比如数字绘画。于是我从柜子底部翻出了绘图板（它在那里积灰好几年了）。

 

果不其然，我的 Linux 配置一开始就拒绝识别它。

 

我想用 Krita 画画，于是通过 USB 把绘图板连接到笔记本电脑。绘图板上的指示灯亮了起来，我天真地以为这是个好兆头。于是我拿起手写笔开始画。

 

瞬间失望。

 

我在绘图板上用手写笔做的任何操作，都没有反映到显示器上。我想到故障可能出在两个环节之一。

 

- Linux 没有检测到绘图板。
 
- 绘图板的输入没有被检测到。

 

我通过 `lsusb`确认了第一种情况，并清楚地看到：

 

`Bus 003 Device 006: ID 2feb:0006 Beijing Veikk E-Commerce Co., Ltd. A15PRO`

 

这样就把问题缩小到了第二种情况。

 

为了确认调试方向正确，我追踪了手写笔输入的路径：从笔尖接触绘图板开始，到输入最终在 Krita 中呈现为止。

 

下面有些细节可能只适用于我的系统，配置如下：

 

*操作系统：Arch Linux 内核：7.1.5-zen1-1-zen libinput：1.31.3 sway 版本：1.12 绘图板：VEIKK A15 Pro*

 

下面说说它应该如何工作：

 

- 手写笔检测位置（X、Y）和压力的变化，并通过 USB 发送这些输入。
 
- 绘图板使用 USB HID（人机接口设备）协议进行通信。因此，设备连接时会向 Linux 提供 *HID 报告描述符*。这个描述符说明数据包的布局，规定每个位或字节代表什么。
 
- Linux 有一个名为 *usbhid* 的内核级驱动，负责处理 USB HID 通信。绘图板通过 USB 发送 HID 输入报告，Linux HID 子系统则根据设备提供的 HID 报告描述符接收并解析这些报告。
 
- Linux 有一个通用输入子系统，会将这些 HID 报告转换为标准化输入事件。对我的绘图板来说，它会提供 ABS_X、ABS_Y、ABS_PRESSURE、BTN_TOOL_PEN、BTN_TOUCH、BTN_STYLUS 等事件。
 
- Linux 输入子系统通过 *evdev* 接口提供这些标准化事件。*Evdev*（事件设备）是 Linux 内核提供的通用接口，用于向用户空间提供输入事件。在本例中，手写笔以 */dev/input/event19* 的形式暴露给用户空间，因此 *evtest* 等程序可以读取这些输入事件。
 
- *libinput* 使用这些输入设备，并根据设备类型进行处理。libinput 是一个计算机库，用于在 Linux 上为显示服务器和图形环境处理输入设备。它充当 Linux 内核与桌面界面之间的桥梁。
 
- libinput 用户空间库会解析这些事件，然后将其发送给 Sway 合成器。随后，这些事件作为输入事件传递给 Krita 应用程序。

 

那么，我们就逐层调试这个错误。

 

首先，检查 USB HID 设备是否绑定到了内核的 *usbhid* 驱动。

 

要检查任何内容，首先需要找到存放手写笔输入设备文件的位置（Linux 中一切皆文件！）。因此，我们用下面的命令检查 Linux 当前检测到的所有输入设备：

 

```
cat /proc/bus/input/devices
```

 

我找到了 Linux 能看到的所有输入设备的信息，其中包括手写笔：

 

![](/curation/media/ebc78e0126456dcbc11da72350445b6b89989b0ffc6f7109387c05d906c55a9c.webp)

 

这表明输入手写笔的处理程序是“event19”。

 

那么，如何访问与这个特定输入处理程序相关的文件呢？

 

Linux 有一个名为 /dev 的设备文件系统。内核暴露硬件接口时，会在其中创建设备节点。对于输入设备，内核的 *evdev* 使用以下命名约定：

 

*/dev/input/event19*

 

接下来，我用下面的命令验证 usbhid：

 

`udevadm info /dev/input/event19`

 

结果如下：

 

`ID_USB_DRIVER=usbhid`

 

由此确认，USB HID 设备已绑定到内核的 usbhid 驱动。

 

接下来是位于 /sys/class/input/event19/device/device/report_descriptor 的 HID 描述符。

 

![](/curation/media/a8803a315c9d554a8dab7eac19b3f101e1772dd41a275d7dcb1b1a655230b056.webp)

 

绘图板的 HID 描述符实际上告诉 Linux 这是支笔，并描述了 X、Y、压力、按键等信息。

 

接下来是 *evdev* 层，我们用下面的命令检查：

 

`sudo evtest /dev/input/event19`

 

运行此命令后，移动手写笔会产生不断变化的 X、Y 和压力事件。

 

![](/curation/media/990c63c4569c948791767b5c3e22dc10c041a3fca23c19b38025dd858bde91c3.webp)

 

因此，直到这一层为止，我们都能清楚地收到输入。

 

接下来是 *libinput* 层。我们要检查 libinput 是否将它识别为可用的绘图板。

 

为此，我们运行了：

 

```
sudo libinput list-devices
```

 

运行后，终端输出了：

 

```
VEIKK.INC A15PRO Stylus:
    libinput bug: missing tablet capabilities: resolution.
    Ignoring this device.
```

 

现在我们找到了问题所在。

 

*Libinput* 需要某些元数据，如果缺少这些信息，就会忽略设备。本例中缺少的是“resolution”（分辨率）。

 

在此语境下，轴分辨率指每毫米的物理移动对应多少坐标单位。例如，分辨率为 129 单位/毫米，意味着手写笔在绘图板上移动 1 毫米，对应 ABS_X 坐标范围内大约 129 个单位。

 

那么，分辨率去哪儿了？

 

我们再回头看看之前的报告描述符，因为所有元数据最初都来自那里。

 

再看一遍，似乎有些地方不对劲。

 

“Unit = 0x33, Unit Exponent = -3”是什么意思？

 

hid-decode 将其解读为：

 

`Unit (EnglishLinear: inÂ³)`

 

所以绘图板用立方单位测量 X 和 Y？这听起来不太对。

 

0x33 是一个打包的 HID 单位值。低位半字节描述单位系统，后续位则编码各维度的指数。在这种编码中，0x13 表示英寸，而 0x33 表示长度指数为 3 的英寸，hid-decode 将其显示为 EnglishLinear: inÂ³。

 

这对 X/Y 坐标来说很可疑：X 坐标是长度，因此立方单位在这里毫无道理。HID 规范在 6.2.2.7 节定义了这种单位编码，内核源码引用的也是这一节。

 

但关键问题不只是 0x33 看起来奇怪。Linux 内核实际上会如何处理它？

 

我们怎么会因此得到没有分辨率的结果？

 

为此，我们需要看看 Linux 如何根据这个 HID 描述符计算分辨率。

 

查看内核源文件（[https://github.com/torvalds/linux/blob/d89f04ac41e3b83a25b02c8d818ce09d7afc74c9/drivers/hid/hid-input.c](https://github.com/torvalds/linux/blob/d89f04ac41e3b83a25b02c8d818ce09d7afc74c9/drivers/hid/hid-input.c)）：

 

`hidinput_calc_abs_res()` - 此函数负责根据 HID 描述符提供的信息计算绝对输入轴的分辨率。

 

内核要求 X/Y 单位必须是它支持的长度表示形式之一。我的绘图板报告的单位是 0x33，hid-decode 将其解读为 EnglishLinear: inÂ³。内核的 X/Y 分辨率计算不接受这种单位表示形式，因此计算结果为零。

 

```
switch (code) {
    case ABS_X:
    case ABS_Y:
    case ABS_Z:
    case ABS_MT_POSITION_X:
    case ABS_MT_POSITION_Y:
    case ABS_MT_TOOL_X:
    case ABS_MT_TOOL_Y:
    case ABS_MT_TOUCH_MAJOR:
    case ABS_MT_TOUCH_MINOR:
        if (field->unit == 0x11) {      /* If centimeters */
            /* Convert to millimeters */
            unit_exponent += 1;
        } else if (field->unit == 0x13) {   /* If inches */
            /* Convert to millimeters */
            prev = physical_extents;
            physical_extents *= 254;
            if (physical_extents < prev)
                return 0;
            unit_exponent -= 1;
        } else {
            return 0;
        }
        break;
}
```

 

我们可以用下面的命令交叉验证 Linux 看到的分辨率：

 

`sudo evemu-describe /dev/input/event19`

 

结果如下：

 

（原图获取失败，本处不展示图片。）

 

两个轴的分辨率都报告为 0，这证实了我们的追踪结果。那么，该如何修复？

 

一种常用解决方案是另找一种途径，绕过 libinput 向 Krita 应用程序提供输入。我在这里使用 *OpenTabletDriver* 作为替代方案。

 

OTD 直接与绘图板通信，并通过自身的绘图板支持来解析其报告。

 

我成功安装了驱动，问题也因此解决。

 

不过，如果我们直接向用户空间提供修正后的设备元数据，会怎么样？

 

我可以从这里提供的硬件规格中获取正确的分辨率：[https://veikk.com/en-in/products/creator-a15pro](https://veikk.com/en-in/products/creator-a15pro)

 

我们可以根据官方给出的 10x6 英寸有效区域（254 x 152.4 毫米）以及 0-32767 的逻辑范围来设置分辨率（逻辑范围来自描述符）：

 

X：32767 / 254 = 129 单位/毫米

 

Y：32767 / 152.4 = 215 单位/毫米

 

设备出现时，如何向 libinput 提供这些元数据？

 

通常作为第一个用户空间进程（PID 1）运行的 *systemd*，包含一个硬件专用元数据修正数据库，udev 会在设备出现时将其中的信息应用到设备上。这个数据库叫作 *systemd-hwdb*。

 

于是我创建了这个文件的本地版本：*/etc/udev/hwdb.d/61-evdev-local.hwdb*，并在其中添加了以下内容：

 

```
evdev:input:b0003v2FEBp0006*
    EVDEV_ABS_00=::129
    EVDEV_ABS_01=::215
```

 

各部分的含义如下：

 

evdev:input: - 匹配一个 evdev 输入设备

 

b0003 - USB 总线

 

v2FEB - VEIKK 厂商 ID

 

p0006 - A15 Pro 产品 ID

 

`*` - 其余 modalias 字段可以是任意值

 

EVDEV_ABS_00=::129 表示最小值和最大值保持不变，分辨率设为 129。

 

然后我重建并重新加载了数据库：

 

```
sudo systemd-hwdb update
sudo udevadm trigger /dev/input/event19
```

 

完成这些操作后，Krita 就能检测到手写笔输入。分辨率的变化可以在 udev 层看到，libinput 也不再抛出之前的错误。

 

确认它在我的机器上正常工作后，我向 systemd 提交了包含相同条目的拉取请求。该请求已合并：[https://github.com/systemd/systemd/pull/43962](https://github.com/systemd/systemd/pull/43962).

 

因此，如果你有 VEIKK A15 Pro，那么只要包含此修复的 systemd 版本发布，你就不需要做这些操作了。

 

回头看，问题本身比排查过程简单得多。绘图板的描述符将 X/Y 轴声明为内核不接受的单位，因此分辨率变成了零，libinput 也就拒绝了这个设备。这甚至不是改一个字节就能解决的。描述符还给两个轴都设置了相同的物理最大值 8000；即使单位修正了，那也会对应一个边长为 8 英寸的正方形，而实际绘画区域是 10Ã6。因此我不能只修补单位，而必须从规格表中查出真实尺寸。

 

如果你的另一款绘图板也有相同症状

 

通用处理步骤如下：

 

用 lsusb 获取厂商 ID 和产品 ID。

 

从制造商的规格中找到真实的有效区域尺寸，单位为毫米。

 

将每个轴的逻辑最大值（来自 evtest 或描述符）除以该轴的毫米尺寸。这就是以单位/毫米表示的分辨率。

 

在匹配设备的 hwdb 条目中填入这些数值，然后运行 sudo systemd-hwdb update 并触发设备。

 

我仍然不知道 Windows 为什么从未遇到这个问题。它可能会容忍这个描述符，也可能是 VEIKK 自己的驱动绕过了问题。我没有测试过是哪一种，所以就把它留作一个疑问。

 

这块在柜子底部待了好几年的绘图板表现还不错。现在我只需要学会怎么画画了。

 

AI 翻译；具体表述请与原文对照。
