手搓华为笔记本指纹驱动时卡壳了

下载华为指纹驱动时,网站 https://gitee.com/houko/goodix-fp-dkmshttps://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(&reg_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, &reg_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 骗过吗