Mmap: получаю MAP_FAILED

Модератор: Модераторы разделов

IMB
Сообщения: 2567
ОС: Debian

Mmap: получаю MAP_FAILED

Сообщение IMB »

Доброго дня!
Имеется следющий код:

Код: Выделить всё

Int8 *virtPtr;
    cout << "[" << __FILE__ "] displaySize before mmap " << displaySize << endl;
       cout << "[" << __FILE__ "] attrs->numBufs before mmap " << attrs->numBufs << endl;
    virtPtr = (Int8 *) mmap (NULL,
                             displaySize * attrs->numBufs,
                             PROT_READ | PROT_WRITE,
                             MAP_SHARED,
                             hDisplay->fd, 0);
    if (MAP_FAILED == virtPtr) {
        cout << "Failed mmap on " << attrs->displayDevice
            << " (" << strerror(errno) << ")" << endl;
        cout << "MMAP errno ";
        switch (errno) {
            case EINVAL:
                cout << "EINVAL";
                break;
        }
        cout << endl;
        return NULL;
    }

При запуске Failed mmap on /dev/fb/3 (Invalid argument) MMAP errno EINVAL
Сперва я решил, что это из за нулевого размера displaySize. После того, как я вручную задал displaySize вывод не изменился.
displaySize == 0

Код: Выделить всё

[display.cpp] displaySize before mmap 0
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb/3 (Invalid argument)
MMAP errno EINVAL

displaySize != 0

Код: Выделить всё

[display.cpp] displaySize before mmap 1228800
[display.cpp] attrs->numBufs before mmap 2
Failed mmap on /dev/fb/3 (Invalid argument)
MMAP errno EINVAL

В чём может быть проблема и как её решить?
Спасибо.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Mmap: получаю MAP_FAILED

Сообщение NickLion »

В мане сказано:
EINVAL
We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary).

Может попробовать грубо так:

Код: Выделить всё

    virtPtr = (Int8 *) mmap (NULL,
                             ( displaySize * attrs->numBufs + 4095) & ~4095,
                             PROT_READ | PROT_WRITE,
                             MAP_SHARED,
                             hDisplay->fd, 0);
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Спасибо за вариант, но увы - результат не изменился.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Mmap: получаю MAP_FAILED

Сообщение eddy »

IMB писал(а):
26.04.2010 13:43
/dev/fb/3

Вы уверены, что не /dev/fb3 ?
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Вы знаете - без разницы. Да и SDK производителя оперируют файлами именно в /dev/fb.
Что самое неприятное аналогичная конструкция в другой части программы работает, но там идёт работа с /dev/video0.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Mmap: получаю MAP_FAILED

Сообщение watashiwa_daredeska »

А этот самый /dev/fb-то имеется?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Да :) Он нормально открывается и к нему можно обращаться, в частности перед вызовом mmap произодится несколько ioctl и они проходят без ошибок.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Mmap: получаю MAP_FAILED

Сообщение watashiwa_daredeska »

IMB писал(а):
26.04.2010 13:43
[display.cpp] displaySize before mmap 0
[display.cpp] attrs->numBufs before mmap 2
(man mmap) писал(а):EINVAL (since Linux 2.6.12) length was 0.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Если Вы обратите внимание, я создал условия при которых length != 0 и это ничего не изменило.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Mmap: получаю MAP_FAILED

Сообщение NickLion »

А не пробовали играться с флагами? Вроде MAP_NONBLOCK… И адрес не NULL попробовать. А что вообще за устройство /dev/fb/3?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Вместо адреса NULL пробовал подставить 0 - без разницы. С флагами не игрался, так как они подходят.

grep fb -C2 linux-2.6.18_pro500/Documentation/devices.txt

29 char Universal frame buffer 0 = /dev/fb0 First frame buffer 1 = /dev/fb1 Second frame buffer ... 31 = /dev/fb31 32nd frame buffer
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Mmap: получаю MAP_FAILED

Сообщение NickLion »

Стоп. Не получается ли то, что и говорил eddy?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Нет, устройство создано корректно, в соответствии с SDK /dev/fb. Вывод из документации я привёл только для объяснения того какую роль выполняет устройство.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Mmap: получаю MAP_FAILED

Сообщение eddy »

IMB писал(а):
27.04.2010 13:29
устройство создано корректно

А вы все-таки попробуйте вместо /dev/fb/3 написать /dev/fb3 - вдруг поможет. Да, а какие права доступа к этому файлу?
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

# ls -l /dev/fb*

crw-r--r-- 1 root root 29, 3 Apr 27 2010 /dev/fb3 /dev/fb: crw-r--r-- 1 root root 29, 0 Apr 6 2010 0 crw-r--r-- 1 root root 29, 1 Apr 15 2010 1 crw-r--r-- 1 root root 29, 2 Apr 15 2010 2 crw-r--r-- 1 root root 29, 3 Apr 15 2010 3

# ./prog

............................ [display.cpp] displaySize before mmap 614400 [display.cpp] attrs->numBufs before mmap 2 Failed mmap on /dev/fb3 (Invalid argument) MMAP errno EINVAL
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Mmap: получаю MAP_FAILED

Сообщение eddy »

Запускаете из-под рута?
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Да, на это также указывает традиционная # ;)
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Mmap: получаю MAP_FAILED

Сообщение eddy »

IMB писал(а):
27.04.2010 15:16
традиционная #

[offtop]У меня везде при работе из-под рута пишется красным:
[ROOT SESSION 27.04 15:39 ~]
[offtop]
Это я к тому, что # - не факт :)
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

[offtop]Сделайте мне цвет при доступе к устройству по RS232 при ч/б minicom-е[offtop]
Не факт, но "широко известно в узких кругах" ;)
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Mmap: получаю MAP_FAILED

Сообщение watashiwa_daredeska »

eddy писал(а):
27.04.2010 15:38
Это я к тому, что # - не факт
«#» — это общепринятое соглашение, даже в управляющих последовательностях для $PS1 нашло отражение в некоторых шеллах.

IMB, только с /dev/fb3 проблема или с другими /dev/fb* тоже не работает?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Да можно сказать, что со всеми. По SDK возможны /dev/fb/1 и /dev/fb/3, на обоих эта картина.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Mmap: получаю MAP_FAILED

Сообщение watashiwa_daredeska »

IMB писал(а):
27.04.2010 17:56
По SDK
Какой-такой SDK? А без всяких SDK пробовали?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

SDK от TexasInstruments для работы с ихнеми ARM-процессорами серии DaVinci.
Пробовал, переписал стандартную фукцию, ничего не меняется. Что при использовании фукции от производителя, что моя - всё стопорится с этой же ошибкой.
Вы скажите - нет поддержке в ядре. Увы нет, поддержка в ядре присутвует. Завтра вставлю в фукцию больше отладочного вывода и предъявлю.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Mmap: получаю MAP_FAILED

Сообщение eddy »

А вы не пробовали как-нибудь вот так:

Код: Выделить всё

fd = open("/dev/fb3");
mmap (NULL, 1024,  PROT_WRITE, MAP_SHARED, fd, 0);

просто для проверки? Вдруг это устройство нельзя отображать в память (ioctl'ов, например, таких нет...).
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Mmap: получаю MAP_FAILED

Сообщение IMB »

Фукция

Код: Выделить всё

Display_Handle Display::create (Display_Attrs *attrs, unsigned int imageWidth,
                                unsigned int imageHeight)
{
    cout << "[" << __FILE__ << "] Starting Display create!" << endl;

    if (NULL == attrs) {
        cout << "[" << __FILE__ << "] Display_Attrs can't be NULL! " << endl;
        return NULL;
    }

    Display_Handle hDisplay = (Display_Handle) calloc(1, sizeof(Display_Object));
    if (NULL == hDisplay) {
        cout << "[" << __FILE__
            << "] Failed to allocate space for Dispaly Object!" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] Calloc successfully" << endl;

    hDisplay->fd = open(attrs->displayDevice, O_RDWR);
    if (-1 == hDisplay->fd) {
        cout << "[" << __FILE__ << "] Failed to open fb device "
            << attrs->displayDevice << " (" << strerror(errno) << ")" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] Open " << attrs->displayDevice
        << " successfully" << endl;

    struct fb_fix_screeninfo fixInfo;
    if (-1 == ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo)) {
        cout << "Failed FBIOGET_FSCREENINFO on " <<  attrs->displayDevice
            << " (" << strerror(errno) << ")" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] FBIOGET_FSCREENINFO successfully" << endl;

    struct fb_var_screeninfo varInfo;
    if (-1 == ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo)) {
        cout << "Failed FBIOGET_VSCREENINFO on " << attrs->displayDevice
            << " (" << strerror(errno) << ")" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] FBIOGET_VSCREENINFO successfully" << endl;

    varInfo.xres = imageWidth;
    varInfo.yres = imageHeight;
    varInfo.yres_virtual = imageHeight * attrs->numBufs;

    if (-1 == ioctl(hDisplay->fd, FBIOPUT_VSCREENINFO, &varInfo)) {
        cout << "Failed FBIOPUT_VSCREENINFO on " << attrs->displayDevice
            << " (" << strerror(errno) << ")" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] FBIOPUT_VSCREENINFO successfully" << endl;

    varInfo.xres = imageWidth;
    varInfo.yres = imageHeight;
    varInfo.yres_virtual = imageHeight * attrs->numBufs;

    BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
    if (strcmp("/dev/fb/1", attrs->displayDevice) == 0 ||
        strcmp("/dev/fb/3", attrs->displayDevice) == 0) {

        /* Color format of a video window */
        gfxAttrs.colorSpace = ColorSpace_UYVY;
    }
    else {
        /* Color format of the OSD window */
        gfxAttrs.colorSpace = ColorSpace_RGB565;
    }

    gfxAttrs.dim.width          = varInfo.xres;
    gfxAttrs.dim.height         = varInfo.yres;
    gfxAttrs.dim.lineLength     = fixInfo.line_length;
    gfxAttrs.bAttrs.reference   = TRUE;

    //unsigned int displaySize = fixInfo.line_length * varInfo.yres;
    unsigned int displaySize = 1280 * varInfo.yres;
    BufTab_Handle hBufTab = BufTab_create(attrs->numBufs, displaySize,
                            BufferGfx_getBufferAttrs(&gfxAttrs));

    if (NULL == hBufTab) {
        cout << "Failed to allocate BufTab for display buffers" << endl;
        return NULL;
    }
    cout << "[" << __FILE__ << "] BufTab_create successfully" << endl;

    Buffer_Handle hBuf = BufTab_getBuf(hBufTab, 0);
    cout << "[" << __FILE__ << "] BufTab_getBuf successfully" << endl;

    Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
                                 varInfo.bits_per_pixel / 8);
    cout << "SetNumBytesUsed "
        << varInfo.xres * varInfo.yres * varInfo.bits_per_pixel / 8 << endl;

    Int8 *virtPtr;
    cout << "[" << __FILE__ "] displaySize before mmap "
        << displaySize << endl;
    cout << "[" << __FILE__ "] attrs->numBufs before mmap "
        << attrs->numBufs << endl;
    //cout << "Machine page size " << sysconf(_SC_PAGESIZE) << endl;
    virtPtr = (Int8 *) mmap (NULL,
                             displaySize * attrs->numBufs,
                             PROT_READ | PROT_WRITE,
                             MAP_SHARED,
                             hDisplay->fd, 0);
    if (MAP_FAILED == virtPtr) {
        cout << "Failed mmap on " << attrs->displayDevice
            << " (" << strerror(errno) << ")" << endl;
        cout << "MMAP errno ";
        switch (errno) {
            case EINVAL:
                cout << "EINVAL";
                break;
        }
        cout << endl;
        return NULL;
    }

    if (0 > Buffer_setUserPtr(hBuf, virtPtr))
        return NULL;

    unsigned char bufIdx;
    Int32 physPtr;
    for (bufIdx=1; bufIdx < attrs->numBufs; bufIdx++) {
        hBuf = BufTab_getBuf(hBufTab, bufIdx);
        Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres *
                                     varInfo.bits_per_pixel / 8);

        virtPtr = virtPtr + displaySize;
        Buffer_setUserPtr(hBuf, virtPtr);

        cout << "Display buffer " << bufIdx
            << "mapped to " << virtPtr
            << " ,physical address " << physPtr << endl;
    }

    hDisplay->hBufTab = hBufTab;
    hDisplay->displayIdx = 0;
    hDisplay->workingIdx = attrs->numBufs > 1 ? 1 : 0;
    hDisplay->displayStd = Display_Std_FBDEV;

    if (0 > setDisplayBuffer(hDisplay, hDisplay->displayIdx))
        return NULL;


    if (ioctl(hDisplay->fd, FBIOBLANK, 0)) {
        cout << "Error enabling " <<  attrs->displayDevice << endl;
        return NULL;
    }

    return hDisplay;
}

Вывод

# ./prog

[display.cpp] Starting Display create! [display.cpp] Calloc successfully [display.cpp] Open /dev/fb/3 successfully [display.cpp] FBIOGET_FSCREENINFO successfully [display.cpp] FBIOGET_VSCREENINFO successfully [display.cpp] FBIOPUT_VSCREENINFO successfully @0x000eba83:[T:0x40b06490] ti.sdo.dmai - [BufTab] Allocating BufTab for 2 buffers [display.cpp] BufTab_create successfully [display.cpp] BufTab_getBuf successfully SetNumBytesUsed 614400 [display.cpp] displaySize before mmap 614400 [display.cpp] attrs->numBufs before mmap 2 Failed mmap on /dev/fb/3 (Invalid argument) MMAP errno EINVAL Failed to create display device!
Спасибо сказали: