LINUX.ORG.RU

PCI driver

 , ,


2

1

Debian 10

Всем привет! Друзья подскажите почему printk не выводит в dmesg?

Вариант 1: что то с настройками системы.

Вариант 2: не вызываеться myPciDriverProbe из init функции, что уже хуже и более вероятно. Тогда от сюда следующий вопрос - почему myPciDriverProbe не вызывается, ведь pci_get_device находит устройсво?

pci_register_driver возвращает 0

Заранее спасибо.

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Drakonof");
MODULE_DESCRIPTION("PCI");
MODULE_VERSION("0.1");

#define VENDOR	0x8086
#define ID	0x0150


static struct pci_device_id pciId[] = {
	{ PCI_DEVICE(0x8086, 0x0150), },
	{ 0, }
};


MODULE_DEVICE_TABLE(pci, pciId);


static int myPciDriverProbe(struct pci_dev *pDev, const struct pci_device_id *id);
static void myPciDriverRemove(struct pci_dev *pDev);

static struct pci_driver myDriver = {
	.name = "my pci driver",
	.id_table = pciId,
	.probe = myPciDriverProbe,
	.remove = myPciDriverRemove
};

static int __init myPciDriverInit(void)
{
	struct pci_dev *pDev = NULL;

	printk(KERN_NOTICE "Init PCI start\n" );
	

	if((pDev = pci_get_device(VENDOR,ID, pDev)) != NULL) 
	{
		printk(KERN_NOTICE "V:%X D:%X finded\n",pDev->vendor,pDev->device);
		
	}
	else
	{
		printk(KERN_NOTICE "PCI device not finded\n");
		return -1;
	}
	
	printk(KERN_NOTICE "Init PCI stop\n" );
	return pci_register_driver(&myDriver);
}

static void __exit myPciDriverExit(void)
{
	pci_unregister_driver(&myDriver);
}

static int myPciDriverProbe(struct pci_dev *pDev, const struct pci_device_id *id)
{
	u16 vendor, id;

	pci_read_config_word(pDev, PCI_VENDOR_ID, &vendor);
	pci_read_config_word(pDev, PCI_DEVICE_ID, &id);

	printk(KERN_ERR "Device vid: 0x%X  pid: 0x%X\n", vendor, id);

	return 0;
}

static void myPciDriverRemove(struct pci_dev *pDev)
{

	pci_release_region(pDev, pci_select_bars(pDev, IORESOURCE_MEM));
	pci_disable_device(pDev);
}

module_init(myPciDriverInit);
module_exit(myPciDriverExit);




Последнее исправление: Drakonoff (всего исправлений: 1)

Ответ на: комментарий от Drakonoff

лана... давай зайдем с другой стороны, что у тебы в конфиге ядра?
у меня
$ grep PRINTK ~/devel/linux-5.2.16/.config
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_TTY_PRINTK=m
CONFIG_TTY_PRINTK_LEVEL=6
# CONFIG_SND_VERBOSE_PRINTK is not set
CONFIG_PRINTK_TIME=y
# CONFIG_PRINTK_CALLER is not set
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not set
# CONFIG_EARLY_PRINTK_USB_XDBC is not set

metawishmaster ★★★★★
()

Попробуй без восхода/заката сонца вручную

module_pci_driver(myDriver);

вместо

static int __init myPciDriverInit(void)
{
	struct pci_dev *pDev = NULL;

	printk(KERN_NOTICE "Init PCI start\n" );
	

	if((pDev = pci_get_device(VENDOR,ID, pDev)) != NULL) 
	{
		printk(KERN_NOTICE "V:%X D:%X finded\n",pDev->vendor,pDev->device);
		
	}
	else
	{
		printk(KERN_NOTICE "PCI device not finded\n");
		return -1;
	}
	
	printk(KERN_NOTICE "Init PCI stop\n" );
	return pci_register_driver(&myDriver);
}

static void __exit myPciDriverExit(void)
{
	pci_unregister_driver(&myDriver);
}

module_init(myPciDriverInit);
module_exit(myPciDriverExit);
anonymous
()
Ответ на: комментарий от metawishmaster

извините я не очень опытный.

grep PRINTK ~/devel/linux-4.19.0/.config не может найти файл

где 4.19.0 моя версия ядра.

root@drakonof:~# sudo grep PRINTK ~/devel/linux-4.19.0/.config
grep: /root/devel/linux-4.19.0/.config: No such file or directory

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 3)
Ответ на: комментарий от Drakonoff

