doom13 0 13 августа, 2015 Опубликовано 13 августа, 2015 · Жалоба Посмотрел примеры драйверов, все, оказывается, пользуются read, write??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 7 13 августа, 2015 Опубликовано 13 августа, 2015 · Жалоба "Нативными" методами работы с драйверами устройств являются open,read,write,close. fopen,fread,fwrite,fclose - это уже функции библитеки libc, они удобны для работы с файлами, как с потоками данных (stream), поэтому читают из устройства (как бы файла) сразу большими блоками и буферизируют внутри себя данные. Это позволяет добиться существенного выиграша в скорости при работе с файловой системой, даже если верхний уровень читает по 16 байт, в "глубине души" чтение идёт блоками, удобными устройству и буферизируется, а когда юзер снова попросит следующие 16 байт, уже ничего читать не нужно, можно скопировать из буфера уже прочитанное... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 14 августа, 2015 Опубликовано 14 августа, 2015 · Жалоба Ясно, пользуемся open, read, write, close и всё будет работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 17 августа, 2015 Опубликовано 17 августа, 2015 · Жалоба Откуда взялся номер 11 в конфигурационной области? Если его пишет система (или BIOS), то почему после переопределения номера линии прерывания он не переписывается на правильный? Полагаю, что он задается в device tree. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 30 сентября, 2015 Опубликовано 30 сентября, 2015 · Жалоба Приветствую! Возник вопрос, какой максимальный размер памяти с непрерывной адресацией можно выделить в ядре? Посмотрел, что kmalloc, dma_alloc_coherent максимум дают 4МБ, что делать если хочу больше? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 30 сентября, 2015 Опубликовано 30 сентября, 2015 · Жалоба Если использовать alloc_pages, то вообще выделяет только 8 страниц, далее выдаёт ошибку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 15 декабря, 2015 Опубликовано 15 декабря, 2015 · Жалоба Приветствую. В функции инициализации модуля pcievx7_init хочу добраться до struct pci_dev *pdev, вроде как должно помочь container_of, но получаются разные значения для pdev и my_pdev. Может кто подскажет, что тут неправильно? Значения pdev->driver и &pcievx7_pci_driver одинаковы. static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { ... PINFO("pdev = %p\n", pdev); PINFO("pdev->driver = %p\n", pdev->driver); // выводит в syslog адрес pcievx7_pci_driver = DRIVER_ADDRESS ... } static struct pci_driver pcievx7_pci_driver = { .name = DRIVER_NAME, .probe = pcievx7_probe, .remove = pcievx7_remove, .id_table = pcievx7_pci_driver_ids }; static int __init pcievx7_init(void) { struct pci_dev *my_pdev; ... pci_register_driver(&pcievx7_pci_driver); PINFO("&pcievx7_pci_driver = %p\n", &pcievx7_pci_driver); // выводит в syslog адрес pcievx7_pci_driver = DRIVER_ADDRESS my_pdev = container_of(&pcievx7_pci_driver, struct pci_dev, driver); PINFO("my_pdev = %p\n", my_pdev); ... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tarbal 4 16 декабря, 2015 Опубликовано 16 декабря, 2015 · Жалоба Я бы поле имени pdev->driver->name напечатал в консоль для обоих. Может помочь понять. Перед печатью проверьте если pdev->driver не равен нулю иначе система рухнет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 16 декабря, 2015 Опубликовано 16 декабря, 2015 · Жалоба Я бы поле имени pdev->driver->name напечатал в консоль для обоих. Может помочь понять. Перед печатью проверьте если pdev->driver не равен нулю иначе система рухнет. Если правильно Вас понял, то сделал это: static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { PINFO("%s\n", pdev->driver->name); // выводит в syslog имя драйвера "pcievx7" } static struct pci_driver pcievx7_pci_driver = { .name = DRIVER_NAME, .probe = pcievx7_probe, .remove = pcievx7_remove, .id_table = pcievx7_pci_driver_ids }; static int __init pcievx7_init(void) { pci_register_driver(&pcievx7_pci_driver); PINFO("%s\n", (&pcievx7_pci_driver)->name); // выводит в syslog имя драйвера "pcievx7" } Имя драйвера в обоих случаях одинаково. Вопрос остался. Попробовал сделать так: static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { struct pci_dev *test_pdev; test_pdev = container_of(pdev->driver, struct pci_dev, driver); PINFO("%p\n", test_pdev); PINFO("%p\n", pdev); } Получаю разные значения для test_pdev и pdev. Объясните, что тут неправильно? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
doom13 0 16 декабря, 2015 Опубликовано 16 декабря, 2015 · Жалоба Надо было так: static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { struct pci_dev *test_pdev; test_pdev = container_of(&pdev->driver, struct pci_dev, driver); PINFO("%p\n", test_pdev); PINFO("%p\n", pdev); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 16 июля, 2016 Опубликовано 16 июля, 2016 · Жалоба Если использовать alloc_pages, то вообще выделяет только 8 страниц, далее выдаёт ошибку. Так это же известнейшее ограничение что нельзя сразу много страниц вподряд выделить. Для этого надо использовать SG-DMA подход (LDD3, 15.4. Direct Memory Access). Я как раз сам в процессе освоения этого. У Вас что-то получилось по этой теме? Куча вопросов, я пока только смог сделать запись и чтение регистров своего устройства через MMIO... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dimidrol 0 16 июля, 2016 Опубликовано 16 июля, 2016 · Жалоба Так это же известнейшее ограничение что нельзя сразу много страниц вподряд выделить. В последних ядрах есть CMA (Contiguous Memory Allocator), в принципе можно выделить и подряд много, сам пробовал, получалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 16 июля, 2016 Опубликовано 16 июля, 2016 · Жалоба В последних ядрах есть CMA (Contiguous Memory Allocator), в принципе можно выделить и подряд много, сам пробовал, получалось. Я может что-то не понимаю, но меня искренне удивляет что работа устройства будет отдана воле случая, выделится а может нет - зачем такое делать? Допустим в системе 16 гигабайт ОЗУ. CMA может выделить буфер 5 гигабайт? Я знаю что так делать не хорошо, но что если будет некоторое устройство, которому именно что требуется это, и пользователь будет предупрежден что именно столько надо для работы устройства. Я сторонник исключительно 100% надежно работающих подходов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dimidrol 0 16 июля, 2016 Опубликовано 16 июля, 2016 · Жалоба Я может что-то не понимаю, но меня искренне удивляет что работа устройства будет отдана воле случая, выделится а может нет - зачем такое делать? Допустим в системе 16 гигабайт ОЗУ. CMA может выделить буфер 5 гигабайт? Я знаю что так делать не хорошо, но что если будет некоторое устройство, которому именно что требуется это, и пользователь будет предупрежден что именно столько надо для работы устройства. Я сторонник исключительно 100% надежно работающих подходов. Я так понимаю, если в системе только один драйвер использует подобный алгоритм выделения памяти, то вообще никаких проблем не будет, если несколько, то надо следить за суммарным размером области. В целом да, специфично, но зато можно без SGDMA обойтись. Да и производительность чуть-чуть будет повыше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться