Arm с внешней шиной данных?

Тема в разделе "Флудилка", создана пользователем Igor68, 15 апр 2021.

  1. Igor68

    Igor68 Гуру

    В выхлопе ругается на
    Код (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#
    Вот даже тут что-то криво.
     
  2. Igor68

    Igor68 Гуру

    И ещё:
    Код (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#
    То же что-то не так.
     
  3. Igor68

    Igor68 Гуру

    Опять косяк. Вроде собрал, но компиляция не проходит. Вот этот делал на самой плате:
    Код (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#
     
  4. Igor68

    Igor68 Гуру

    Ну и вот:
    Код (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 Но важно то, что методика сборки стала понятна.
    Жаль, что никто не сказал что надо сделать и в какой последовательности.
    А может кто и гворил, но честное слово не припомню.
     
    Un_ka нравится это.
  5. Un_ka

    Un_ka Гуру

    Linux, gcc, make и т.д. это всё открытое ПО, на него должна быть куча книг и инструкций как с этим работать. Тем более Линукс энтузиасты поддерживают в ряде случаев.
     
  6. Igor68

    Igor68 Гуру

    Я понимаю, что открытое ПО и прочее. Но вот я (может и тупой) не могу всё знать. Мне бы хотя бы направление куда копать. И всё же на плате:
    Код (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 предагают сменить ядро... наверное надо(да и сам хочу), но хотелось чуть-чуть привыкнуть и узнать хоть какие-нибудь тонкости перед этим.
     
    Последнее редактирование: 12 авг 2021
  7. Igor68

    Igor68 Гуру

    Последние опыты на сегодня - загрузка нескольких модулей (трёх - один самодельный тестовый, два других при сборки из исходников):
    Код (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.
    На сегодня хватит!
     
  8. Igor68

    Igor68 Гуру

    Вот это:
    Код (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);
     
    Ну что же, наверное пора что-то рабочее делать.
     
  9. Igor68

    Igor68 Гуру

    Доброго времени суток! Вот собрал кучу чужих модулей 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?
    И как работать вообще с модулями в смысле написания своего кода для взаимодесйтвия с ними?

    Спасибо!
     
  10. Un_ka

    Un_ka Гуру

    Через фаилы устройств модуля в /dev. Для начала почитайте статью.
     
    Igor68 нравится это.
  11. Igor68

    Igor68 Гуру

    Обучение(самообучение) продолжается. Взят пример:
    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!
    .....
    Только переварю немного функции, но уж дома.
    Курить думаю надо всего... О-ГОГОГО....
     
  12. Un_ka

    Un_ka Гуру

    А то, вы посмотрите какая страшная обложка у книги по этой теме.
    upload_2021-8-18_20-55-16.png
     
    Igor68 нравится это.
  13. Igor68

    Igor68 Гуру

    Нормальная обложка. Я обычно начинаю читать с оглавления...

    Испытал этот код на плате - результат аналогичен... но это нормально.
    А ссылка на книгу - похоже битая.

    Похоже основные минимальные понятия мне понятны... курю, набираю (пока довольно скудный) опыт
     
  14. Igor68

    Igor68 Гуру

    Вот курю:
    Код (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/<устройство> связанное с модулем это ясно... а напрямую никак?
     
  15. Igor68

    Igor68 Гуру

    Спасибо за название книги! Нашёл, скачал PDF, курю........
     
  16. Un_ka

    Un_ka Гуру

    Нет это Флибуста заблокирована.
    Это.
     
  17. Igor68

    Igor68 Гуру

  18. Igor68

    Igor68 Гуру

    конечно информации много(сил больше нет), но может пример простой кто предоставил бы?
    А именно обмен данными между модулями. Сначала загружается один модуль, потом другой который создаем устройтство в /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: слова на Руссом языке можно трактовать по разному, а фрагмент на Си ясен.
    В коде много мусора - результат опыта проводимого(не окончено - всякое испытал и не чистил)


    Спасибо!
     
    Последнее редактирование: 21 авг 2021
  19. Igor68

    Igor68 Гуру

    Доброго времени суток!
    Доступ к драйверу через устройство /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>. А тут в исходниках что-то не заметил.
     
  20. Igor68

    Igor68 Гуру

    Доброго времени суток!
    Вот опять ковыряние с загружаемыми модулями:
    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. Да и разрешения на создаваемое устройство модулем в этом тесте игнорировал.
     

    Вложения:

    • testmod3.zip
      Размер файла:
      272,8 КБ
      Просмотров:
      88