тогда уж лучше попробовать так:
sudo grep PRINTK /lib/modules/`uname -r`/build/.config

p.s.
а не выводится все, что выше по значению чем KERN_WARN?

#define KERN_EMERG «<0>» /* system is unusable*/
#define KERN_ALERT «<1>» /* action must be taken immediately*/
#define KERN_CRIT «<2>» /* critical conditions*/
#define KERN_ERR «<3>» /* error conditions*/
#define KERN_WARNING «<4>» /* warning conditions*/
#define KERN_NOTICE «<5>» /* normal but significant condition*/
#define KERN_INFO «<6>» /* informational*/
#define KERN_DEBUG «<7>» /* debug-level messages*/

p.s. перечитал топик
а если lsmod набрать, там твой модуль будет?

metawishmaster ★★★★★
()
Последнее исправление: metawishmaster (всего исправлений: 2)
Ответ на: комментарий от Drakonoff

и еще, делать что-то типа «return pci_register_driver(&myDriver);» - это к попаболи

грамонее все ответы функций, которые могут вернуть ошибку обрабатывать так:

// при условии, что func что-то отличное от нуля при ошибке
ret = func([arg list]);
if (ret) {
// освободить память, если что-то аллоцировал
    printk(KERN_ERR"error: блииин! в func косяк ;(");
    return ret;
}
// весело шагаем дальше
...

metawishmaster ★★★★★
()
Последнее исправление: metawishmaster (всего исправлений: 2)
Ответ на: комментарий от Drakonoff

я почитаю как это сделать

сбирать - make

vsn.c

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vasyan Vasyanov <v.vasyanov@linux.org.ru>");
MODULE_DESCRIPTION("PCI vasyan");
MODULE_VERSION("0.1");

#define PCI_VENDOR_ID_VASYANTECH  0x8086
#define PCI_DEVICE_ID_VSN1        0x0150

static const struct pci_device_id vsn1_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_VASYANTECH, PCI_DEVICE_ID_VSN1), },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, vsn1_pci_tbl);

static int vsn1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	dev_info(&pdev->dev, "device vid: 0x%X  pid: 0x%X\n",
		id->vendor, id->device);
	return 0;
}

static void vsn1_remove(struct pci_dev *pdev)
{
	dev_info(&pdev->dev, "bye\n");
}

static struct pci_driver vsn1_driver = {
	.name = KBUILD_MODNAME,
	.probe = vsn1_probe,
	.remove = vsn1_remove,
	.id_table = vsn1_pci_tbl,
};

module_pci_driver(vsn1_driver);

Makefile

ifneq ($(KERNELRELEASE),)
obj-m := vsn.o

else
KDIR ?= /lib/modules/`uname -r`/build

default:
	$(MAKE) -C $(KDIR) M=$$PWD
endif
anonymous
()

Попробуй KERN_EMERG или KERN_ALERT или KERN_CRIT. Вот прям со всеми тремя подряд, при старте модуля. Убедись что вообще хоть что то выводится

Надеюсь ты не забыл dmesg запустить???

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)
Ответ на: комментарий от metawishmaster

По

sudo grep PRINTK /lib/modules/`uname -r`/build/.config

выдаёт:

CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_PRINTK=y
CONFIG_PRINTK_NMI=y
CONFIG_TTY_PRINTK=m
# CONFIG_SND_VERBOSE_PRINTK is not set
CONFIG_PRINTK_TIME=y
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not set
CONFIG_EARLY_PRINTK_EFI=y
# CONFIG_EARLY_PRINTK_USB_XDBC is not set

где отсутвует

CONFIG_TTY_PRINTK_LEVEL=6

в lsmod модуль отображается

Module                  Size  Used by
test_pci_module        16384  0
intel_rapl             24576  0
x86_pkg_temp_thermal    16384  0
intel_powerclamp       16384  0

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

ERN_EMERG или KERN_ALERT или KERN_CRIT не работают.

dmesg запускаю

sudo dmesg | tail -n4

четырёх хватает что бы увидить как работает

Drakonoff
() автор топика
Ответ на: комментарий от Drakonoff

Но так же, к сожалению, не выводит

у тебя устройство физическое подключено и идентификаторы совпдают ? без этого естественно probe не сработает. Можешь так проверить

$ sudo insmod vsn.ko
$ dmesg
...
[ 6000.151567] vsn: loading out-of-tree module taints kernel.
[ 6000.151627] vsn: module verification failed: signature and/or required key missing - tainting kernel

$ lsmod | grep vsn
vsn                    16384  0

у меня нет твоего устройства - probe не срабатывает как видишь хоть драйвер и загружается. Есть неиспользуемый проводной изернет

$ lspci -nk
...
03:00.0 0200: 10ec:8168 (rev 07)
	Subsystem: 10ec:0123
	Kernel driver in use: r8169
	Kernel modules: r8169

меняю идентификаторы в vsn.c от этого устройства

if 0
#define PCI_VENDOR_ID_VASYANTECH  0x8086
#define PCI_DEVICE_ID_VSN1        0x0150
#endif

#define PCI_VENDOR_ID_VASYANTECH  0x10ec
#define PCI_DEVICE_ID_VSN1        0x8168

пересобираю модуль

make -C /lib/modules/`uname -r`/build M=$PWD clean
make

выгружаю родной риелетековский драйвер и vsn

$ sudo rmmod r8169
$ sudo rmmod vsn

подгружаю и выгружаю vsn c фейковыми идентифиакторами от риелтека

$ sudo insmod vsn.ko
$ sudo rmmod vsn
$ dmesg
...
[ 6415.071728] vsn 0000:03:00.0: device vid: 0x10EC  pid: 0x8168
[ 6442.175238] vsn 0000:03:00.0: bye
anonymous
()
Ответ на: комментарий от anonymous

Но а вообще, если отталкиваться от моего кода,

pci_register_driver(&myDriver);

может вернуть 0, но при этом не вызвать

myPciDriverProbe();

?

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 1)
Ответ на: комментарий от Drakonoff

pci_register_driver(&myDriver); может вернуть 0, но при этом не вызвать myPciDriverProbe();

конечно может - если нет устройства или идентификаторы vendor/device не совпадают то probe ядро не вызовет

anonymous
()
Ответ на: комментарий от anonymous

Попробовал с эзернетом (мой вендор и девайс совпадают с Вашими).

Всё заработало и ERN_EMERG и KERN_ALERT и KERN_CRIT. По всей идимости prob не вызывался, хотя все параметры проверял.

Я, вообще, под fpga и МК разрабатываю, просто решив освоить linux вызвался написать тест скорости PCIE+DMA из хоста в ddr плиса.

Можете подсказать как лучше организовать замер скорости трансфера некоторого массива из хоста (комп, рутсистем), если абстрогироваться от плиса, в эндпоит(по сути просто записать по бару)?

Да, и спасибо за помощь!

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 2)
Ответ на: комментарий от Drakonoff

Можете подсказать как лучше организовать замер скорости трансфера некоторого массива из хоста (комп, рутсистем), если абстрогироваться от плиса, в эндпоит(по сути просто записать по бару)?

можно смапить через mmap (отобразить в адресном пространстве CPU) нужный регион физической памяти

https://stackoverflow.com/a/44291508

и провести замер времени memcpy

anonymous
()
Ответ на: комментарий от Drakonoff

Посмотри еще тут пример - возможно что-то близко к тому что тебе нужно

https://elixir.bootlin.com/linux/v5.5.9/source/drivers/char/xillybus/

https://elixir.bootlin.com/linux/v5.5.9/source/drivers/char/xillybus/xillybus_pcie.c

ты похоже из какой-то макулатуры пример взял - так давно никто не пишет - в ядре есть управляемые ресурсы, об их осовобождении и корректном завершении не нужно беспокоиться. Вот тут есть описание от чувака котрый написал драйвер xillybus

http://www.haifux.org/lectures/323/

это вообще толковый чувак - есть чему поучиться

anonymous
()
Ответ на: комментарий от Drakonoff

Проблема была не в printk, а в моей нубости)

Пожалуйста, прошу не надо завершать темы так. «Ой это там у меня ошибка была, расходимся посоны». Как была решена проблема, каков итог? Это важно. Форум не техподдержка а база знаний, вопросы и главное ответы

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Подозреваю что там vendor/device прописаны неправильно, это бук асус с говноинтелом

00:00.0 0600: 8086:0154 (rev 09) Subsystem: 1043:107b Kernel driver in use: ivb_uncore

это то что проипсано в драйвере ТС

#define VENDOR	0x8086
#define ID	0x0150

вендор совсем не VASYANTECH

anonymous
()
Ответ на: комментарий от anonymous

А ну так да, PCI VID/PID попало на существующее устройство, так совпало и тогда драйвер уже не полетит, очевидно. Не вызовется настройка драйвера в принципе

