Автор Тема: Работа с големи буфери в ядрото  (Прочетена 5269 пъти)

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Работа с големи буфери в ядрото
« Отговор #15 -: Aug 10, 2006, 11:27 »
Цитат
Error reading mem_fd, error 14 : Bad address
Ret is -1
Charp is

Не е изненада за мен де'<img'> Мисля си че сигурно офсета не трябва да е такъв, лошо че колегата дето разбира повече от хардуера е болен... Ще продължавам да го мъча.
Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!

  • Гост
Работа с големи буфери в ядрото
« Отговор #16 -: Aug 10, 2006, 11:51 »
EFAULT - buf is outside your accessible address space.


Не знам защо ми хрумна, но я пробвай така:

char *charp=malloc(16);
...
ret = read(mem_fd, charp, 16);

Би трябвало грешката да идва оттам, че четеш от файла повече байтове, отколкото ти е буфера, което не изглежда логично, но не знам...пробвай също да изчетеш не 16, ами 8 и после 4 байта, и аз не знам защо, но просто да сме сигурни че не е някаква малоумна ситуация. Въпреки че си изглежда наред.
Активен

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Работа с големи буфери в ядрото
« Отговор #17 -: Aug 10, 2006, 12:22 »
Пробвах предложенията ти, макар да не бях никак убеден че е такъв проблема - продължавам да получвам същите грешки, което ме убеждава че проблема че май не адресирам правилните адреси. Ще видя какво казва книгата Linux Device Drivers, 3rd edition по въпроса...
Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!

  • Гост
Работа с големи буфери в ядрото
« Отговор #18 -: Aug 10, 2006, 13:06 »
'<img'>
Написах си подобна програмка тук (х86). Забелязвам, че с някои offsets спокойно се чете, с други read връща същата грешка като при теб.

Според мен ядрото маркира някои региони от паметта като in use или нещо от сорта и не дава достъп до тях през /dev/mem, поне друго обяснение за проблема нямам.

Странното е че примерно ако направя cat /dev/mem > file, то после големината на файла е точно толкова колкото на ZONE_NORMAL (896MB), като все пак накрая избълва грешка, но тя предполагам идва оттам че се опитва да чете след края на адресното пространство. Би трябвало да изпищи за някаква грешка доста преди това, че не е успяло да изчете нещо от файла, но не е такъв случая '<img'>

Верно голяма мистерия '<img'> П.П - не знаех че толкова интересни неща си стояли в cleartext в рам-та, някои програмери са за убиване '<img'>

Цитат

gat3way:/# grep --binary-file=text <parolata_za_usera_mi> /dev/mem 2>/dev/null|wc -l
18
Активен

  • Гост
Работа с големи буфери в ядрото
« Отговор #19 -: Aug 10, 2006, 13:10 »
Хахахаххаха лелелелле това не го бях очаквал '<img'>

Цитат

gat3way:/# grep --binary-file=text "eba " /dev/mem 2>/dev/null|wc -l
1377


Наистина стана така ахаххаха. "eba " is leet '<img'>
Активен

the_real_maniac

  • Напреднали
  • *****
  • Публикации: 1258
  • Kernel panic, me - no panic ;-) :-)
    • Профил
Работа с големи буфери в ядрото
« Отговор #20 -: Aug 10, 2006, 13:21 »
Цитат (Lord_Bad @ Авг. 09 2006,10:46)
За какво точно става дума - имам аз един(даже 2) CMOS сензора които правят снимки с доста голяма скорост,

offtopic:

Интересна дискусия си водите :-) Евалата или браво :-D

Аз обаче имам едно питане извън темата относно CMOS сензорите. Доколото се разбира си в БГ ?
Ако да - какъв модел са CMOS сензореите и откъде ги взехте ?
Активен

Powered by Debian GNU / LINUX /// Intel inside ...

„Насилието е последното убежище на некомпетентността“ - Айзък Азимов (1920 — 1992)

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Работа с големи буфери в ядрото
« Отговор #21 -: Aug 10, 2006, 13:51 »
Сензорите са National, но тях ги купиха Кодак наскоро така че може да ги броиш за Кодак. Модела точно не го знам понеже аз съм главно по софтуерното осигуряване и някои хардуерни детайли ми убягват. Не знам дали въобще такива се продават в България. Ние знам че ги купуваме от Виена.

