Я портирую модуль ядра lirc_serial для работы на нашей встроенной плате. Нам нужно только реализовать функцию ИК-передатчика.
Только для передатчика, пользовательский драйвер должен управлять только выводом RTS на /dev/ttyS0
, изнутри модуля.
На стандартном оборудовании драйвер загружается:
00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
НОВЫЙ ПОДХОД
Я не понял, как деактивировать текущий драйвер для последовательного порта, вместо того, чтобы создавать новый драйвер, как бы вы использовали текущий драйвер 8250-dw для изменения контакта RTS от имени моего модуля ядра? Как то так?
Использование линейных дисциплин в этой статье для драйвера скольжения выглядит многообещающе, просто возьмите slip.c и удалите сетевой код. Но для этого требуется программа пространства пользователя (slattach
или dip
), чтобы открыть / dev / ttyS0 и активировать дисциплину строки.
Возможно ли это (или хорошая идея) из модуля ядра?
В этом похожем вопросе Как мне открыть / записать / прочитать устройство uart из модуля ядра? , Ian Abbott предложил перенести serdev в ядро 4.9.
Это немного усложняется, и мы уже отстаем от графика. Есть ли более простой способ?
ОРИГИНАЛЬНЫЙ ВОПРОС
Однако встроенная плата (основанная на BayTrail Atom E3845 ) имеет контроллер последовательного порта в отображаемой памяти ввода-вывода:
80860F0A:00: ttyS0 at MMIO 0x90a0c000 (irq = 39, base_baud = 2764800) is a 16550A
80860F0A:01: ttyS1 at MMIO 0x90a0e000 (irq = 40, base_baud = 2764800) is a 16550A
Я новичок в разработке драйверов. Я думаю, 0x90a0c000
это физический адрес контроллера?
Чтобы проверить модуль, я сначала переназначил 0x90a0c000
на виртуальный адрес, используя ioremap_nocache
, а затем попытался зарезервировать память, используя request_mem_region
. Это не удалось.
ioVirtBase = ioremap_nocache(iommap, 8);
TQTRACE("ecp_serial_probe: devm_ioremap for MMIO 0x%X returned 0x%X\n", (uint32_t)iommap, (uint32_t)ioVirtBase);
if (ioVirtBase != NULL)
{
tqDumpBuffer(ioVirtBase, 8);
}
tqRes = request_mem_region((uint32_t)ioVirtBase, 8, ECP_DRIVER_NAME);
TQTRACE("ecp_serial_probe: request_mem_region for 0x%X returned 0x%X\n", (uint32_t)ioVirtBase, (uint32_t)tqRes);
if (!tqRes)
{
TQTRACE("ecp_serial_probe: Cannot request memory at 0x%X\n", (uint32_t)iommap);
return -ENXIO;
}
Это правильный порядок функций?
Кроме того, кажется, что request_mem_region
дает сбой, потому что устройство находится под контролем 80860F0A
?? В lsmod
такой записи нет, но в /sys/devices
.
Нужно ли выгружать этот драйвер для управления USART? Как?
# ls -l /sys/devices/platform/80860F0A\:00
lrwxrwxrwx 1 root root 0 Jul 8 23:30 driver -> ../../../bus/platform/drivers/dw-apb-uart
-rw-r--r-- 1 root root 4096 Jul 9 17:02 driver_override
lrwxrwxrwx 1 root root 0 Jul 9 17:14 firmware_node -> ../../LNXSYSTM:00/LNXSYBUS:00/80860F0A:00
-r--r--r-- 1 root root 4096 Jul 9 17:02 modalias
drwxr-xr-x 2 root root 0 Jul 9 17:02 power
lrwxrwxrwx 1 root root 0 Jul 8 23:30 subsystem -> ../../../bus/platform
drwxr-xr-x 3 root root 0 Jul 8 23:30 tty
-rw-r--r-- 1 root root 4096 Jul 9 17:02 uevent
drwxr-xr-x 3 root root 0 Jul 8 23:30 VCOM0001:00
вывод dmesg ниже. Сброс данных по переназначенному виртуальному адресу не согласован. Иногда все 0xFF, иногда 00 00 00 00 41 02 1C 48
. Я тоже этого не понимаю ...
MARK Tue Jul 9 17:45:35 SGT 2019
ecp_serial: ecp_serial_exit_module()
Spectre V2 : System may be vulnerable to spectre v2
ecp_serial: loading module not compiled with retpoline compiler.
ecp_serial: ecp_serial_init_module()
ecp_serial: ecp_serial_init()
ecp_serial: ecp_serial_probe() iommap=0x90A0C000
ecp_serial: ecp_serial_probe: devm_ioremap for MMIO 0x90A0C000 returned 0xE3296000
ecp_serial: Dump address 0xE3296000:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000 FF FF FF FF FF FF FF FF
ecp_serial: ecp_serial_probe: request_mem_region for 0xE3296000 returned 0x0
ecp_serial: ecp_serial_probe: Cannot request memory at 0x90A0C000
platform ecp_serial.0: lirc_dev: driver ecp_serial registered at minor = 0
MARK Tue Jul 9 17:46:08 SGT 2019
ecp_serial: ecp_serial_exit_module()
Spectre V2 : System may be vulnerable to spectre v2
ecp_serial: loading module not compiled with retpoline compiler.
ecp_serial: ecp_serial_init_module()
ecp_serial: ecp_serial_init()
ecp_serial: ecp_serial_probe() iommap=0x90A0C000
ecp_serial: ecp_serial_probe: devm_ioremap for MMIO 0x90A0C000 returned 0xE32A2000
ecp_serial: Dump address 0xE32A2000:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000 00 00 00 00 41 02 1C 48
ecp_serial: ecp_serial_probe: request_mem_region for 0xE32A2000 returned 0x0
ecp_serial: ecp_serial_probe: Cannot request memory at 0x90A0C000
platform ecp_serial.0: lirc_dev: driver ecp_serial registered at minor = 0
Что говорит proc / iomem
90a0c000-90a0cfff : 80860F0A:00
90a0e000-90a0efff : 80860F0A:01
Так что, действительно, память находится под контролем другого драйвера ... Но как выгрузить ее, если она не указана в lsmod
?
# rmmod 80860F0A:00
ERROR: Module 80860F0A:00 does not exist in /proc/modules
# rmmod 80860F0A
ERROR: Module 80860F0A does not exist in /proc/modules
OS INFO
# uname -a
Linux ecp 4.4.127-1.el6.elrepo.i686 #1 SMP Sun Apr 8 09:44:43 EDT 2018 i686 i686 i386 GNU/Linux
# cat /etc/centos-release
CentOS release 6.6 (Final)