十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

三星 Galaxy Book Linux 驱动实战指南:基于 SCAI ACPI 设备的平台驱动功能解析

三星 Galaxy Book Linux 驱动实战指南:基于 SCAI ACPI 设备的平台驱动功能解析 三星 Galaxy Book Linux 驱动实战指南基于 SCAI ACPI 设备的平台驱动功能解析【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文以内核文档 Documentation/admin-guide/laptops/samsung-galaxybook.rst 为骨架结合 samsung-galaxybook.c1457 行的源码实现进行逐项印证与扩展。它面向三星 Galaxy Book 系列笔记本用户、Linux 内核驱动阅读者与 ACPI 平台驱动开发者讲解该驱动如何通过三星专有 SCAI ACPI 设备提供键盘背光、性能模式、电池充电截止阈值、固件属性以及 Fn 热键处理等能力并给出可操作的 sysfs 用法与底层原理。驱动定位与内核接入三星 Galaxy Book 驱动driver 名samsung-galaxybook是一个 Linux x86 平台驱动其核心思路是借助三星笔记本固件中的SCAIACPI 设备设备 ID 前缀SAM0.../SAMB...与固件通信从而控制 Windows 下由三星应用管理的一系列扩展功能并接收 ACPI 通知与热键事件。在内核配置层面其定义位于 drivers/platform/x86/Kconfig选项为CONFIG_SAMSUNG_GALAXYBOOKtristate可编译为模块并声明了如下依赖与自动选择项依赖ACPI、ACPI_BATTERY、INPUT、LEDS_CLASS、SERIO_I8042后两项分别对应键盘背光 LED 与 i8042 热键过滤自动select ACPI_PLATFORM_PROFILE性能模式依赖的 platform profile 框架与select FW_ATTR_CLASS固件属性框架Makefile 中的编译规则见 drivers/platform/x86/Makefile。从源码的 ACPI 设备 ID 表samsung-galaxybook.c 第 1435–1443 行可见凡 DSDT 中 SCAI 设备具有以下 ID 之一的机型都会被驱动匹配SAM0426 SAM0427 SAM0428 SAM0429 SAM0430 SAMB430因此支持设备的范围可以概括为只要 DSDT 中 ACPI 设备 ID 命中的三星 Galaxy Book 系列笔记本即受支持可能也涵盖部分其它三星笔记本型号。编译为模块后通过modprobe samsung-galaxybook加载或配置为y随内核内建。驱动与 SCAI ACPI 设备的通信机制驱动不直接访问 I/O 或 SMBus而是通过三个 ACPI 方法见源码 188–192 行的宏定义与固件交互SDLS设备级的启用/禁用开关galaxybook_acpi_init在 probe 时先写入 1 启用退出时写入 0 禁用CSFI设置类请求键盘背光、电源管理/电池阈值、USB 充电、块录制、通知启用等CSXI性能模式专用方法通过 GUID 功能码 子码完成 list/get/set。所有请求与响应都封装在一个紧凑的 SAWB 缓冲区结构中源码 93–122 行struct sawb { u16 safn; /* 服务访问功能号固定为 0x5843 (GB_SAFN) */ u16 sasb; /* 子块号例如 0x78 键盘背光 / 0x7a 电源管理 / 0x8a 块录制 */ u8 rflg; /* 返回标志成功时为 0xaa */ union { ... u8 gunm; u8 guds[250]; ... } /* 通用号 通用数据 */ };galaxybook_acpi_method()223–278 行对每次调用都做三重校验响应缓冲区长度必须与请求一致、rflg必须等于成功码0xaa、gunm不得等于失败码0xff。这既保证了通信可靠性也构成了功能探测机制的基础。关键设计逐特性探测后才启用不同型号功能差异很大因此驱动采用请求-验证-注册的防御式初始化每个特性在注册设备LED 类、扩展属性、battery hook、sysfs 组之前都先通过galaxybook_enable_acpi_feature()280–300 行尝试启用并读取初始值凡是设备不支持的子块固件会返回非成功响应驱动便把该特性标记为不可用并跳过注册内部用正数的EOPNOTSUPP宏GB_NOT_SUPPORTED217 行与真正的错误码区分。所以同一份驱动在不同机型上呈现出的 sysfs 节点集合可能不同——文档也特别提醒并不是所有特性在你的机器上都一定可用。probe 的顺序同样有讲究源码 1385–1432 行的注释明确指出为避免某些机型初始化失败必须依次执行galaxybook_acpi_init() → SDLS 启用 安装 notify handler 启用 ACPI 通知 电源管理子块 galaxybook_platform_profile_init() → 性能模式platform profile galaxybook_battery_threshold_init() → 电池充电截止阈值 galaxybook_kbd_backlight_init() → 键盘背光 LED galaxybook_input_init() → Lens Cover 输入设备 galaxybook_fw_attrs_init() → firmware-attributes galaxybook_i8042_filter_install() → i8042 热键过滤键盘背光标准 LED 类接口支持键盘背光的机型上驱动注册一个名为samsung-galaxybook::kbd_backlight的 LED 类设备暴露在标准 sysfs LED 路径/sys/class/leds/samsung-galaxybook::kbd_backlight/通过写入brightness属性即可调节亮度范围 0–3源码 194 行GB_KBD_BACKLIGHT_MAX_BRIGHTNESS 3也可用任意用户态工具如brightnessctl控制# 查看当前亮度 cat /sys/class/leds/samsung-galaxybook::kbd_backlight/brightness # 设置为最亮 echo 3 | sudo tee /sys/class/leds/samsung-galaxybook::kbd_backlight/brightness # 关闭背光 echo 0 | sudo tee /sys/class/leds/samsung-galaxybook::kbd_backlight/brightness源码实现上364–399 行LED 设备的回调把读写直接翻译为对CSFI方法中键盘背光子块SASB0x78的get/set请求读取时brightness_get→kbd_backlight_acpi_get()返回固件当前亮度写入时brightness_set_blocking→kbd_backlight_acpi_set()把值写入数据字节。LED 注册时设置了LED_BRIGHT_HW_CHANGED标志394 行这与下面热键一节中led_classdev_notify_brightness_hw_changed()的配合密切相关——当热键在驱动内部改亮度时用户态能收到硬件变更通知。需要注意一个已知固件行为这些机器大多带环境光传感器在光线充足时固件会自动关闭键盘背光驱动目前无法控制该自动行为使用时可留意这一现象非故障。性能模式基于 platform profile 的动态映射性能模式通过内核标准化的 platform profile 接口暴露见仓库文档 Documentation/userspace-api/sysfs-platform_profile.rst。驱动注册时的 ops722–726 行只负责 profile 的 get/set而真正的关键在 probe 阶段的动态映射表构建galaxybook_platform_profile_probe651–720 行。底层性能模式码值从源码宏178–186 行可以看到三星固件定义了一组性能模式原始码值驱动把它们归类映射到标准 platform profile三星性能模式固件码值platform profile说明Fanoff0x0blow-power静音/低功耗Lownoise0x0aquiet安静模式Optimized0x00/ Optimized V20x02balanced平衡模式Performance0x01/ Performance V20x15/ Ultra0x16performance高性能模式0x14IGNORE1/0x0cIGNORE2—无映射被跳过对应到内核文档描述即Silent → low-power、Quiet → quiet、Optimized → balanced、High performance → performance。动态探测不是每个机型都全量支持驱动并不写死每个 profile 是否可用而是通过CSXI方法下发list子请求FNCN0x51, SUBN0x01从固件返回的iob0支持的模式数量和随后的码值列表逐项解析未识别的码值被忽略并打印ignoring unmapped performance mode 0x%x691 行同一 profile 若有多个等价码值如 Optimized 与 Optimized V2较新的 V2 码值会覆盖旧的695–708 行的 switch 逐项覆盖逻辑每个被支持的模式通过set_bit(profile, choices)打开对应 platform profile 选项。因此你的设备实际暴露的 profile 集合是固件支持 驱动映射的交集映射结果可在模块加载时的内核日志dmesg中看到dev_dbg级别需开启 dyndbg。用户态可读取的接口为/sys/firmware/acpi/platform_profile_choices # 列出可用 profile /sys/firmware/acpi/platform_profile # 读取/设置当前 profile读写示例cat /sys/firmware/acpi/platform_profile_choices cat /sys/firmware/acpi/platform_profile echo balanced | sudo tee /sys/firmware/acpi/platform_profile默认初始化为 balanced在驱动注册平台 profile 时如果固件列表里包含balanced会顺带把三星固件的性能模式初始化到 balanced 对应的码值源码 715–717 行test_bit(PLATFORM_PROFILE_BALANCED, choices)时调用performance_mode_acpi_set。这对应文档中模块加载时若之前未设置过 profile则默认使用 balanced的描述。电池充电截止阈值标准 charge_control_end_threshold驱动通过acpi_battery_hookbattery hook 机制注册名 Samsung Galaxy Book Battery Extension550 行为电池设备动态扩展属性只提供充电结束阈值end threshold不支持起始阈值start threshold。Windows 侧三星应用一般称之为 Battery SaverLinux 侧则复用了标准的 sysfs 属性位于电池设备上/sys/class/power_supply/BAT1/charge_control_end_threshold# 读取当前充电截止值单位% cat /sys/class/power_supply/BAT1/charge_control_end_threshold # 设置 80% 即停止充电 echo 80 | sudo tee /sys/class/power_supply/BAT1/charge_control_end_threshold源码中值得注意的两个细节100% 即关闭的语义转换固件内部用 0 表示无截止一直充满而标准接口用 100 表示关闭。驱动在读取时把 0 翻译成 100458–463 行在写入时把 100 翻译回 0487–492 行对外保持标准语义。取值范围写入值限定在 1–100 之间越界返回-EINVAL484–485 行。文档同时建议若希望与 Windows 侧 Samsung Settings 应用保持互操作应使用 100 表示off或只在 50 / 60 / 70 / 80 / 90 中取值启用该功能驱动本身则接受 1–100 中任意整数作为停止充电的百分比。另外文档提醒部分设备在收到小于 30 的输入值时固件会被观察到自动关闭充电截止功能即自动回到充满状态设置极低阈值时需留意实际固件行为。固件属性Firmware Attributes设备支持时驱动会在固件属性类目录下建立一组枚举型属性/sys/class/firmware-attributes/samsung-galaxybook/attributes/包含三个属性子目录源码 63–79 行的枚举与名字表一一对应属性含义取 1开取 0关power_on_lid_open开盖自动开机打开盖即上电关闭usb_chargingUSB 充电关机/低功耗状态下 USB 口仍可对外供电启用关闭block_recording屏蔽录制阻断摄像头与麦克风访问屏蔽允许它们都是布尔型枚举值possible_values固定为0;1default_value为0display_name_language_code为en_US.UTF-8源码 931–945 行。读写均通过current_value属性# 查看 cat /sys/class/firmware-attributes/samsung-galaxybook/attributes/power_on_lid_open/current_value # 开启开盖即开机 echo 1 | sudo tee /sys/class/firmware-attributes/samsung-galaxybook/attributes/power_on_lid_open/current_value # 启用 USB 充电 echo 1 | sudo tee /sys/class/firmware-attributes/samsung-galaxybook/attributes/usb_charging/current_value # 屏蔽摄像头与麦克风 echo 1 | sudo tee /sys/class/firmware-attributes/samsung-galaxybook/attributes/block_recording/current_value每个属性实际由独立的 get/set 回调驱动power_on_lid_open与block_recording走CSFI电源管理/块录制子块SASB0x7a/0x8ausb_charging则使用独立的读写子块号SASB_GET0x67, SASB_SET0x68。写路径被fw_attr_lock互斥保护以避免多线程并发更新固件属性造成冲突源码 41–42 行、985–991 行。特别地block_recording的写入会在成功后立刻向输入子系统发送一个SW_CAMERA_LENS_COVER开关事件源码 865–867 行input_report_switchinput_sync对应的输入设备名是 Samsung Galaxy Book Camera Lens Cover878–885 行注册。因此桌面环境可在摄像头被屏蔽时自动感知状态变化例如让隐私指示灯联动。固件属性注册同样是先探测再注册的只有power_on_lid_open_acpi_get/usb_charging_acpi_get返回成功才创建对应属性组1088–1106 行。Fn 热键的驱动内处理i8042 过滤为避免与桌面环境的通用键位映射冲突驱动向 i8042 控制器注册了一个按键过滤器galaxybook_i8042_filter1173–1218 行把下列 Fn 组合键的扫描码在输入栈入口处吞掉改由驱动自身执行动作热键触发动作FnF9键盘背光多级切换按键事件在驱动内被吃掉FnF10切换 block recording屏蔽/解除摄像头与麦克风过滤器只处理 i8042 扩展字节0xe0前缀之后的扫描码0x2c/0xac背光键 down/up、0x1f/0x9fblock recording 键 down/up还有电池相关的0x0f/0x8f该按键事件被静默吞掉因为电池状态已另有 ACPI 通知通道。其它按键则把此前暂存的0xe0重新注入serio_interrupt(port, 0xe0, 0)后放行保证不影响普通按键。FnF9循环切换背光档位keyup 时调度kbd_backlight_hotkey_work1126–1149 行读取当前亮度并循环0 → 1 → 2 → 3 → 0通过led_set_brightness_sync()写入固件再调用led_classdev_notify_brightness_hw_changed()广播硬件侧改变了亮度通知。这正是文档强调的模仿传统嵌入式控制器机型的行为——即背光由 EC 内部循环并由通知上抛用户态如 GNOME 的 LED 代理可据此同步状态。这里也解释了为什么 LED 注册时要设LED_BRIGHT_HW_CHANGED标志。FnF10切换 block recordingkeyup 时调度block_recording_hotkey_work1151–1171 行先读当前值再取反写入写入路径本身会像上文所述那样产生SW_CAMERA_LENS_COVER开关事件使系统状态与物理隐私开关保持同步。ACPI 通知与 FnF11 性能模式切换驱动在 probe 时通过acpi_install_notify_handler安装通知处理器1342–1343 行所有固件事件进入galaxybook_acpi_notify1253–1292 行已知事件码包括事件码含义驱动行为0x61电池状态变化忽略battery 子系统另有通道0x6c/0x6d设备上/下桌面table mode忽略0x70FnF11性能模式热键platform_profile_cycle()切换到下一个可用 profile0x7d键盘背光热键调度背光循环 work0x6e麦克风静音热键上报一次KEY_MICMUTE0x6f摄像头热键有 block_recording 则切换之否则上报SW_CAMERA_LENS_COVER翻转其中FnF11是驱动内部处理的性能模式热键每次按下会调用platform_profile_cycle()源码 1262–1264 行在设备支持的 profile 列表里循环到下一个等效于逐次执行echo next platform_profile。除驱动内处理外每个 ACPI 事件最终还会通过acpi_bus_generate_netlink_event()生成 ACPI netlink 事件1290 行其设备类class为samsung-galaxybookbus ID 为平台上 SCAI 设备的 ACPI 名称。用户态可用标准工具监听# 前台监听需 root sudo acpi_listen # 或用 acpid 配置规则响应此时按下 Fn 组合键或发生固件事件即可看到samsung-galaxybook ...前缀的 netlink 行供脚本或桌面组件消费。尚未实现的能力文档明确列出以下功能目前未实现需要更多逆向与固件研究使用中不要期望它们生效扬声器 Dolby Atmos 模式SAM0427型号上的 Outdoor Mode室外高亮模式提高屏幕亮度SAM0427型号上的 Silent Mode。小结与调试建议samsung-galaxybook驱动把三星私有的 SCAI ACPI 通道翻译为一组 Linux 标准接口LED 类键盘背光、platform profile性能模式、power_supply 扩展属性充电截止、firmware-attributes固件开关以及输入子系统事件隐私开关/麦克风。其逐特性探测、动态注册的设计让一份代码安全覆盖差异巨大的多代 Galaxy Book 机型。上手排障时可按下面顺序核对确认硬件匹配dmesg | grep -i samsung或检查/sys/bus/platform/devices/下是否存在匹配 SAM0xxx/SAMB430 的 SCAI 平台设备确认模块已加载lsmod | grep samsung_galaxybook注意模块文件名为samsung-galaxybook.ko逐项验证特性节点是否出现不同机型集合不同/sys/class/leds/samsung-galaxybook::kbd_backlight、/sys/firmware/acpi/platform_profile_choices、/sys/class/power_supply/BAT1/charge_control_end_threshold、/sys/class/firmware-attributes/samsung-galaxybook/attributes/想看更细的初始化日志可开启驱动的动态调试echo module samsung_galaxybook p | sudo tee /sys/kernel/debug/dynamic_debug/control sudo dmesg -w此时每个特性的探测失败原因如failed to enable kbd_backlight feature、ignoring unmapped performance mode等都会清晰打印便于判断是设备不支持还是通信异常。阅读提示驱动完整源码见 samsung-galaxybook.c平台 profile 的标准用户态接口规范见 Documentation/userspace-api/sysfs-platform_profile.rst对应 ABI 文档见 Documentation/ABI/testing/sysfs-platform_profile。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表