А иначе по темата - баси на мем и греп-а ми дава seg fault. Да го такова у /dev/mem-a. Ся гледам някфа алтернатива boot mem alloc, ама ми се види уникално мръсно... Трябва драйвера да е вграден в имиджа на ядрото за да може да заделя памет при boot - мръсна история. Другия вариант който се сещам  е ако не измисля как да станат нещаат с /dev/mem да направя /dev/myalloc - някакъв character device, да му сложа един vma и да мапвам него ама бая писане ще падне...



Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!

ivak

  • Напреднали
  • *****
  • Публикации: 156
    • Профил
Работа с големи буфери в ядрото
« Отговор #22 -: Aug 11, 2006, 10:40 »
Lord_Bad,

мисля че има готово решение за твоя случай.
прегледай файла drivers/media/video/video-buf.c
Активен

Cлoжнитe пpoблeми имaт пpocти и лecни зa paзбиpaнe гpeшни oтгoвopи.

kennedy

  • Напреднали
  • *****
  • Публикации: 2151
  • Николай Колев
    • Профил
Работа с големи буфери в ядрото
« Отговор #23 -: Aug 11, 2006, 16:02 »
хммм това което правиш някак си ще му намеря приложение при мен. Имам само 1 въпрос. Това процесорче, колко кадара ще може да обработи като картинки (в смисъл ако се ползва за ахранителна камера или нещо подобно)?
Активен

"за всичко иде час" Еклесиаст 3:1
всеки пост - отговор на въпрос
-----------------
24.12.2003 "MS Free"

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Работа с големи буфери в ядрото
« Отговор #24 -: Aug 11, 2006, 17:02 »
@ivak,
Ще го погледна макар че на пръв поглед ми се струва че този драйвер използва dma а ние се надявахме да избегнем това. Мерси все пак.

@kennedy,
Ами не мога да ти кажа цифра точна, но няма да са никак малко - процесора е адски бърз и скъп - все пак е от серията TMS320C6000. Целта на проекта - от две стерео изображения да се създаде триизмерно...
Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!

ivak

  • Напреднали
  • *****
  • Публикации: 156
    • Профил
Работа с големи буфери в ядрото
« Отговор #25 -: Aug 11, 2006, 17:49 »
Цитат (Lord_Bad @ Авг. 11 2006,17:02)
@ivak,
Ще го погледна макар че на пръв поглед ми се струва че този драйвер използва dma а ние се надявахме да избегнем това. Мерси все пак.


video_buf е предназначен именно за фрейм грабери, които сипват данни през DMA. всъщност, проблем с линейната памет има само тогава. ако ползваш PIO, можеш да пишеш където си поискаш, включително и да работиш изцяло в user space. ако пък имаш dual port memory, можеш да я mmap-неш без никакви проблеми.

апропо, какъв е интерфейсът на твоите имидж сензори? опиши накратко каква ти е постановката. евентулно бих могъл да ти дам някоя идея; правил съм подобни неща в миналото, макар и за x86.
Активен

Cлoжнитe пpoблeми имaт пpocти и лecни зa paзбиpaнe гpeшни oтгoвopи.

kennedy

  • Напреднали
  • *****
  • Публикации: 2151
  • Николай Колев
    • Профил
Работа с големи буфери в ядрото
« Отговор #26 -: Aug 11, 2006, 19:39 »
малееее може да ми свърши работа ако е на поносима цена де ....
Активен

"за всичко иде час" Еклесиаст 3:1
всеки пост - отговор на въпрос
-----------------
24.12.2003 "MS Free"

mhydra

  • Напреднали
  • *****
  • Публикации: 715
  • Distribution: Fedora, Mandriva
  • Window Manager: GNOME
    • Профил
Работа с големи буфери в ядрото
« Отговор #27 -: Aug 11, 2006, 23:04 »
Ами поносима е ..... като го купиш едно такова и после 1 година ще имаш възможност да му носиш изплащането. '<img'>  '<img'>
Активен

Указвам помощ за всичко свързано с Fedora и Мандрива.
Може да ме търсите на ICQ.

Boiler

  • Напреднали
  • *****
  • Публикации: 48
    • Профил
Работа с големи буфери в ядрото
« Отговор #28 -: Aug 24, 2006, 18:18 »
Lord_Bad, направи ли го все пак драйвера или още имаш нужда от помощ? Има една статия: Developing a Linux Driver for the StrongARM Platform. Малко е постничка, но има нещо в нея.
Активен

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Работа с големи буфери в ядрото
« Отговор #29 -: Sep 07, 2006, 15:37 »
Съжелявам за дългото прекъсване по темата, но излязох в отпуск точно след последния си пост. Сега тъкмо се захващам пак с историята и нещата все още не изглеждат добре. Големия ми мерак продължава да е да направя успешен mmap на /dev/mem, но все още не се получава по необяснима причина. Какъвто и да е проблема силно се съмнявам че той е свързан с ARM процесора. Както и да е, за заинтересованите ще публикувам още веднуж актуалната версия на драйвера който ме тормози и на програмката с която тествам работата му.
Драйвера:
Примерен код
#include <linux/version.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/vmalloc.h>

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>   /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>

#include <asm/page.h>
#include <asm/io.h>

#include "hpialloc.h"

int hpialloc_major = HPIALLOC_MAJOR;
int hpialloc_minor = 0;
int hpialloc_nr_devs = HPIALLOC_NR_DEVS;

module_param(hpialloc_major, int, S_IRUGO);
module_param(hpialloc_minor, int, S_IRUGO);
module_param(hpialloc_nr_devs, int, S_IRUGO);

MODULE_AUTHOR("Bozhidar Bastov");
MODULE_LICENSE("GPL");

struct hpialloc_dev *hpialloc_devices;

/*
 * Open and close
 */

int hpialloc_open(struct inode *inode, struct file *filp)
{
   struct hpialloc_dev *dev; /* device information */

   dev = container_of(inode->i_cdev, struct hpialloc_dev, cdev);
   filp->private_data = dev; /* for other methods */

   return 0;          /* success */
}

int hpialloc_release(struct inode *inode, struct file *filp)
{
   return 0;
}

struct file_operations hpialloc_fops = {
   .owner =    THIS_MODULE,
   .llseek =   NULL,
   .read =     NULL,
   .write =    NULL,
   .ioctl =    NULL,
   .open =     hpialloc_open,
   .release =  hpialloc_release,
};

/*
 * Finally, the module stuff
 */

/*
 * The cleanup function is used to handle initialization failures as well.
 * Thefore, it must be careful to work correctly even if some of the items
 * have not been initialized
 */

void hpialloc_cleanup_module(void)
{
   int i;
   dev_t devno = MKDEV(hpialloc_major, hpialloc_minor);

   /* Get rid of our char dev entries */
   if (hpialloc_devices) {
      for (i = 0; i < hpialloc_nr_devs; i++) {
         cdev_del(&hpialloc_devices[i].cdev);
      }
      kfree(hpialloc_devices);
   }

   /* cleanup_module is never called if registering failed */
   unregister_chrdev_region(devno, hpialloc_nr_devs);

   printk(KERN_WARNING "hpialloc: smpd module unloaded!\n");

}

/*
 * Set up the char_dev structure for this device.
 */

static void hpialloc_setup_cdev(struct hpialloc_dev *dev, int index)
{
   int err, devno = MKDEV(hpialloc_major, hpialloc_minor + index);
    
   cdev_init(&dev->cdev, &hpialloc_fops);
   dev->cdev.owner = THIS_MODULE;
   dev->cdev.ops = &hpialloc_fops;
   err = cdev_add (&dev->cdev, devno, 1);
   /* Fail gracefully if need be */
   if (err)
      printk(KERN_NOTICE "Error %d adding hpialloc%d", err, index);
}


int hpialloc_init_module(void)
{
   int result, i;
   dev_t dev = 0;
   volatile void *remapped;
    unsigned long trial_size = 0x100000; // 1MB
   char test_string[] = "0123456789abcde"; // 16 bytes

/*
 * Get a range of minor numbers to work with, asking for a dynamic
 * major unless directed otherwise at load time.
 */
   if (hpialloc_major) {
      dev = MKDEV(hpialloc_major, hpialloc_minor);
      result = register_chrdev_region(dev, hpialloc_nr_devs, "hpialloc");
   } else {
      result = alloc_chrdev_region(&dev, hpialloc_minor, hpialloc_nr_devs,
            "hpialloc");
      hpialloc_major = MAJOR(dev);
   }
   if (result < 0) {
      printk(KERN_WARNING "hpialloc: can't get major %d\n", hpialloc_major);
      return result;
   }

    /*
    * allocate the devices -- we can't have them static, as the number
    * can be specified at load time
    */
   hpialloc_devices = kmalloc(hpialloc_nr_devs * sizeof(struct hpialloc_dev), GFP_KERNEL);
   if (!hpialloc_devices) {
      result = -ENOMEM;
      goto fail;  /* Make this more graceful */
   }
   memset(hpialloc_devices, 0, hpialloc_nr_devs * sizeof(struct hpialloc_dev));

   /* Initialize each device. */
   for (i = 0; i < hpialloc_nr_devs; i++) {
      hpialloc_setup_cdev(&hpialloc_devices[i], i);
   }
                                    
   printk(KERN_WARNING "hpialloc: hpialloc module loaded!\n");

       
    remapped = ioremap(0xA1E00000, trial_size);

    if (!remapped)
      return -1;

   printk(KERN_INFO "hpialloc: hpialloc module mapped memory successfully!\n");

   for (i = 0; i < trial_size; i += 16) {
      strcpy((char *)(remapped) + i, test_string);
        if (strcmp((char *)(remapped) + i, test_string)) {
         printk(KERN_INFO "Compare failure, i = %d!\n", i);
         printk(KERN_INFO "remapped : %s\n", (char *)remapped);
         break;
      }
    }

   for (i = 0; i < trial_size; i += 16) {
      strncpy(test_string, (char *)(remapped) + i, 16);
        if (strcmp((char *)(remapped) + i, test_string)) {
         printk(KERN_INFO "Compare failure, i = %d!\n", i);
         printk(KERN_INFO "remapped : %s\n", (char *)remapped);
         break;
      }
    }

    //iounmap((void *)remapped);
   
   return 0; /* succeed */

  fail:
   hpialloc_cleanup_module();
   return result;
}


module_init(hpialloc_init_module);
module_exit(hpialloc_cleanup_module);


Тестовата програма:

Примерен код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int main(void)
{
   int mem_fd, i, ret;
   char test_string[] = "0123456789abcde";
   volatile void *mapped;
   char *charp;

   if ((mem_fd = open("/dev/mem", O_RDONLY)) < 0) {
      printf("\n\nProblem in opening /dev/mem");
      exit(-1);
   }
   
   
   mapped = mmap(0, 0x100000, PROT_READ | PROT_WRITE, MAP_FIXED, mem_fd, 0x01E00000);

   if (!mapped)
      return -1;

   printf("Mmap mapped memory successfully!\n");

   for (i = 0; i < 0x100000; i += 16) {
      printf("Current i is : %d\n", i);
      if (strncmp((char *)(mapped) + i, test_string, 16)) {
         printf("Compare failure, i = %d!\n", i);
         printf("mapped : %s\n", (char *)mapped);
         break;
      }
   }
     

   munmap(0, 0xA1E00000);

   /*   
   charp = malloc(16);
   lseek(mem_fd, 0xA1E00000, SEEK_CUR);
   ret = read(mem_fd, charp, 16);
   if (ret < 0)
      printf("Error reading mem_fd, error %d : %s\n", errno, strerror(errno));

   printf("Ret is %d\n", ret);
   printf("Charp is %s\n", charp);

   */
   return 0;
   
}



Съзнавам че кода е доста дълъг за един форум, но в драйвера не гледайте всичко наред. Само hpialloc_init_module е важна, другите като изключим cleanup-a са за да има entry драйвера в /dev файловата система. Това се случва като тествам драйвера аз:
Примерен код
-bash-2.05b# insmod hpialloc.ko
hpialloc: hpialloc module loaded!
hpialloc: hpialloc module mapped memory successfully!
-bash-2.05b# ./readmem
Mmap mapped memory successfully!
Current i is : 0
Segmentation fault


Ако някой се сети нещо, което може да ми помогне ще съм много благодарен.
Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!