晚上好 世界

晚上好 世界

早安

本文由voyage200的 hermes-agent 代其撰写,不过voyage200本人仍对文章负责。

火影 T5G AMD(搭载 AMD Ryzen 5 5600H + NVIDIA RTX 3050 Mobile)本质上基于蓝天(Clevo)NH50/NH55(如 NH55Ax)公模。这类模具性价比极高,但官方往往只提供 Windows 版驱动(即官网上 270MB 的「综合控制中心-CV」,Clevo_ControlCenter_7.057.zip)。

在 Linux(我的主力机运行 Arch Linux + Linux 7.2 内核 + GNOME Wayland)环境下,默认没有专有控制程序,通常会面临两个烦人问题:

  1. 风扇策略不可控:默认保守的 EC 策略在负载升高时容易迟滞或突然起飞咆哮,日常码字又希望能有一套更安静的温控曲线;
  2. 键盘 RGB 无法调节:单区 RGB 背光无法改色,无法调暗甚至关不掉。

为了彻底解决火影 T5G 在 Linux 下的综合控制问题,我们逆向解包了官方 Windows 驱动包,理清了底层协议,并成功基于 Linux 开源生态打通了整套风扇曲线与键盘调色方案。以下是完整的逆向探查与配置排坑记录。


一、 官方 Windows 驱动包逆向剖析