Вот поэтому начинают с простого hello_world.ko, где он просто загружается и printk

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от mv

Тем более нужно использовать новый способ печати, если уж драйвер писисяйный dev_info dev_err и прочие dev_dbg. Хотя на первых порах printk сойдет

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

На первых порах и русский подойдёт, если английский никак не идёт.

mv ★★★★★
()
Ответ на: комментарий от anonymous

можно смапить через mmap

вспомнил тут еще - можно не писать никакой кот а использовать готовые средства ОС

https://wiki.archlinux.org/index.php/Swap_on_video_RAM

можно аналогичным образом из метода 1 использовать модуль slram подсистемы MTD для создания блочного устройства в RAM подключенной через FPGA

http://lists.infradead.org/pipermail/linux-mtd/2002-January/003872.html

и измерять время копирования файлов

anonymous
()
Ответ на: комментарий от mv

To be забыл вставит, прямо трагедия, или по вашему мнению perfect здесь лучше подойдет? а артикль какой the или a?

Прошу продемонстрируйте знание

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

Я подумал что и так ясно, ошибка в неправильном указание вендора и девайса, как следствие prob не вызывался и printk не печатал.

Drakonoff
() автор топика
Ответ на: комментарий от mv

печатья(ЯДР_УВЕДОМЛЕНИЕ "

удваиваю, дичь какая-то

anonymous
()
Ответ на: комментарий от mv

да мне, если честно, всё равно.. не правильный глагол to find, was not,по барабану, я для себя писал, а не для королевы англии.

Всем спасибо за помощь, кроме mv. Хотя нет ему отдельное, теперь буду грамматику соблюдать, что бы подобные товарищи от основной темы не отвлекали.

Drakonoff
() автор топика
Последнее исправление: Drakonoff (всего исправлений: 1)
Ответ на: комментарий от Drakonoff

Пиши на языке, который знаешь (хотя, ты и русский не знаешь).

На вот системтап, если сомневаешься, что функции твоей поделки вызываются:

systemtap-4.2/testsuite/systemtap.examples/general/callgraph.stp

#! /usr/bin/env stap

function trace(entry_p)
{
  printf("%s%s%s\n",
         thread_indent (entry_p),
         (entry_p>0?"->":"<-"),
         ppfunc ())
}

probe $1.call   { trace(1) }
probe $1.return { trace(-1) }

Запускать: stap -v callgraph.stp 'module(«твояподелка»).function(«*»)'

mv ★★★★★
()
Ответ на: комментарий от anonymous

С этим я разобрался, всё работает отлично, но со скоростью около 500 Мб/с.

Теперь я начал с DMA разбираться. На сколько я понял, нужно выделить кусок физической памяти и сопоставить его с шинной pcie.

В теле функции probe:

// адрес буфера dma в ПК
dma_addr_t dma_addr;

// дескриптор DMA буфера
struct dma_desc {
	void *addr;
	size_t size;
} desc1;

// выделение памяти для буфера
desc1.addr = kzalloc(1024, GFP_KERNEL | GFP_DMA);
desc1.size = 1024;

// получение адреса DMA буфера на шине
dma_addr = dma_map_single(&p_dev->dev, desc1.addr, desc1.size, DMA_TO_DEVICE);

// проверка на ошибку
if (dma_mapping_error(&p_dev->dev, dma_handle)) {
	printk(KERN_INFO "dma mapping error\n");
}

// забираю буфер в ПК для инициализации
dma_sync_single_for_cpu(&p_dev->dev, dma_handle, 1024, DMA_TO_DEVICE);

for(i = 0; i < 10; i++)
{
	*(u8*)(desc1.addr + i )= i + 9;
}
     
// отдаю буфер обратно   
dma_sync_single_for_device(&p_dev->dev, dma_handle, 1024, DMA_TO_DEVICE);

// пишу source адрес регистр DMA в ПЛИС
iowrite32(dma_addr, p_priv_str->memFromBar + SA);
// пишу регистр адреса назначения в DMA в ПЛИС, это адрес DDR
iowrite32(0x80000000, p_priv_str->memFromBar + DA);
// сколько байт писать, это запускает передачу данных
iowrite32(1024, p_priv_str->memFromBar + BTT);

все регистры пишутся, статусы выставляются, но данные не идут. Я думаю изза того что адрес источник DMA берет оносительно ПЛИС, а не ПК. Не могу понять что не так.

Drakonoff
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.