В выхлопе ругается на Код (Text): tm.c:3:24: fatal error: linux/init.h: No such file or directory стоит его отыскать и положить куда надо, то появятся другие. И по мере уступок (искать и ложить) ошибок будет больше и в конце концов буде ругаться на содержимое Си файла.... типа я не знаю, и я не умею, и я не понимаю и т.п. Одним словом linux-headers надо полноценный. Как его сделать? Вот делал так: Код (Text): make ARCH=arm CROSS_COMPILE=/usr/bin/arm-none-eabi- INSTALL_HDR_PATH=/home/tmp/123 headers_install Вот из этой подсказки: Код (Text): root@debian:/home/kto/Загрузки/at91sam9260_Linux_board/linux-at91-wilc_15_4_1# make help Cleaning targets: clean - Remove most generated files but keep the config and enough build support to build external modules mrproper - Remove all generated files + config + various backup files distclean - mrproper + remove editor backup and patch files Configuration targets: config - Update current config utilising a line-oriented program nconfig - Update current config utilising a ncurses menu based program menuconfig - Update current config utilising a menu based program xconfig - Update current config utilising a Qt based front-end gconfig - Update current config utilising a GTK+ based front-end oldconfig - Update current config utilising a provided .config as base localmodconfig - Update current config disabling modules not loaded localyesconfig - Update current config converting local mods to core defconfig - New config with default from ARCH supplied defconfig savedefconfig - Save current config as ./defconfig (minimal config) allnoconfig - New config where all options are answered with no allyesconfig - New config where all options are accepted with yes allmodconfig - New config selecting modules when possible alldefconfig - New config with all symbols set to default randconfig - New config with random answer to all options listnewconfig - List new options olddefconfig - Same as oldconfig but sets new symbols to their default value without prompting kvmconfig - Enable additional options for kvm guest kernel support xenconfig - Enable additional options for xen dom0 and guest kernel support tinyconfig - Configure the tiniest possible kernel testconfig - Run Kconfig unit tests (requires python3 and pytest) Other generic targets: all - Build all targets marked with [*] * vmlinux - Build the bare kernel * modules - Build all modules modules_install - Install all modules to INSTALL_MOD_PATH (default: /) dir/ - Build all files in dir and below dir/file.[ois] - Build specified target only dir/file.ll - Build the LLVM assembly file (requires compiler support for LLVM assembly generation) dir/file.lst - Build specified mixed source/assembly target only (requires a recent binutils and recent build (System.map)) dir/file.ko - Build module including final link modules_prepare - Set up for building external modules tags/TAGS - Generate tags file for editors cscope - Generate cscope index gtags - Generate GNU GLOBAL index kernelrelease - Output the release version string (use with make -s) kernelversion - Output the version stored in Makefile (use with make -s) image_name - Output the image name (use with make -s) headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH (default: ./usr) /bin/sh: 3: Syntax error: Unterminated quoted string Makefile:1482: ошибка выполнения рецепта для цели «help» make: *** [help] Ошибка 2 root@debian:/home/kto/Загрузки/at91sam9260_Linux_board/linux-at91-wilc_15_4_1# Вот даже тут что-то криво.
И ещё: Код (Text): root@debian:/home/kto/Загрузки/at91sam9260_Linux_board/linux-at91-wilc_15_4_1# make ARCH=arm CROSS_COMPILE=/usr/bin/arm-none-eabi- INSTALL_MOD_PATH=/home/tmp/123m modules_install cp: не удалось выполнить stat для «./modules.builtin.modinfo»: Нет такого файла или каталога Makefile:1352: ошибка выполнения рецепта для цели «_modinst_» make: *** [_modinst_] Ошибка 1 root@debian:/home/kto/Загрузки/at91sam9260_Linux_board/linux-at91-wilc_15_4_1# То же что-то не так.
Опять косяк. Вроде собрал, но компиляция не проходит. Вот этот делал на самой плате: Код (Text): bash-3.2# /usr/bin/gcc -I/lib/modules/kernel/2.6.27/build/include -Wall -DMODULE -D__KERNEL__ -D_LINUX -v -E -c main.c Invoked as /usr/bin/gcc Reference path: /usr/bin/.. arg[ 0] = rawgcc arg[ 1] = -nostdinc arg[ 2] = -isystem arg[ 3] = /usr/bin/../include arg[ 4] = -isystem arg[ 5] = /usr/bin/../gcc/include arg[ 6] = -U__nptl__ arg[ 7] = -I/lib/modules/kernel/2.6.27/build/include arg[ 8] = -Wall arg[ 9] = -DMODULE arg[10] = -D__KERNEL__ arg[11] = -D_LINUX arg[12] = -v arg[13] = -E arg[14] = -c arg[15] = main.c Using built-in specs. Target: armv5l-unknown-linux Configured with: /home/landley/firmware-0.9.6/build/temp-armv5l/gcc-core/configure --prefix=/home/landley/firmware-0.9.6/build/mini-native-armv5l/usr --disable-multilib --build=x86_64-walrus-linux --host=armv5l-unknown-linux --target=armv5l-unknown-linux --enable-long-long --enable-c99 --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-nls --enable-languages=c,c++ --disable-libstdcxx-pch --enable-sjlj-exceptions --program-prefix= Thread model: posix gcc version 4.1.2 /usr/bin/../libexec/gcc/armv5l-unknown-linux/4.1.2/cc1 -E -quiet -nostdinc -v -I/lib/modules/kernel/2.6.27/build/include -iprefix /usr/bin/../lib/gcc/armv5l-unknown-linux/4.1.2/ -U__nptl__ -DMODULE -D__KERNEL__ -D_LINUX -isystem /usr/bin/../include -isystem /usr/bin/../gcc/include main.c -Wall ignoring nonexistent directory "/lib/modules/kernel/2.6.27/build/include" #include "..." search starts here: #include <...> search starts here: /usr/bin/../include /usr/bin/../gcc/include End of search list. # 1 "main.c" # 1 "<built-in>" # 1 "<command line>" # 1 "main.c" main.c:1:24: error: linux/init.h: No such file or directory main.c:2:26: error: linux/module.h: No such file or directory # 1 "/usr/bin/../include/linux/kernel.h" 1 3 4 # 10 "/usr/bin/../include/linux/kernel.h" 3 4 struct sysinfo { long uptime; unsigned long loads[3]; unsigned long totalram; unsigned long freeram; unsigned long sharedram; unsigned long bufferram; unsigned long totalswap; unsigned long freeswap; unsigned short procs; unsigned short pad; unsigned long totalhigh; unsigned long freehigh; unsigned int mem_unit; char _f[20-2*sizeof(long)-sizeof(int)]; }; # 4 "main.c" 2 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert W. Oliver II"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); static int __init lkm_example_init(void) { printk(KERN_INFO "Hello, World!\n"); return 0; } static void __exit lkm_example_exit(void) { printk(KERN_INFO "Goodbye, World!\n"); } module_init(lkm_example_init); module_exit(lkm_example_exit); bash-3.2#
Ну и вот: Код (Text): igor@debian1:~/coding/GCC/testmod$ make make ARCH=arm CROSS_COMPILE=arm-none-eabi- -C /home/igor/coding/GCC/linux-at91-wilc_15_4_1 M=/home/igor/coding/GCC/testmod modules make[1]: вход в каталог «/home/igor/coding/GCC/linux-at91-wilc_15_4_1» CC [M] /home/igor/coding/GCC/testmod/lkm_example.o Building modules, stage 2. MODPOST 1 modules CC [M] /home/igor/coding/GCC/testmod/lkm_example.mod.o LD [M] /home/igor/coding/GCC/testmod/lkm_example.ko make[1]: выход из каталога «/home/igor/coding/GCC/linux-at91-wilc_15_4_1» при Mfrtfile... (кстати многие о такой его форме говорили - СПАСИБО!!): Код (Text): CrC=arm-none-eabi- obj-m := lkm_example.o KERNELDIR ?= /home/igor/coding/GCC/linux-at91-wilc_15_4_1 PWD := $(shell pwd) default: $(MAKE) ARCH=arm CROSS_COMPILE=$(CrC) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) ARCH=arm CROSS_COMPILE=$CrC -C $(KERNELDIR) M=$(PWD) clean Но к сожалению никто не сказал, что кроме конфигурации надо произвести так сказать сборку исходников: Код (C++): make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- А вот конфигурацию предварительно я делал: Код (Text): make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- at91_dt_defconfig и потом это (там надо ответить на толпу вопросов): Код (Text): make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- config Ну и испытания на плате: Код (Text): bash-3.2# insmod lkm_example.ko insmod: can't insert 'lkm_example.ko': invalid module format Смотрим в чем недовольство по dmesg: Код (Text): lkm_example: version magic '5.4.81-linux4sam-2020.102.6.27 mod_unload ARMv7 p2v8 ' should be '2.6.27 mod_unload ARMv5 ' Для уточнения: Код (Text): bash-3.2# uname -a Linux My_AT91SAM9263_board 2.6.27 #2 Sun Feb 8 16:11:45 PST 2015 armv5tejl GNU/Linux Ни процкссор ARMv5, ни версия 2.6.27 не совпадают. У меня только linux-at91-wilc_15_4_1 в корой работает этот Makeile Но важно то, что методика сборки стала понятна. Жаль, что никто не сказал что надо сделать и в какой последовательности. А может кто и гворил, но честное слово не припомню.
Linux, gcc, make и т.д. это всё открытое ПО, на него должна быть куча книг и инструкций как с этим работать. Тем более Линукс энтузиасты поддерживают в ряде случаев.
Я понимаю, что открытое ПО и прочее. Но вот я (может и тупой) не могу всё знать. Мне бы хотя бы направление куда копать. И всё же на плате: Код (Text): bash-3.2# insmod lkm_example.ko bash-3.2# и странный формат вывода: Код (Text): bash-3.2# lsmod lkm_example 1248 0 - Live 0xbf000000 и совсем не красиво: Код (Text): lbash-3.2# rmmod lkm_example rmmod: module 'lkm_example' not found bash-3.2# lsmod bash-3.2# Но тем не менее последние две строки вывода dmesg: Код (Text): Hello, World! Goodbye, World! Ну это и понятно по коду Си: Код (C++): #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert W. Oliver II"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); static int __init lkm_example_init(void) { printk(KERN_INFO "Hello, World!\n"); return 0; } static void __exit lkm_example_exit(void) { printk(KERN_INFO "Goodbye, World!\n"); } module_init(lkm_example_init); module_exit(lkm_example_exit); А Marefile вот: Код (Text): CrC=arm-none-eabi- obj-m := lkm_example.o KERNELDIR ?= /home/igor/coding/GCC/linux-2.6.27 PWD := $(shell pwd) default: $(MAKE) ARCH=arm CROSS_COMPILE=$(CrC) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) ARCH=arm CROSS_COMPILE=$CrC -C $(KERNELDIR) M=$(PWD) clean Собиралось на ПК с Debian. Вроде как работает. На electronix.ru предагают сменить ядро... наверное надо(да и сам хочу), но хотелось чуть-чуть привыкнуть и узнать хоть какие-нибудь тонкости перед этим.
Последние опыты на сегодня - загрузка нескольких модулей (трёх - один самодельный тестовый, два других при сборки из исходников): Код (Text): bash-3.2# lsmod bonding 82480 1 - Loading 0xbf005000 bcm203x 4224 0 - Live 0xbf002000 lkm_example 1248 0 - Live 0xbf000000 bash-3.2# совсем не привычно. Выхлоп dmesg отрывк: Код (Text): Goodbye, World! Hello, World! bfusb: Unknown symbol hci_free_dev bfusb: Unknown symbol hci_alloc_dev bfusb: Unknown symbol hci_unregister_dev bfusb: Unknown symbol hci_register_dev Bluetooth: Broadcom Blutonium firmware driver ver 1.2 usbcore: registered new interface driver bcm203x usb 1-1: new full speed USB device using at91_ohci and address 2 usb 1-1: configuration #1 chosen from 1 choice usbcore: deregistering interface driver bcm203x Bluetooth: Broadcom Blutonium firmware driver ver 1.2 usbcore: registered new interface driver bcm203x asix: Unknown symbol usbnet_set_msglevel asix: Unknown symbol usbnet_unlink_rx_urbs asix: Unknown symbol usbnet_get_msglevel asix: Unknown symbol usbnet_skb_return asix: Unknown symbol usbnet_get_settings asix: Unknown symbol usbnet_suspend asix: Unknown symbol usbnet_get_drvinfo asix: Unknown symbol usbnet_get_endpoints asix: Unknown symbol usbnet_nway_reset asix: Unknown symbol usbnet_defer_kevent asix: Unknown symbol usbnet_disconnect asix: Unknown symbol usbnet_set_settings asix: Unknown symbol usbnet_probe asix: Unknown symbol usbnet_resume zaurus: Unknown symbol usbnet_suspend zaurus: Unknown symbol usbnet_get_endpoints zaurus: Unknown symbol usbnet_generic_cdc_bind zaurus: Unknown symbol usbnet_disconnect zaurus: Unknown symbol usbnet_cdc_unbind zaurus: Unknown symbol usbnet_probe zaurus: Unknown symbol usbnet_resume usbnet: Unknown symbol netpoll_trap Error: Driver 'atmel_spi' is already registered, aborting... --- тут последняя ошибка - этот модуль встроен в ядро .... .... .... Попыток было много с загрузкой разных модулей - чисто для проверки их загрузки. Кто-то из них хотел каких-то ранее загруженных, а кто-требовал firmware. На сегодня хватит!
Вот это: Код (Text): bash-3.2# insmod lkm_example.ko Обычная загрузка модуля, но: Код (Text): bash-3.2# ls /dev audio mtd2 ram10 tty15 tty41 ttyS1 console mtd2ro ram11 tty16 tty42 ttyS2 controlC0 mtdblock0 ram12 tty17 tty43 ttyS3 cpu_dma_latency mtdblock1 ram13 tty18 tty44 ttyS4 dsp mtdblock2 ram14 tty19 tty45 ttyS5 full network_latency ram15 tty2 tty46 ttyS6 kmem network_throughput ram2 tty20 tty47 ttyp0 kmsg null ram3 tty21 tty48 ttyp1 lkm_example pcmC0D0p ram4 tty22 tty49 ttyp2 loop0 ptmx ram5 tty23 tty5 ttyp3 loop1 pts ram6 tty24 tty50 ttyp4 loop2 ptyp0 ram7 tty25 tty51 ttyp5 loop3 ptyp1 ram8 tty26 tty52 ttyp6 loop4 ptyp2 ram9 tty27 tty53 ttyp7 loop5 ptyp3 random tty28 tty54 ttyp8 loop6 ptyp4 root tty29 tty55 ttyp9 loop7 ptyp5 rtc0 tty3 tty56 ttypa mem ptyp6 seq tty30 tty57 ttypb mice ptyp7 sequencer tty31 tty58 ttypc mixer ptyp8 sequencer2 tty32 tty59 ttypd mmcblk0 ptyp9 timer tty33 tty6 ttype mmcblk0p1 ptypa tty tty34 tty60 ttypf mmcblk0p2 ptypb tty0 tty35 tty61 urandom mmcblk0p3 ptypc tty1 tty36 tty62 usbdev1.1_ep00 mmcblk0p4 ptypd tty10 tty37 tty63 usbdev1.1_ep81 mtd0 ptype tty11 tty38 tty7 vcs mtd0ro ptypf tty12 tty39 tty8 vcsa mtd1 ram0 tty13 tty4 tty9 zero mtd1ro ram1 tty14 tty40 ttyS0 bash-3.2# обратите внимание на /dev/lkm_example - появилось устройство... появилось при загрузке модуля. При выгрузке модуля: Код (Text): bash-3.2# rmmod lkm_example Исчезает и это устройство. Долго искал как автоматом это сделать. И в /sys/class то же появилось: Код (Text): bash-3.2# bash-3.2# ls bdi leds misc net scsi_disk spi_master usb_endpoint vtconsole firmware lkm_example mmc_host rtc scsi_host spidev usb_host input mem mtd scsi_device sound tty vc bash-3.2# И глядя на источник(чужой) переделал свой тестовый код, что бы твкое было возможно: Код (C++): // #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/fs.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert W. Oliver II"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); static dev_t first; // Global variable for the first device number static struct cdev c_dev; // Global variable for the character device structure static struct class *cl; // Global variable for the device class static int my_open(struct inode *i, struct file *f) { printk(KERN_INFO "Driver: open()\n"); return 0; } static int my_close(struct inode *i, struct file *f) { printk(KERN_INFO "Driver: close()\n"); return 0; } static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: read()\n"); return 0; } static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: write()\n"); return len; } static struct file_operations pugs_fops = { .owner = THIS_MODULE, .open = my_open, .release = my_close, .read = my_read, .write = my_write }; static int __init lkm_example_init(void) { printk(KERN_INFO "Namaskar: ofcd registered\n"); if (alloc_chrdev_region(&first, 0, 1, "lkm_example") < 0) { return -1; } if ((cl = class_create(THIS_MODULE, "lkm_example")) == NULL) { unregister_chrdev_region(first, 1); return -1; } if (device_create(cl, NULL, first, NULL, "lkm_example") == NULL) { class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } cdev_init(&c_dev, &pugs_fops); if (cdev_add(&c_dev, first, 1) == -1) { device_destroy(cl, first); class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } printk(KERN_INFO "Hello, World!\n"); return 0; } static void __exit lkm_example_exit(void) { cdev_del(&c_dev); device_destroy(cl, first); class_destroy(cl); printk(KERN_INFO "Goodbye, World!\n"); } module_init(lkm_example_init); module_exit(lkm_example_exit); Ну что же, наверное пора что-то рабочее делать.
Доброго времени суток! Вот собрал кучу чужих модулей bluetooth, загрузил их по insmod на плате. По lsmod посмотрел: Код (Text): ash-3.2# lsmod hci_uart 18852 0 - Live 0xbf022000 hci_vhci 5344 0 - Live 0xbf01f000 bfusb 8736 1 - Loading 0xbf019000 hci_usb 10744 1 - Loading 0xbf013000 bluetooth 51200 4 hci_uart,hci_vhci,bfusb,hci_usb, Live 0xbf005000 bcm203x 4224 0 - Live 0xbf002000 lkm_example 2340 0 - Live 0xbf000000 bash-3.2# Вот фрагмент dmesg: Код (Text): Modules linked in: hci_usb(+) bluetooth bcm203x lkm_example CPU: 0 Tainted: P (2.6.27 #2) PC is at internal_create_group+0x5c/0x1e8 LR is at sysfs_create_group+0x18/0x1c pc : [<c00c0768>] lr : [<c00c0928>] psr: 60000013 sp : c3af3cb8 ip : c3af3cec fp : c3af3ce8 r10: 00000001 r9 : 00000000 r8 : c39f4ef8 r7 : c39f4ef8 r6 : 00000000 r5 : 00000000 r4 : bf015840 r3 : 00000000 r2 : 00000001 r1 : 00000000 r0 : c39f4ef8 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 0005317f Table: 23ac8000 DAC: 00000015 Process insmod (pid: 497, stack limit = 0xc3af2260) Stack: (0xc3af3cb8 to 0xc3af4000) 3ca0: 00000000 c39fa508 3cc0: bf015840 00000000 00000000 c39f4ef8 c39f4e90 00000000 c395a288 c3af3cf8 3ce0: c3af3cec c00c0928 c00c071c c3af3d1c c3af3cfc c014fa4c c00c0920 c39f4e90 3d00: c39f4e90 00000000 c39f4f1c bf0114a0 c3af3d60 c3af3d20 c0150ab4 c014fa38 3d20: c39f4ef8 c3a6b01c c3af3d60 c3af3d38 c0150344 c02484fc c39f4e90 c39f4e90 3d40: 00000000 00000001 c3a7785c c39f4c00 c395a288 c3af3d74 c3af3d64 c0150cc8 3d60: c0150770 c39f4c00 c3af3d8c c3af3d78 bf00cb40 c0150cbc c39f4c00 00000000 3d80: c3af3dac c3af3d90 bf0067a4 bf00cb04 c3a803c0 bf015980 bf015538 c3a6b000 3da0: c3af3de0 c3af3db0 bf013900 bf006638 c395a2b0 c3a77800 c3a6b01c c3a6b000 3dc0: bf015500 bf015790 bf0154d0 c3af2000 c3a77800 c3af3e08 c3af3de4 c0181b90 3de0: bf013594 c3a6b01c bf015500 bf015500 bf015500 bf015500 c02f4b18 c3af3e28 3e00: c3af3e0c c0152a74 c0181aac c3a6b01c bf015500 c3a6b0c8 bf015500 c3af3e44 3e20: c3af3e2c c0152b74 c01529ac 00000000 c3af3e48 c0152b28 c3af3e70 c3af3e48 3e40: c015195c c0152b38 c3834698 c3834698 c3a6b064 00000000 bf015500 c3985260 3e60: bf0143bf c3af3e80 c3af3e74 c0152758 c0151920 c3af3eac c3af3e84 c015256c 3e80: c0152748 bf0143bf bf0154d0 bf015500 bf015840 bf0143bf bf015500 00000000 3ea0: c3af3ecc c3af3eb0 c0152f84 c01524d4 bf0154d0 ffffffed bf015840 bf0143bf 3ec0: c3af3ef0 c3af3ed0 c0180fb8 c0152efc 00003750 bf015840 000e5080 bf017000 3ee0: c02fdb30 c3af3f04 c3af3ef4 bf017028 c0180f5c 00003750 c3af3f80 c3af3f08 3f00: c00272b4 bf017010 00000000 00000000 00000000 0000009a 0000009a 00000000 3f20: c01de290 c3af2000 00000017 bf014dfc c48b83e0 00000017 00000000 00000000 3f40: 00000000 00000000 00000000 00003750 bf015840 000e5080 00000000 00003750 3f60: bf015840 000e5080 00000000 c0027d24 beb38e2c c3af3fa4 c3af3f84 c005c4f0 3f80: c0027274 c002ce78 756e694c beb38e28 00000069 00000080 00000000 c3af3fa8 3fa0: c0027b80 c005c468 756e694c beb38e28 000e5080 00003750 000bdd14 00000000 3fc0: 756e694c beb38e28 00000069 beb38e28 00000000 beb38e24 beb38e2c 00000002 3fe0: 40186310 beb38a84 000201fc 4018631c 60000010 000e5080 2f000000 00737973 Backtrace: [<c00c070c>] (internal_create_group+0x0/0x1e8) from [<c00c0928>] (sysfs_create_group+0x18/0x1c) [<c00c0910>] (sysfs_create_group+0x0/0x1c) from [<c014fa4c>] (device_add_groups+0x24/0x78) [<c014fa28>] (device_add_groups+0x0/0x78) from [<c0150ab4>] (device_add+0x354/0x54c) r8:bf0114a0 r7:c39f4f1c r6:00000000 r5:c39f4e90 r4:c39f4e90 [<c0150760>] (device_add+0x0/0x54c) from [<c0150cc8>] (device_register+0x1c/0x20) [<c0150cac>] (device_register+0x0/0x20) from [<bf00cb40>] (hci_register_sysfs+0x4c/0x5c [bluetooth]) r4:c39f4c00 [<bf00caf4>] (hci_register_sysfs+0x0/0x5c [bluetooth]) from [<bf0067a4>] (hci_register_dev+0x17c/0x1c8 [bluetooth]) r5:00000000 r4:c39f4c00 [<bf006628>] (hci_register_dev+0x0/0x1c8 [bluetooth]) from [<bf013900>] (hci_usb_probe+0x37c/0x3f4 [hci_usb]) r7:c3a6b000 r6:bf015538 r5:bf015980 r4:c3a803c0 [<bf013584>] (hci_usb_probe+0x0/0x3f4 [hci_usb]) from [<c0181b90>] (usb_probe_interface+0xf4/0x134) [<c0181a9c>] (usb_probe_interface+0x0/0x134) from [<c0152a74>] (driver_probe_device+0xd8/0x18c) [<c015299c>] (driver_probe_device+0x0/0x18c) from [<c0152b74>] (__driver_attach+0x4c/0x70) r7:bf015500 r6:c3a6b0c8 r5:bf015500 r4:c3a6b01c [<c0152b28>] (__driver_attach+0x0/0x70) from [<c015195c>] (bus_for_each_dev+0x4c/0x84) r6:c0152b28 r5:c3af3e48 r4:00000000 [<c0151910>] (bus_for_each_dev+0x0/0x84) from [<c0152758>] (driver_attach+0x20/0x28) r7:bf0143bf r6:c3985260 r5:bf015500 r4:00000000 [<c0152738>] (driver_attach+0x0/0x28) from [<c015256c>] (bus_add_driver+0xa8/0x214) [<c01524c4>] (bus_add_driver+0x0/0x214) from [<c0152f84>] (driver_register+0x98/0x118) [<c0152eec>] (driver_register+0x0/0x118) from [<c0180fb8>] (usb_register_driver+0x6c/0xf4) r7:bf0143bf r6:bf015840 r5:ffffffed r4:bf0154d0 [<c0180f4c>] (usb_register_driver+0x0/0xf4) from [<bf017028>] (hci_usb_init+0x28/0x60 [hci_usb]) r8:c02fdb30 r7:bf017000 r6:000e5080 r5:bf015840 r4:00003750 [<bf017000>] (hci_usb_init+0x0/0x60 [hci_usb]) from [<c00272b4>] (do_one_initcall+0x50/0x174) r4:00003750 [<c0027264>] (do_one_initcall+0x0/0x174) from [<c005c4f0>] (sys_init_module+0x98/0x184) [<c005c458>] (sys_init_module+0x0/0x184) from [<c0027b80>] (ret_fast_syscall+0x0/0x2c) r7:00000080 r6:00000069 r5:beb38e28 r4:756e694c Code: e5983018 e3530000 03e05015 0a00005d (e59a1000) ---[ end trace 685b9b2ebeaca745 ]--- usb 1-1: USB disconnect, address 2 Bluetooth: BlueFRITZ! USB driver ver 1.2 Bluetooth: Virtual HCI driver ver 1.2 Bluetooth: HCI UART driver ver 2.2 Bluetooth: HCI H4 protocol initialized Bluetooth: HCI BCSP protocol initialized Bluetooth: HCILL protocol initialized bash-3.2# Вопрос: если все загрузились, может и правильно, какие устройства надо сгенерировать в /dev? И как работать вообще с модулями в смысле написания своего кода для взаимодесйтвия с ними? Спасибо!
Обучение(самообучение) продолжается. Взят пример: https://habr.com/ru/post/343828/ скрестил его с вышеупомянутым, где автоматом создается устройство и вышло это: Код (C++): //#include <linux/init.h> //#include <linux/module.h> //#include <linux/kernel.h> #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/cdev.h> //#include <linux/fs.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/uaccess.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert W. Oliver II"); MODULE_DESCRIPTION("A simple example Linux module."); MODULE_VERSION("0.01"); #define DEVICE_NAME "lkm_example" #define EXAMPLE_MSG "Hello, World!\n" #define MSG_BUFFER_LEN 15 static dev_t first; // Global variable for the first device number static struct cdev c_dev; // Global variable for the character device structure static struct class *cl; // Global variable for the device class /* Prototypes for device functions */ static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); static int major_num; static int device_open_count = 0; static char msg_buffer[MSG_BUFFER_LEN]; static char *msg_ptr; /* This structure points to all of the device functions */ static struct file_operations file_ops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; /* When a process reads from our device, this gets called. */ static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset) { int bytes_read = 0; /* If we’re at the end, loop back to the beginning */ if (*msg_ptr == 0) { msg_ptr = msg_buffer; } /* Put data in the buffer */ while (len && *msg_ptr) { /* Buffer is in user data, not kernel, so you can’t just reference * with a pointer. The function put_user handles this for us */ put_user(*(msg_ptr++), buffer++); len--; bytes_read++; } return bytes_read; } /* Called when a process tries to write to our device */ static ssize_t device_write(struct file *flip, const char *buffer, size_t len, loff_t *offset) { /* This is a read-only device */ printk(KERN_ALERT "This operation is not supported.\n"); return -EINVAL; } /* Called when a process opens our device */ static int device_open(struct inode *inode, struct file *file) { /* If device is open, return busy */ if (device_open_count) { return -EBUSY; } device_open_count++; try_module_get(THIS_MODULE); return 0; } /* Called when a process closes our device */ static int device_release(struct inode *inode, struct file *file) { /* Decrement the open counter and usage count. Without this, the module would not unload. */ device_open_count--; module_put(THIS_MODULE); return 0; } static int __init lkm_example_init(void) { printk(KERN_INFO "Namaskar: ofcd registered\n"); if (alloc_chrdev_region(&first, 0, 1, "lkm_example") < 0) { return -1; } if ((cl = class_create(THIS_MODULE, "lkm_example")) == NULL) { unregister_chrdev_region(first, 1); return -1; } if (device_create(cl, NULL, first, NULL, "lkm_example") == NULL) { class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } //cdev_init(&c_dev, &pugs_fops); cdev_init(&c_dev, &file_ops); if (cdev_add(&c_dev, first, 1) == -1) { device_destroy(cl, first); class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } //printk(KERN_INFO "Hello, World!\n"); //return 0; /* Fill buffer with our message */ strncpy(msg_buffer, EXAMPLE_MSG, MSG_BUFFER_LEN); /* Set the msg_ptr to the buffer */ msg_ptr = msg_buffer; /* Try to register character device */ major_num = register_chrdev(0, "lkm_example", &file_ops); if (major_num < 0) { printk(KERN_ALERT "Could not register device: %d\n", major_num); return major_num; } else { printk(KERN_INFO "lkm_example module loaded with device major number %d\n", major_num); printk(KERN_INFO "Hello, World!\n"); return 0; } } static void __exit lkm_example_exit(void) { cdev_del(&c_dev); device_destroy(cl, first); class_destroy(cl); /* Remember — we have to clean up after ourselves. Unregister the character device. */ unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "Goodbye, World!\n"); } /* Register module functions */ module_init(lkm_example_init); module_exit(lkm_example_exit); Makefile взял там же: Код (Text): obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean test: # We put a — in front of the rmmod command to tell make to ignore # an error in case the module isn’t loaded. -sudo rmmod lkm_example # Clear the kernel log without echo sudo dmesg -C # Insert the module sudo insmod lkm_example.ko # Display the kernel log dmesg и вышло это...... ....загрузка модуля через тест Makefile: Код (Text): root@debian:/home/kto/coding/AT91SAM9260_board/testmod2# make test # We put a — in front of the rmmod command to tell make to ignore # an error in case the module isn’t loaded. #sudo rmmod lkm_example rmmod lkm_example # Clear the kernel log without echo dmesg -C #sudo dmesg -C # Insert the module #sudo insmod lkm_example.ko insmod lkm_example.ko # Display the kernel log dmesg [19066.712295] Namaskar: ofcd registered [19066.712352] lkm_example module loaded with device major number 245 [19066.712354] Hello, World! .... наблюдаем новое устройство в /dev: Код (Text): root@debian:/home/kto/coding/AT91SAM9260_board/testmod2# ls /dev | grep lk lkm_example root@debian:/home/kto/coding/AT91SAM9260_board/testmod2# .... читаем из устройства по cat /dev/lkm_example: Код (Text): ..... Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! ..... Только переварю немного функции, но уж дома. Курить думаю надо всего... О-ГОГОГО....
Нормальная обложка. Я обычно начинаю читать с оглавления... Испытал этот код на плате - результат аналогичен... но это нормально. А ссылка на книгу - похоже битая. Похоже основные минимальные понятия мне понятны... курю, набираю (пока довольно скудный) опыт
Вот курю: Код (Text): root@debianNUC7PJYH:/home/igor/coding/GCC/modules-2.6.27/mluetooth_2# modinfo bluetooth.ko filename: /home/igor/coding/GCC/modules-2.6.27/mluetooth_2/bluetooth.ko alias: net-pf-31 license: GPL version: 2.13 description: Bluetooth Core ver 2.13 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 9A3BC0C30A3C7408F41F1D2 depends: vermagic: 2.6.27 mod_unload ARMv5 root@debianNUC7PJYH:/home/igor/coding/GCC/modules-2.6.27/mluetooth_2# modinfo l2cap.ko filename: /home/igor/coding/GCC/modules-2.6.27/mluetooth_2/l2cap.ko alias: bt-proto-0 license: GPL version: 2.11 description: Bluetooth L2CAP ver 2.11 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 5A03D5492C5FF01EF0DF37B depends: bluetooth vermagic: 2.6.27 mod_unload ARMv5 root@debianNUC7PJYH:/home/igor/coding/GCC/modules-2.6.27/mluetooth_2# modinfo sco.ko filename: /home/igor/coding/GCC/modules-2.6.27/mluetooth_2/sco.ko alias: bt-proto-2 license: GPL version: 0.6 description: Bluetooth SCO ver 0.6 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 834CD58B49482BEEA1EE739 depends: bluetooth vermagic: 2.6.27 mod_unload ARMv5 parm: disable_esco:Disable eSCO connection creation (bool) root@debianNUC7PJYH:/home/igor/coding/GCC/modules-2.6.27/mluetooth_2/rfcomm# modinfo rfcomm.ko filename: /home/igor/coding/GCC/modules-2.6.27/mluetooth_2/rfcomm/rfcomm.ko alias: bt-proto-3 license: GPL version: 1.10 description: Bluetooth RFCOMM ver 1.10 author: Marcel Holtmann <marcel@holtmann.org> srcversion: 9C07D526677C92D2DAB5617 depends: bluetooth,l2cap vermagic: 2.6.27 mod_unload ARMv5 parm: disable_cfc:Disable credit based flow control (bool) parm: channel_mtu:Default MTU for the RFCOMM channel (int) parm: l2cap_mtu:Default MTU for the L2CAP connection (uint) root@debianNUC7PJYH:/home/igor/coding/GCC/modules-2.6.27/mluetooth_2/bnep# modinfo bnep.ko filename: /home/igor/coding/GCC/modules-2.6.27/mluetooth_2/bnep/bnep.ko alias: bt-proto-4 license: GPL version: 1.3 description: Bluetooth BNEP ver 1.3 author: Marcel Holtmann <marcel@holtmann.org> srcversion: D0CC658735BC3F994FE247F depends: bluetooth,l2cap vermagic: 2.6.27 mod_unload ARMv5 parm: compress_src:Compress sources headers (bool) parm: compress_dst:Compress destination headers (bool) Вот к примеру: Код (Text): depends: bluetooth Обратил внимание, что модуль bluetooth(bluetooth.ko) должен быть уже загружен, перед тем как загрузить этот (содержащий такую строку) модуль. Выясняется последовательность загрузки модулей. А вот это: Код (Text): parm: disable_cfc:Disable credit based flow control (bool) parm: channel_mtu:Default MTU for the RFCOMM channel (int) parm: l2cap_mtu:Default MTU for the L2CAP connection (uint) не понятно. Это параметры при загрузке модуля? Тут я так понимаю указано имя параметра и его тип? Пока не могу отыскать формат указания параметра. Что-то не смог пока найти метода доступа к функциям модуля из кода... ну допустим код запущенный от ROOT может получить доступ к ним? И если да то как? Метод доступа к устройству через /dev/<устройство> связанное с модулем это ясно... а напрямую никак?
??? https://www.opennet.ru/base/dev/kernel_module_guide.txt.html http://citforum.ru/operating_systems/linux/lkmpg/#FUNCTIONSAVAILABLETOMODULES
конечно информации много(сил больше нет), но может пример простой кто предоставил бы? А именно обмен данными между модулями. Сначала загружается один модуль, потом другой который создаем устройтство в /dev. Далее Код (Text): echo "123" > /dev/test_mod1 что-то пишем, а модуль mod0 должен "перевернуть" строку и вернуть в модуль mod1, который при загрузке формирует dev/test_mod1 (с ним и идет работа) - выхлоп в dmesg: Код (Text): [ 4074.639417] mod0 module loaded [ 4078.455765] Namaskar: ofcd registered [ 4078.456954] mod1 module loaded with device major number 239 [ 4093.180563] MOD1 1: from /dev/test_mod1(buffer):123 e/igor/coding/My_AT91SAM9260_board/testmod3 \xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf ............ \xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf\xffffffdf [ 4093.180570] MOD0 SI: [ 4093.180572] MOD0 SI: [ 4093.180575] MOD0 SI: [ 4093.180577] MOD0 SI: [ 4093.180579] MOD0 SI: [ 4093.180581] MOD0 SI: [ 4093.180583] MOD0 SI: [ 4093.180586] MOD0 SI: [ 4093.180588] MOD0 SI: [ 4093.180590] MOD0 SI: [ 4093.180592] MOD0 SI: [ 4093.180594] MOD0 SI: [ 4093.180597] MOD0 SI: [ 4093.180599] MOD0 SI: [ 4093.180601] MOD0 SI: [ 4093.180603] MOD0 SI: [ 4093.180605] MOD0 SI: [ 4093.180608] MOD0 SI: [ 4093.180610] MOD0 SI: [ 4093.180612] MOD0 SI: [ 4093.180614] MOD0 SI: [ 4093.180616] MOD0 SI: [ 4093.180618] MOD0 SI: [ 4093.180621] MOD0 SI: [ 4093.180623] MOD0 SI: [ 4093.180625] MOD0 SI: [ 4093.180627] MOD0 SI: [ 4093.180629] MOD0 SI: [ 4093.180632] MOD0 SI: [ 4093.180634] MOD0 SI: [ 4093.180636] MOD0 SI: [ 4093.180638] MOD0 SI: [ 4093.180641] MOD1 from mod0: len=4 root@DebTool:/home/igor# Вот модуль mod0, который крутит строку: Код (C++): // #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/uaccess.h> //#include <linux/kallsyms.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Igor D: 19.08.2021"); MODULE_DESCRIPTION("mod0 testing."); MODULE_VERSION("1.01"); #define MSG_BUFFER_LEN 32 static char instr[MSG_BUFFER_LEN]; EXPORT_SYMBOL(instr); static char outstr[MSG_BUFFER_LEN]; EXPORT_SYMBOL(outstr); static void mod0_strreverse(void) { int cnt1 = 0; int cnt2 = MSG_BUFFER_LEN; // while(cnt1 < MSG_BUFFER_LEN) { outstr[cnt1] = instr[cnt2]; printk(KERN_INFO "MOD0 SI:%c SO:%c\n", (*(char*)(instr + cnt1)), (*(char*)(outstr + cnt2))); cnt1++; cnt2--; } } EXPORT_SYMBOL(mod0_strreverse); static int __init mod0_init(void) { printk(KERN_INFO "mod0 module loaded\n"); return 0; } static void __exit mod0_exit(void) { printk(KERN_INFO "mod1 unloaded!\n"); } /* Register module functions */ module_init(mod0_init); module_exit(mod0_exit); А это модуль mod1, который принмает данные от echo "123" > /dev/test_mod1 и должен отдать cat /dev/test_mod1 Сам модуль: Код (C++): // #include <linux/device.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/uaccess.h> #include "mod0.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Igor D: 19.08.2021"); MODULE_DESCRIPTION("mod1 testing."); MODULE_VERSION("1.01"); MODULE_SOFTDEP("pre: mod0"); //MODULE_DEPENDS(mod0, 1); //EXPORT_NO_SYMBOLS; #define DEVICE_NAME "test_mod1" #define EXAMPLE_MSG "mod1 loaded!\n" #define MSG_BUFFER_LEN 32 //#define SZ_VAL 10 static dev_t first; // Global variable for the first device number static struct cdev c_dev; // Global variable for the character device structure static struct class *cl; // Global variable for the device class // //static int strreverse(char *instr, char *outstr, size_t len); // static int major_num; static int device_open_count = 0; static char msg_buffer[MSG_BUFFER_LEN]; static char *msg_ptr; static int cnt_rd = 0; /* Prototypes for device functions */ static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); /* This structure points to all of the device functions */ static struct file_operations file_ops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release // }; /* When a process reads from our device, this gets called. */ static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset) { int bytes_read = 0; /* If we’re at the end, loop back to the beginning */ if (*msg_ptr == 0) { if(cnt_rd > 0) { msg_ptr = msg_buffer; cnt_rd = 0; } else { return 0; } } /* Put data in the buffer */ while (len && *msg_ptr) { /* Buffer is in user data, not kernel, so you can’t just reference * with a pointer. The function put_user handles this for us */ put_user(*(msg_ptr++), buffer++); len--; bytes_read++; } return bytes_read; } /* Called when a process tries to write to our device */ static ssize_t device_write(struct file *flip, const char *buffer, size_t len, loff_t *offset) { printk(KERN_INFO "MOD1 1: from /dev/test_mod1(buffer):%s len=%i\n", buffer, (int)(len)); //offset = 0; if(len < MSG_BUFFER_LEN) { memset(instr, 0x20, MSG_BUFFER_LEN); //memcpy(msg_buffer, buffer, len); cnt_rd = len; memcpy(instr, buffer, (int)(len)); //cnt_rd = len; //printk(KERN_INFO "MOD1 2: from /dev/test_mod1:%s len=%i\n", instr, (int)(len)); // mod0_strreverse(); memcpy(msg_buffer, outstr, (int)(len)); printk(KERN_INFO "MOD1 from mod0:%s len=%i\n", outstr, (int)(len)); cnt_rd = len; // return len; } else return -EINVAL; } /* Called when a process opens our device */ static int device_open(struct inode *inode, struct file *file) { /* If device is open, return busy */ if (device_open_count) { return -EBUSY; } device_open_count++; try_module_get(THIS_MODULE); return 0; } /* Called when a process closes our device */ static int device_release(struct inode *inode, struct file *file) { /* Decrement the open counter and usage count. Without this, the module would not unload. */ device_open_count--; module_put(THIS_MODULE); return 0; } static int __init mod1_init(void) { printk(KERN_INFO "Namaskar: ofcd registered\n"); if (alloc_chrdev_region(&first, 0, 1, DEVICE_NAME) < 0) { return -1; } if ((cl = class_create(THIS_MODULE, DEVICE_NAME)) == NULL) { unregister_chrdev_region(first, 1); return -1; } if (device_create(cl, NULL, first, NULL, DEVICE_NAME) == NULL) { class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } //cdev_init(&c_dev, &pugs_fops); cdev_init(&c_dev, &file_ops); if (cdev_add(&c_dev, first, 1) == -1) { device_destroy(cl, first); class_destroy(cl); unregister_chrdev_region(first, 1); return -1; } /* Fill buffer with our message */ strncpy(msg_buffer, EXAMPLE_MSG, MSG_BUFFER_LEN); /* Set the msg_ptr to the buffer */ msg_ptr = msg_buffer; /* Try to register character device */ major_num = register_chrdev(0, DEVICE_NAME, &file_ops); if (major_num < 0) { printk(KERN_ALERT "Could not register device: %d\n", major_num); return major_num; } else { printk(KERN_INFO "mod1 module loaded with device major number %d\n", major_num); return 0; } } static void __exit mod1_exit(void) { cdev_del(&c_dev); device_destroy(cl, first); class_destroy(cl); /* Remember — we have to clean up after ourselves. Unregister the character device. */ unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO "mod1 unloaded!\n"); } /* Register module functions */ module_init(mod1_init); module_exit(mod1_exit); А это отчём о наличии модулей: Код (Text): root@DebTool:/home/igor/coding/My_AT91SAM9260_board/testmod3# lsmod | grep mod mod1 16384 0 mod0 16384 1 mod1 sd_mod 40960 3 sr_mod 24576 1 cdrom 49152 1 sr_mod scsi_mod 180224 4 sd_mod,libata,sr_mod,sg root@DebTool:/home/igor/coding/My_AT91SAM9260_board/testmod3# Вопрос в том, что числовые данные меду модулями без проблем, а вот строку(массив) ну совсем ни как. Что не так? PS: слова на Руссом языке можно трактовать по разному, а фрагмент на Си ясен. В коде много мусора - результат опыта проводимого(не окончено - всякое испытал и не чистил) Спасибо!
Доброго времени суток! Доступ к драйверу через устройство /dev/<dev> испытал. Но есть ли иной способ получить доступ к драйверу - подсмотрел драйвера (исходники) вот уже собранные: Код (Text): bcm203x.ko bluetooth.ko bpa10x.ko hci_ldisc.ko hci_usb.ko hidp.ko rfcomm.ko bfusb.ko bnep.ko btusb.ko hci_uart.ko hci_vhci.ko l2cap.ko sco.ko Но в них (исходниках) не заметил что-то похожее на Код (C++): /* This structure points to all of the device functions */ static struct file_operations file_ops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; которое для файла устройства, ну и функции типа: Код (C++): /* When a process reads from our device, this gets called. */ static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset) { int bytes_read = 0; /* If we’re at the end, loop back to the beginning */ if (*msg_ptr == 0) { if(cnt_rd > 0) { msg_ptr = msg_buffer; cnt_rd = 0; } else { return 0; } } /* Put data in the buffer */ while (len && *msg_ptr) { /* Buffer is in user data, not kernel, so you can’t just reference * with a pointer. The function put_user handles this for us */ put_user(*(msg_ptr++), buffer++); len--; bytes_read++; } return bytes_read; } /* Called when a process tries to write to our device */ static ssize_t device_write(struct file *flip, const char *buffer, size_t len, loff_t *offset) { //char outstr[MSG_BUFFER_LEN] = {0}; if(len < MSG_BUFFER_LEN) { memset(instr, 0x20, MSG_BUFFER_LEN); //memcpy(msg_buffer, buffer, len); cnt_rd = len; memcpy(instr, buffer, (int)(len)); //cnt_rd = len; //printk(KERN_INFO "from /dev/test_mod1:%s len=%i\n", outstr, (int)(len)); // mod0_strreverse(); memcpy(msg_buffer, outstr, (int)(len)); printk(KERN_INFO "from mod0:%s len=%i\n", outstr, (int)(len)); cnt_rd = len; // return len; } else return -EINVAL; } /* Called when a process opens our device */ static int device_open(struct inode *inode, struct file *file) { /* If device is open, return busy */ if (device_open_count) { return -EBUSY; } device_open_count++; try_module_get(THIS_MODULE); return 0; } /* Called when a process closes our device */ static int device_release(struct inode *inode, struct file *file) { /* Decrement the open counter and usage count. Without this, the module would not unload. */ device_open_count--; module_put(THIS_MODULE); return 0; } Которые для драйвера (модуля) операции ввода-вывода со стороны самого драйвера. Для приложений надо только обращаться к /dev/<dev>. А тут в исходниках что-то не заметил.
Доброго времени суток! Вот опять ковыряние с загружаемыми модулями: testmod3.zip На сей раз удачно: Код (Text): root@debian:/dev# echo "123456789abcdef" > /dev/test_mod1 root@debian:/dev# cat /dev/test_mod1 fedcba987654321 root@debian:/dev# и выхлоп системы (dmesg): Код (Text): [25774.873029] from /dev/test_mod1: len=16 [25774.873033] From mod1: SI:1 (HEX=31) [25774.873034] From mod1: SI:2 (HEX=32) [25774.873035] From mod1: SI:3 (HEX=33) [25774.873036] From mod1: SI:4 (HEX=34) [25774.873037] From mod1: SI:5 (HEX=35) [25774.873038] From mod1: SI:6 (HEX=36) [25774.873039] From mod1: SI:7 (HEX=37) [25774.873040] From mod1: SI:8 (HEX=38) [25774.873041] From mod1: SI:9 (HEX=39) [25774.873042] From mod1: SI:a (HEX=61) [25774.873043] From mod1: SI:b (HEX=62) [25774.873043] From mod1: SI:c (HEX=63) [25774.873044] From mod1: SI:d (HEX=64) [25774.873045] From mod1: SI:e (HEX=65) [25774.873046] From mod1: SI:f (HEX=66) [25774.873047] From mod1: SI: (HEX=0A) [25774.873049] mod0: outstr sim(num=0):f [25774.873050] mod0: outstr sim(num=1):e [25774.873051] mod0: outstr sim(num=2):d [25774.873051] mod0: outstr sim(num=3):c [25774.873052] mod0: outstr sim(num=4):b [25774.873053] mod0: outstr sim(num=5):a [25774.873054] mod0: outstr sim(num=6):9 [25774.873055] mod0: outstr sim(num=7):8 [25774.873056] mod0: outstr sim(num=8):7 [25774.873057] mod0: outstr sim(num=9):6 [25774.873058] mod0: outstr sim(num=10):5 [25774.873058] mod0: outstr sim(num=11):4 [25774.873059] mod0: outstr sim(num=12):3 [25774.873060] mod0: outstr sim(num=13):2 [25774.873061] mod0: outstr sim(num=14):1 [25774.873062] from mod0:fedcba987654321 len=16 root@debian:/usr/src# Что происходит? загружаются два модуля mod0.ko и mod1.ko. Модуль mod1 при загрузке, создаёт устройство /dev/ test_mod1, через которое можно обращаться к нему. Это устройство символьное. Мы записываем в это устройство некую строку "123456789abcdef". Он модуль mod1 забирает её и отдаёт модулю mod0, который переворачивает эту строку задом наперёд. Потом (тут же) модуль mod1 забирает строку у модуля mod0. При чтении из устройства мы получаем эту нашу строку зодом на перед. Задача бестолковая конечно, но цель попробовать механизм обмена между загружаемыми модулями ядра системы Linux. В коде много мусора и неточностей... это тест. Можно таким образом получать доступ к железу устройства на Linux... ну там всякие SPI и прочее практически напрямую из своих программ. Надо разобраться как. Следует отметить, что загрузка и выгрузка модулей с правами ROOT. Да и разрешения на создаваемое устройство модулем в этом тесте игнорировал.