下载华为指纹驱动时,网站 https://gitee.com/houko/goodix-fp-dkms 和 https://aur.archlinux.org/packages/goodix-fp-dkms 进不去
我只好手搓了……
【终极兜底方案:完全手动编写驱动】在我这约等于用一小瓶布洛芬治疗烧伤病人
AI里给的github网址是编造的
可是我就想手搓驱动
手搓的话也是建议找找相关的帖子论坛,问ai,十个ai告你九个答案,还有一个系统繁忙,请稍候再试
那就去好好看书。

是这个设备吗?我也想要这个设备的驱动(华为MateBook X pro 2019款的)
我并不懂驱动开发,但是也让ai写了一个可以读写这个设备中的内存的测试驱动,看不懂,但是我大为震撼。第一次的时候读取到了很多非零的数据,重启过后地址变了,ai说是mmio_phys这个地址没整对,第一次成功是因为编写的时候用的就是当时的地址,写死在代码里的,这个地址要动态获取,但是,ai怎样都写不对动态获取,奈何本人完全看不懂,就到此为止了
关于你的问题,你的图中的问题是makefile没写对,内核sdk中的makefile会回过头来找你的makefile中定义的obj-m这个变量,而你设置的路径下完全不存在一个Makefile,所以失败了。
附上ai写的代码:
// goodix_fp.c - Goodix 指纹传感器驱动
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define DRIVER_NAME "goodix-fingerprint"
#define MMIO_SIZE 0x8000
// DSM UUID: cc58b68a-4479-4893-a8bb-961209db59e5
static const guid_t goodix_dsm_guid =
GUID_INIT(0xcc58b68a, 0x4479, 0x4893,
0xa8, 0xbb, 0x96, 0x12, 0x09, 0xdb, 0x59, 0xe5);
struct goodix_fp_data {
struct platform_device *pdev;
void __iomem *mmio_base;
resource_size_t mmio_phys;
resource_size_t mmio_size;
struct gpio_desc *reset_gpio;
int irq;
struct miscdevice misc;
bool device_open;
};
static struct goodix_fp_data *g_data;
// 调用 ACPI _DSM 方法
static int goodix_dsm_call(struct goodix_fp_data *data, int func,
union acpi_object *argv4,
union acpi_object **result)
{
acpi_handle handle = ACPI_HANDLE(&data->pdev->dev);
union acpi_object *obj;
if (!handle) {
dev_err(&data->pdev->dev, "No ACPI handle\n");
return -ENODEV;
}
obj = acpi_evaluate_dsm(handle, &goodix_dsm_guid, 1, func, argv4);
if (!obj) {
dev_err(&data->pdev->dev, "DSM call %d failed\n", func);
return -EIO;
}
if (result)
*result = obj;
else
ACPI_FREE(obj);
return 0;
}
// 读取 MMIO 寄存器
static u32 goodix_read32(struct goodix_fp_data *data, u32 offset)
{
if (offset >= data->mmio_size)
return 0;
return ioread32(data->mmio_base + offset);
}
// 写入 MMIO 寄存器
static void goodix_write32(struct goodix_fp_data *data, u32 offset, u32 value)
{
if (offset >= data->mmio_size)
return;
iowrite32(value, data->mmio_base + offset);
}
// 中断处理函数
static irqreturn_t goodix_fp_irq_handler(int irq, void *dev_id)
{
struct goodix_fp_data *data = dev_id;
dev_info(&data->pdev->dev, "IRQ triggered!\n");
// TODO: 读取状态寄存器,处理中断
return IRQ_HANDLED;
}
// 文件操作: open
static int goodix_fp_open(struct inode *inode, struct file *file)
{
if (g_data->device_open)
return -EBUSY;
g_data->device_open = true;
file->private_data = g_data;
dev_info(&g_data->pdev->dev, "Device opened\n");
return 0;
}
// 文件操作: release
static int goodix_fp_release(struct inode *inode, struct file *file)
{
struct goodix_fp_data *data = file->private_data;
data->device_open = false;
dev_info(&data->pdev->dev, "Device closed\n");
return 0;
}
// 文件操作: read - 读取 MMIO 数据
static ssize_t goodix_fp_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct goodix_fp_data *data = file->private_data;
size_t available;
u8 *kbuf;
int i;
if (*ppos >= data->mmio_size)
return 0;
available = min(count, (size_t)(data->mmio_size - *ppos));
kbuf = kmalloc(available, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
// 读取 MMIO 数据
for (i = 0; i < available; i++)
kbuf[i] = ioread8(data->mmio_base + *ppos + i);
if (copy_to_user(buf, kbuf, available)) {
kfree(kbuf);
return -EFAULT;
}
kfree(kbuf);
*ppos += available;
return available;
}
// IOCTL 命令定义
#define GOODIX_IOC_MAGIC 'G'
#define GOODIX_IOC_READ_REG _IOR(GOODIX_IOC_MAGIC, 1, u32)
#define GOODIX_IOC_WRITE_REG _IOW(GOODIX_IOC_MAGIC, 2, u32[2])
#define GOODIX_IOC_DSM_CALL _IOWR(GOODIX_IOC_MAGIC, 3, u32)
#define GOODIX_IOC_GET_INFO _IOR(GOODIX_IOC_MAGIC, 4, u32[4])
// 文件操作: ioctl
static long goodix_fp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct goodix_fp_data *data = file->private_data;
u32 reg_data[2];
u32 info[4];
int ret = 0;
switch (cmd) {
case GOODIX_IOC_READ_REG:
if (copy_from_user(®_data[0], (void __user *)arg, sizeof(u32)))
return -EFAULT;
reg_data[1] = goodix_read32(data, reg_data[0]);
if (copy_to_user((void __user *)arg, ®_data[1], sizeof(u32)))
return -EFAULT;
break;
case GOODIX_IOC_WRITE_REG:
if (copy_from_user(reg_data, (void __user *)arg, sizeof(reg_data)))
return -EFAULT;
goodix_write32(data, reg_data[0], reg_data[1]);
break;
case GOODIX_IOC_GET_INFO:
info[0] = (u32)data->mmio_phys;
info[1] = (u32)(data->mmio_phys >> 32);
info[2] = (u32)data->mmio_size;
info[3] = data->irq;
if (copy_to_user((void __user *)arg, info, sizeof(info)))
return -EFAULT;
break;
default:
ret = -ENOTTY;
}
return ret;
}
static const struct file_operations goodix_fp_fops = {
.owner = THIS_MODULE,
.open = goodix_fp_open,
.release = goodix_fp_release,
.read = goodix_fp_read,
.unlocked_ioctl = goodix_fp_ioctl,
};
// 在 sysfs 中显示 MMIO 信息
static ssize_t mmio_info_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct goodix_fp_data *data = dev_get_drvdata(dev);
return sprintf(buf, "MMIO base: 0x%llx\nMMIO size: 0x%llx\nIRQ: %d\n",
(u64)data->mmio_phys, (u64)data->mmio_size, data->irq);
}
static DEVICE_ATTR_RO(mmio_info);
// 读取前 256 字节的 MMIO 数据用于调试
static ssize_t mmio_dump_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct goodix_fp_data *data = dev_get_drvdata(dev);
int i, len = 0;
for (i = 0; i < 256 && len < PAGE_SIZE - 32; i += 4) {
u32 val = goodix_read32(data, i);
len += sprintf(buf + len, "%04x: %08x\n", i, val);
}
return len;
}
static DEVICE_ATTR_RO(mmio_dump);
// DSM 调用测试
static ssize_t dsm_test_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct goodix_fp_data *data = dev_get_drvdata(dev);
union acpi_object *result;
int func;
int ret;
if (kstrtoint(buf, 10, &func))
return -EINVAL;
ret = goodix_dsm_call(data, func, NULL, &result);
if (ret) {
dev_err(dev, "DSM call %d failed: %d\n", func, ret);
return ret;
}
dev_info(dev, "DSM call %d result type: %d\n", func, result->type);
if (result->type == ACPI_TYPE_BUFFER) {
int i;
dev_info(dev, "Buffer length: %d\n", result->buffer.length);
for (i = 0; i < min((int)result->buffer.length, 2048); i++)
dev_info(dev, " [%d] = 0x%02x\n", i, result->buffer.pointer[i]);
} else if (result->type == ACPI_TYPE_INTEGER) {
dev_info(dev, "Integer value: 0x%llx\n", result->integer.value);
}
ACPI_FREE(result);
return count;
}
static DEVICE_ATTR_WO(dsm_test);
static struct attribute *goodix_fp_attrs[] = {
&dev_attr_mmio_info.attr,
&dev_attr_mmio_dump.attr,
&dev_attr_dsm_test.attr,
NULL,
};
static const struct attribute_group goodix_fp_attr_group = {
.attrs = goodix_fp_attrs,
};
static int goodix_fp_probe(struct platform_device *pdev)
{
struct goodix_fp_data *data;
struct resource *res;
int ret;
dev_info(&pdev->dev, "Goodix fingerprint device probing...\n");
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->pdev = pdev;
platform_set_drvdata(pdev, data);
g_data = data;
// 获取 MMIO 资源
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res) {
data->mmio_phys = res->start;
data->mmio_size = resource_size(res);
dev_info(&pdev->dev, "MMIO resource: 0x%llx - 0x%llx (size: 0x%llx)\n",
(u64)res->start, (u64)res->end, (u64)data->mmio_size);
data->mmio_base = devm_ioremap(&pdev->dev, res->start, data->mmio_size);
if (!data->mmio_base) {
dev_err(&pdev->dev, "Failed to map MMIO\n");
return -ENOMEM;
}
dev_info(&pdev->dev, "MMIO mapped at %p\n", data->mmio_base);
} else {
// 如果没有自动获取到资源,手动映射已知地址
data->mmio_phys = 0x6f47c000;
data->mmio_size = 0x8000;
dev_info(&pdev->dev, "Using hardcoded MMIO: 0x%llx\n", (u64)data->mmio_phys);
if (!request_mem_region(data->mmio_phys, data->mmio_size, DRIVER_NAME)) {
dev_err(&pdev->dev, "Failed to request MMIO region\n");
return -EBUSY;
}
data->mmio_base = ioremap(data->mmio_phys, data->mmio_size);
if (!data->mmio_base) {
dev_err(&pdev->dev, "Failed to map MMIO\n");
release_mem_region(data->mmio_phys, data->mmio_size);
return -ENOMEM;
}
}
// 获取 IRQ
data->irq = platform_get_irq(pdev, 0);
if (data->irq > 0) {
ret = devm_request_irq(&pdev->dev, data->irq, goodix_fp_irq_handler,
IRQF_TRIGGER_LOW, DRIVER_NAME, data);
if (ret) {
dev_warn(&pdev->dev, "Failed to request IRQ %d: %d\n", data->irq, ret);
data->irq = -1;
} else {
dev_info(&pdev->dev, "IRQ %d registered\n", data->irq);
}
} else {
dev_info(&pdev->dev, "No IRQ available\n");
data->irq = -1;
}
// 尝试获取 GPIO
data->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(data->reset_gpio)) {
dev_warn(&pdev->dev, "Failed to get reset GPIO\n");
data->reset_gpio = NULL;
}
// ===================== 新增核心逻辑 =====================
// Step 1: 调用 DSM func=2 激活设备 (EC command 0xF0)
{
union acpi_object *res = NULL;
int r = goodix_dsm_call(data, 2, NULL, &res);
dev_info(&pdev->dev, "DSM func=2 (EC 0xF0): %d\n", r);
if (res) ACPI_FREE(res);
msleep(100); // 等待设备响应
}
// Step 2: 重新读取寄存器(扫描前 0x40 地址)
dev_info(&pdev->dev, "Post-init register dump:\n");
for (int i = 0; i < 0x40; i += 4) {
u32 val = goodix_read32(data, i);
if (val)
dev_info(&pdev->dev, " [0x%04x] = 0x%08x\n", i, val);
}
// ======================================================
// 创建 misc 设备
data->misc.minor = MISC_DYNAMIC_MINOR;
data->misc.name = "goodix_fp";
data->misc.fops = &goodix_fp_fops;
ret = misc_register(&data->misc);
if (ret) {
dev_err(&pdev->dev, "Failed to register misc device: %d\n", ret);
goto err_unmap;
}
// 创建 sysfs 属性
ret = sysfs_create_group(&pdev->dev.kobj, &goodix_fp_attr_group);
if (ret) {
dev_warn(&pdev->dev, "Failed to create sysfs group: %d\n", ret);
}
// 读取并打印前几个寄存器
dev_info(&pdev->dev, "Initial register dump:\n");
dev_info(&pdev->dev, " [0x0000] = 0x%08x\n", goodix_read32(data, 0x0000));
dev_info(&pdev->dev, " [0x0004] = 0x%08x\n", goodix_read32(data, 0x0004));
dev_info(&pdev->dev, " [0x0008] = 0x%08x\n", goodix_read32(data, 0x0008));
dev_info(&pdev->dev, " [0x000c] = 0x%08x\n", goodix_read32(data, 0x000c));
dev_info(&pdev->dev, "Goodix fingerprint driver loaded successfully\n");
dev_info(&pdev->dev, "Device node: /dev/goodix_fp\n");
return 0;
err_unmap:
if (!res) {
iounmap(data->mmio_base);
release_mem_region(data->mmio_phys, data->mmio_size);
}
return ret;
}
static void goodix_fp_remove(struct platform_device *pdev)
{
struct goodix_fp_data *data = platform_get_drvdata(pdev);
struct resource *res;
sysfs_remove_group(&pdev->dev.kobj, &goodix_fp_attr_group);
misc_deregister(&data->misc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res && data->mmio_base) {
iounmap(data->mmio_base);
release_mem_region(data->mmio_phys, data->mmio_size);
}
g_data = NULL;
dev_info(&pdev->dev, "Goodix fingerprint driver removed\n");
}
static const struct acpi_device_id goodix_fp_acpi_ids[] = {
{ "GXFP51B7", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, goodix_fp_acpi_ids);
static struct platform_driver goodix_fp_driver = {
.driver = {
.name = DRIVER_NAME,
.acpi_match_table = goodix_fp_acpi_ids,
},
.probe = goodix_fp_probe,
.remove = goodix_fp_remove,
};
module_platform_driver(goodix_fp_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Goodix Fingerprint Sensor Driver for Huawei MateBook X 2019");
MODULE_VERSION("0.1");
另外,我看了一下你与ai的会话,我可以确定的说这个会话中,ta已经开始出现严重幻觉了,dkms和这个设备没有任何关系,这个单词在ai的语义空间中和dump有点相似,导致ai幻觉更严重了。还有,华为的这个设备并不是什么usb设备,按照你的会话中的说法,是完全走不通的,这个设备是一个和电源键集成的设备,在acpi上,目前没有任何一个项目尝试逆向这个设备。
代码用 Markdown 代码块包裹一下吧。您现在的帖子中的代码已经被论坛系统渲染得面目全非了。
代码块语法如下:
```bash
#!/bin/sh
echo "Hello world!"
```
感谢提醒,第一次在这上面发言,没留意这还支持markdown语法
你之前也被 AI 骗过吗