官方下载的 Clevo_ControlCenter_7.057.zip 解压后是一套标准的 InstallShield 打包工程(包含 data1.cabdata2.cabsetup.exe)。通过 Linux 下的 unshield 工具解包 CAB 后,可以提取出其内部真正的核心载荷:

  1. ACPI 与 WMI 硬件通信桥

    • 包含 AcpiBridge.sysAcpiBridge1.sysInsydeDCHU.dll
    • INF 文件显示硬件 ID 为 ACPI\CLV0001ACPI\CLV0002
    • 底层通过 \\root\WMI 命名空间以及 ACPI DSM 方法与主板 EC 交互:

      • 0x63 / 0x64 / 0x6E:读取 CPU、GPU 及系统风扇的 RPM 转速与 PWM 占空比;
      • 0x68 / 0x69:设定手动风扇转速 / 恢复自动风扇策略;
      • 0x79(子命令 0x19):切换蓝天官方性能模式(Quiet / Power / Performance / Entertainment);
      • 0x67:控制键盘 RGB 颜色与亮度掩码。
  2. 键盘模块(Keyboard.appxbundle / LedKeyboardSetting.exe

    • 针对外挂的单键 RGB(Per-Key),驱动内置了 ITE Tech(048d:8297 / 048d:8910)USB HID 驱动;
    • 针对主板自带的整区/三区背光,直接走上述 ACPI 0x67 接口下发。

二、 Linux 方案选型:TUXEDO Control Center (TCC)

德国知名 Linux 笔记本厂商 TUXEDO Computers(以及欧洲贴牌商 XMG / Schenker)旗下大量游戏本均采购蓝天模具。他们官方开源并重金维护了一整套成熟的 Linux 方案:

  • tuxedo-drivers:内核 DKMS 模块,内置了 clevo_wmiclevo_acpituxedo_keyboard 以及风扇读写接口 tuxedo_io
  • tuxedo-control-center(TCC):图形化桌面控制中心与后台守护进程 tccd,提供无级风扇曲线调节、键盘 RGB 调色盘、性能模式切换等完整功能。

唯一的障碍与社区补丁

Tuxedo 原厂驱动在 tuxedo_compatibility_check.c 中加了 DMI 厂商白名单校验(若非 TUXEDO 机器直接退出)。
Arch Linux AUR 社区的 clevo-drivers-dkms-git 已经为我们打了补丁,强制 tuxedo_is_compatible() => true,完美移除了厂商硬件锁。


三、 Arch Linux 实装与排坑记录

1. 安装基础包

sudo pacman -S --needed base-devel linux-headers dkms
yay -S clevo-drivers-dkms-git tuxedo-control-center-bin

2. 踩坑一:模块加载语法误区导致 TCC 界面留白

在安装完成后启动 tccd.service,打开 TUXEDO Control Center 发现界面只有 Tux 图标,下方空白,风扇转速也无法调节。查看后台日志提示:

FanControlWorker: onStart: Fan API not available
KeyboardBacklightListener: Detected no keyboard backlight

原因分析
Linux 下 modprobe 的语法是 modprobe [模块名] [参数...]。如果敲成:
sudo modprobe tuxedo_keyboard tuxedo_io clevo_wmi clevo_acpi
内核会把后面三个名字全部当作参数传给 tuxedo_keyboard 并全部忽略!导致关键的 tuxedo_io(提供 /dev/tuxedo_io 节点)和 clevo_acpi 根本没进入内核。

正确做法:逐个单独加载核心模块:

sudo modprobe tuxedo_io
sudo modprobe clevo_wmi
sudo modprobe clevo_acpi

模块加载后,重启后台服务:

sudo systemctl restart tccd.service

再看日志,风扇与性能模式瞬间满血激活:

FanControlWorker: initializeFanControl: tuxedo-io available
FanControlWorker: initializeFanControl: Detected 3 fans
FanControlLogic: Setting tableCPU / tableGPU
ODMProfileWorker: Setting ODM profile 'performance'

在 TCC 界面点击 Profiles,已经可以随心所欲自定义 CPU / GPU 的温度-风扇转速阶梯曲线了!


四、 键盘背光探秘:单区 RGB 到底能不能硬件呼吸?

在排查键盘背光时,驱动成功握手并在内核日志中打印:

tuxedo_keyboard: Set keyboard enabled to: 1
tuxedo_keyboard: Set keyboard backlight mode on CUSTOM

在驱动加载的瞬间,我的键盘背光熄灭并重置为纯白色,同时 /sys/class/leds/rgb:kbd_backlight/ 成功出现!在控制中心也可以自由拖动调色板改色。

但当我尝试测试动效时,发现了一个经典疑问:为什么执行 echo 1 | sudo tee /sys/devices/platform/tuxedo_keyboard/kbd_backlight_mode 会报“权限不够”?火影 T5G 单区键盘到底支不支持硬件呼吸?

为了彻底搞清这个问题,我们直接进行了双向源码反编译:

1. Linux 内核驱动源码求证

查看 clevo_keyboard.h 驱动源码发现:

static void clevo_keyboard_init_device_interface(struct platform_device *dev)
{
    // 只有 3 区 RGB (0x02) 才会创建该 sysfs 动效节点!
    if (clevo_leds_get_backlight_type() == CLEVO_KB_BACKLIGHT_TYPE_3_ZONE_RGB) {
        device_create_file(&dev->dev, &dev_attr_kbd_backlight_mode);
    }
}

报“权限不够”不是因为 sudo 权限不足,而是虚拟文件系统里压根就没有这个文件! 驱动作者在识别到单区 RGB(1_ZONE_RGB,类型值 0x06)时直接跳过了动效节点的创建。

2. 官方 Windows 控制中心反编译验证

我们利用 dnfiledncil 深入反编译了火影官方 LedKeyboardSetting.exe 的 CIL 字节码,在 Page_LED_Device.Open_UI 中找到了答案:

ldfld this.kbType
ldc.i4.2            ; 若为 3 区 RGB (Type 2)
call Init_UI_RGB()  ; 加载包含呼吸(Breath)、波浪(Wave)、循环(Cycle)的特效面板

ldfld this.kbType
ldc.i4.6            ; 若为 单区 RGB (Type 6, 即火影 T5G AMD)
call Init_UI_ALL()  ; 仅加载单色调色板,动效面板直接隐藏剥离!

终极结论
可以彻底死心,不必再折腾固件硬件呼吸了。 火影 T5G AMD 的单区 RGB 在主板 EC 固件中压根就没有烧录硬件呼吸波形微码,即便在 Windows 官方系统下也只有静态纯色。

但这丝毫不影响我们在 Linux 下的使用体验:

  • 原生调色与控光:直接使用 Linux 标准 Multi-Color LED 子系统,在 TUXEDO Control Center 图形界面点选即变色,或者终端一行命令秒切:

    # 变冰蓝
    echo "0 255 255" | sudo tee /sys/class/leds/rgb:kbd_backlight/multi_intensity
    # 调暗亮度 (0 - 255)
    echo 120 | sudo tee /sys/class/leds/rgb:kbd_backlight/brightness
  • 软件呼吸(甚至比硬件更细腻):如果真的喜欢呼吸效果,在 Linux 下写个极轻量的 Python 脚本循环调节 brightness,正弦波插值平滑呼吸,CPU 占用不到 0.1%,刷新率和过渡甚至优于硬件自带微码。

五、 功耗与温控协同:ryzenadj 与 TCC 是否冲突?

很多 AMD 笔记本用户(包括我自己)会使用 ryzenadj 限制温度墙,比如配置开机自启 systemd 单元:

[Unit]
Description=RyzenAdj Power and Thermal Limit
After=multi-user.target suspend.target hibernate.target hybrid-sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/ryzenadj --tctl-temp=75

[Install]
WantedBy=multi-user.target suspend.target hibernate.target hybrid-sleep.target

两者冲突吗?答案是:完全不冲突,天作之合。

  • ryzenadj --tctl-temp=75:工作在物理硬件最底层,直接通过 PCI 写入 AMD 芯片内部的 SMU(系统管理单元协处理器),属于硬件级熔断兜底(一旦触碰 75°C 强制限流);
  • TUXEDO Control Center:工作在操作系统与 EC 层,只负责 Linux 内核 CPU 调度器(cpufreq governor)以及蓝天 EC 的风扇 PWM 曲线映射。

两者搭配时:ryzenadj 负责守住芯片温度上限,TCC 负责在温控范围内根据自定义曲线安安静静地排热,互不干涉,相得益彰。


六、 固化开机自动加载

最后,为了确保每次重启或休眠唤醒后驱动自动就绪,添加自动加载配置文件:

sudo tee /etc/modules-load.d/tuxedo.conf << 'EOF'
tuxedo_compatibility_check
tuxedo_keyboard
clevo_acpi
clevo_wmi
tuxedo_io
EOF

并确保守护进程开机启动:

sudo systemctl enable tccd.service

至此,火影 T5G AMD 游戏本在 Arch Linux 下成功获得了比 Windows 原版更轻巧、更自由、更安静的「综合控制中心」完整体验!


截至 2024年10月,Gemini APP 不为香港提供服务。
梯子节点换成美国、日本之类的地区就好了。

2026 2 10 勘误

香港现在可以访问gemini。访问不了主要和香港地区无关 和路线有关系,有些路线被拦了。


主诉

我在国内网络环境,通过ssh连接 阿里云国际型轻量应用服务器实例 时,遇到极其严重乃至掉线的卡顿

😷:为什么不用梯子走SSH,而要直连?
👩‍💻:我试过用梯子代理 SSH 流量。我有两个梯子。一个不稳定(连一会就断了)、一个无法使用(貌似封SSH协议了)。

👩‍💻:我也试过用阿里云的 Workbench 一键连接,是个 网页版 Terminal ,延迟很低。

👩‍💻:而且看UI是基于vscode相关代码二开的,开文件也是vscode同款编辑器、高亮,好评。

👩‍💻:但根本没有针对linux系统测试过,硬编码了Droid Dans Mono这种字体,,,,,而且有时候开个文件也不稳定、在这里面用 zellij 也没法全屏使用(因为我使用 css 强制修改了字体)。搞得我越用越生气,越感觉是在浪费自己的时间。

More...


我会傻傻地 上网搜索,搜索出来 --ozone-platform 这个命令行参数可以指定用 x11 还是 wayland,在以前,我只会做到这里,妥协地改 .desktop 文件(我不太想改 .desktop 文件,因为.desktop 文件一般是由包管理器负责部署的,直接改,不"通知"包管理器的话以后可能会出问题,而且 chrome 这边PWA也会生成 .desktop 文件)。

但现在,我们可以直接派 Agent 过去调查 chromium 的源代码:

使用 deepseek 的 claude code:
2025-11-17T15:24:15.png

● Ozone 平台在启动时选择 X11 和 Wayland 的具体逻辑如下:

  构建时配置

  在 build/config/ozone.gni:59-90 中定义了默认平台选择:
  - Linux 桌面:默认使用 x11 平台
  - ChromeOS:默认使用 x11 平台
  - Fuchsia:默认使用 flatland 平台
  - 其他情况:默认使用 headless 平台

  运行时选择逻辑

  在 ui/linux/display_server_utils.cc:50-70 中的 SetOzonePlatformForLinuxIfNeeded() 函数:

  1. 命令行参数优先:如果已指定 --ozone-platform,直接使用该值
  2. Wayland 检测:
    - 检查 XDG_SESSION_TYPE 环境变量是否为 "wayland"
    - 如果是,自动选择 wayland 平台
  3. X11 回退:如果没有指定平台且不是 Wayland 会话,默认选择 x11

  环境检测

  在 ui/linux/display_server_utils.cc:72-87 中的检测函数:
  - Wayland:检查 WAYLAND_DISPLAY 环境变量或 $XDG_RUNTIME_DIR/wayland-0 套接字文件
  - X11:检查 DISPLAY 环境变量

  平台初始化流程

  在 ui/ozone/public/ozone_platform.cc:32-43 中:
  1. 通过 GetOzonePlatformId() 获取平台 ID
  2. 使用 PlatformObject<OzonePlatform>::Create() 创建对应平台实例
  3. 平台列表在构建时由 generate_ozone_platform_list.py 生成

  总结:Ozone 优先使用命令行参数,其次根据桌面环境自动选择 Wayland(当检测到 Wayland 会话时),否则默认回退到 X11。

好耶~~!我们现在就知道了 chrome 原来是根据 XDG_SESSION_TYPE 选择 X11/Wayland 的。

我们就可以把 XDG_SESSION_TYPE 改到 wayland 之外的值

2025-11-17T15:34:03.png

启动 chrome ,它真的按照 Agent 说的那样使用 X11 (Xwayland) 了!

虽然 Agent 写代码现在不太行,但让它看现有代码效率比自己看要高。

2026.1.20 更新

哈哈,flatpak 那边的chrome是可以通过 echo "--enable-features=TouchpadOverscrollHistoryNavigation" > ~/.var/app/com.google.Chrome/config/chrome-flags.conf 把命令行参数放到文件 chrome-flags.conf,也可以生效的,这样就不需要配啥环境变量了,这也是 AI 浇我的!


我们用费曼学习法来学习一下“授权协商和授权协议(GNAP)”。目标是用简单的语言和比喻来解释它,让你能彻底理解。

第一步:核心思想(从一个简单的比喻开始)

想象一下,你是一家大型公司新雇佣的自由职业者(也就是你的软件,称为“客户端实例”)。你需要进入一个特定的、有安保的服务器机房(“资源服务器”)去为你的项目拿一些文件。

你不能直接走进去,你需要一张门禁卡(“访问令牌”)。

  1. 你先去公司的安全与人力资源部(“授权服务器”,简称AS)。
  2. 你告诉他们:“我是负责X项目的合同工,我需要进入那个项目的服务器机房。”
  3. 安全部说:“好的,我收到你的请求了。但我不能直接给你门禁卡,我需要得到你上级经理的批准,他/她才是那个服务器机房的负责人(“资源所有者”)。”
  4. 关键部分来了:安全部接着问你:“我们怎样联系你的经理最方便?我可以给他/她发一封带链接的邮件吗?或者我给你一个短码,让他/她在一个网站上输入?”—— 这就是GNAP中的“协商”过程。你告诉安全部你支持哪些联系方式。
  5. 你的经理收到了通知,登录了安全部门的系统,批准了你的特定请求。
  6. 安全部收到批准后,就给你签发了一张特殊的、有使用限制的数字门禁卡(即“访问令牌”)。
  7. 现在,你就可以去服务器机房门口,刷你的卡,门就打开了。

GNAP就是一套现代、灵活且安全的规则手册,它完整地规定了这整个对话和协商的过程。它的设计初衷就是一次协商,而不像旧协议那样死板。


第二步:识别主要“角色”

GNAP定义了几个关键角色,让我们正式认识一下故事里的这些“人物”:

  • 客户端实例 (Client Instance): 想要访问某些资源的特定软件。它不仅仅指这个应用程序本身,而是指你手机上或电脑上具体的那个安装实例。它通过一个独一无二的加密密钥(就像数字指纹)来证明自己的身份。
  • 授权服务器 (Authorization Server, AS): 负责处理安全事务的中心机构。它与用户沟通,获取批准,并最终签发“访问令牌”。可以把它想象成公司的安全/人力资源部。
  • 资源服务器 (Resource Server, RS): 保护着宝贵数据或API的服务器。它就是那个有安保的服务器机房,它信任授权服务器(AS)签发的门禁卡,并且知道如何验证这些卡。
  • 资源所有者 (Resource Owner, RO): 有权批准或拒绝访问其资源的个人或实体。在我们的比喻中,他就是你的经理。他“拥有”这些资源,并且可以授权他人访问。
  • 最终用户 (End User): 实际操作客户端软件的自然人。

一个至关重要的点:在很多情况下,“最终用户”和“资源所有者”是同一个人。例如,当你使用一个照片编辑应用去访问你自己的云端照片时,你既是应用的使用者(最终用户),也是授权它访问你照片的人(资源所有者)。GNAP的设计既能处理这种简单情况,也能处理两者是不同人的复杂情况。


第三步:解释流程 & GNAP的特别之处

现在,我们通过了解GNAP与它的前辈OAuth 2.0有何不同,来加深我们的理解。

1. 它是“协商”,而不是填“死板的表格”

像OAuth 2.0这样的旧协议有不同的“授权类型(grant types)”,就像是为不同场景选择特定的表格来填写(一种给网页应用,另一种给设备等等)。

GNAP则让所有的对话都以同一种方式开始:向同一个地址发起一个请求。客户端说明它想要什么,以及最重要的一点——它能以何种方式与用户互动

  • "我可以把用户的浏览器重定向到你给我的一个网址。"
  • "我可以在屏幕上显示一个短码,让用户在手机上输入。"
  • "我完全无法与用户互动,等批准了再通知我。" (用于异步场景)

授权服务器(AS)会根据收到的请求和自身的策略,选择最佳的前进路线。这种灵活性是GNAP与生俱来的,使得它能轻松支持从浏览器到智能电视再到后端服务的各种设备,而无需为每种设备创建全新的流程。

2. 默认安全性更强

许多OAuth 2.0流程依赖于“持有者令牌(bearer tokens)”。持有者令牌就像现金:谁拿到它,谁就能花。如果被偷了,小偷可以立刻使用。

GNAP默认使用密钥绑定令牌 (key-bound tokens)。这就像一张需要你指纹才能使用的信用卡。

  • 客户端实例拥有自己独一无二的私钥。
  • 授权服务器签发的访问令牌在数字上与这个公钥“绑定”在一起。
  • 为了使用这个令牌,客户端必须通过对请求进行签名来证明它仍然持有这个私钥。

这样一来,即使攻击者偷走了令牌本身,也无法使用它,因为他们没有客户端的私钥。虽然GNAP在明确要求的情况下也可以签发持有者令牌,但安全选项是默认的。

3. 请求内容更丰富、更具体

在OAuth 2.0中,你通常使用叫做“范围(scopes)”的简单字符串来请求访问权限,比如"read_photos""post_updates"

GNAP从一开始就允许更详细、结构化的请求,这类似于后来为OAuth 2.0添加的一个名为“丰富授权请求(RAR)”的功能。客户端可以明确地请求:

  • 操作 (actions): "read", "write"
  • 位置 (locations) (即哪个API): https://api.example.com/
  • 数据类型 (datatypes): "images", "metadata"

一个请求就可以表达:“我想要在 https://photos.example.com/ 上对 images 进行 readwrite 操作。” 这样能更清晰、更准确地表达客户端的意图。

4. 解耦授权服务器(AS)和资源服务器(RS)

当资源服务器(服务器机房)和授权服务器(安全部)由不同的团队或公司运营时,GNAP为它们之间的通信提供了一种更清晰的方式。这在扩展文档 (rfc9767.txt) 中有详细说明。

一个关键功能是令牌内省 (Token Introspection)。当资源服务器(RS)收到一个访问令牌时,它可以去问授权服务器(AS):

“嘿,我收到了这个令牌:OS9M2PMH...。它还有效吗?是给我的吗?它到底有哪些权限?”

然后,授权服务器会给出一个安全的回应,确认令牌的有效性和详细信息。这实现了职责的清晰分离:资源服务器的唯一工作就是保护好自己的资源,并向授权服务器查询任何它不认识的令牌。


第四步:回顾与简化

让我们总结一下。

什么是GNAP?
GNAP是一个用于委托授权的新协议。它是一种高度灵活且安全的方式,让一个软件(客户端)从一个中心机构(授权服务器)获得许可(访问令牌),以便代表用户(资源所有者)去访问受保护的资源(在资源服务器上)。

它有什么不同?

  1. 它是一场协商: 客户端和服务器会商量获取用户批准的最佳方式,而不是被锁定在单一的方法中。
  2. 默认更安全: 它倾向于使用密钥绑定的令牌(卡+指纹),而不是持有者令牌(只有卡)。
  3. 表达能力更强: 它从一开始就允许详细、结构化的访问请求。
  4. 支持现代用例: 它能轻松处理用户和资源所有者是不同人,或者完全没有浏览器参与的场景(如智能设备)。

通过使用这种逐步协商、强大的加密身份验证和清晰的角色分离,GNAP为保护API提供了一个强大而现代的框架。