Перейти к содержанию

    

Zero copy в petalinux

Здравствуйте!

Есть zedboard (zynq7000), на которой запущен petalinux.

Надо по ssh передать файл с компм на zedboard, и чтобы этот файл в конце-концов оказался в буфере с известной физической памятью (в DDR).

Копирование файла через ssh проблем не вызывает. А вот как ьбеспечить помещение этого файла в извастную область ddr памяти?

Пока пробую с splice, но при этом зависает petalinux.

Device tree (часть, касающаяся буфера, в который хочу поместить файл)

reserved-memory {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
                reserved: axi-buffer@0x17000000 {
                        compatible = "shared-dma-pool";
                        no-map; //reusable; 
                        reg = <0x17000000 0x2000000>; //size 32 MB
                        linux,dma-default; 
                };
        };

Код программы на C

    int filedes[2];
    static int buf_size = 4096;
    loff_t in_off = 2;
    loff_t uuu = 0x17000000;
    off_t len;
    
    int fd_mem = open("/dev/mem",O_RDWR);
    int fd_file = open(argv[1],O_RDONLY);

struct stat stbuf;
    if(pipe(filedes) < 0)
        return -1;
    if(fstat(fd_file, &stbuf) < 0)
         return -1;
    len = stbuf.st_size;
    while(len > 0)
    {
        if(buf_size > len) buf_size = len;
        /*
         * move to pipe buffer.
         */
        ret = splice(fd_file, &in_off, filedes[1], NULL, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
        printf("ret is %d\n",ret);
        if(ret < 0)
            return -1;
        len -= ret;
    }
    len = stbuf.st_size;
    printf("len = %d\n",len);
    while(len > 0)
    {
        if(buf_size > len) buf_size = len;
        /*
         * move from pipe buffer to out_fd
         */
        ret = splice(filedes[0], NULL, fd_mem, &uuu, buf_size, SPLICE_F_MOVE | SPLICE_F_MORE);
        if(ret < 0)
        {
            close...
            return -1;
        }
        len -= ret;
    }

На втором splice ядро выдает панику:

Unable to handle kernel paging request at virtual address d7000000 
pgd = db754000 
[d7000000] *pgd=00000000 
Internal error: Oops - BUG: 805 [#1] PREEMPT SMP ARM 
Modules linked in: 
CPU: 0 PID: 1316 Comm: libgannet Not tainted 4.14.0-xilinx #1 
Hardware name: Xilinx Zynq Platform 
task: db6d8680 task.stack: db648000 
PC is at arm_copy_from_user+0xd4/0x39c 
LR is at 0x6c6c6548 
pc : [<c062b9b8>] lr : [<6c6c6548>] psr: 00070013 
sp : db649dfc ip : 0000001c fp : ffffe000 
r10: d7000000 r9 : db649ed0 r8 : 17000000 
r7 : c788a000 r6 : 00000007 r5 : 00000000 r4 : 00000007 
r3 : 00000000 r2 : ffffffe7 r1 : c788a004 r0 : d7000000 
Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel 
Control: 18c5387d Table: 1b75404a DAC: 00000055 
Process libgannet (pid: 1316, stack limit = 0xdb648210) 
Stack: (0xdb649dfc to 0xdb64a000)

Почему линукс зависает? Из-за no-map или из-за неправильного использования splice? Как грамотно решить задачу копирования файла в область с известным физическим адресом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Копирование файла через ssh проблем не вызывает. А вот как ьбеспечить помещение этого файла в извастную область ddr памяти?

Пока пробую с splice, но при этом зависает petalinux.

Почему линукс зависает? Из-за no-map или из-за неправильного использования splice? Как грамотно решить задачу копирования файла в область с известным физическим адресом?

посмотрите в раскладку памяти, может там что видно:

cat /proc/iomem

проверьте так же, что система может отдавать 32МБ (дефолтный ограничитель 16МБ):

https://electronix.ru/forum/index.php?showtopic=139580

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
проверьте так же, что система может отдавать 32МБ (дефолтный ограничитель 16МБ)

Система спокойно отдает нужный объем памяти. Я необходимые настройки для ядра выставила :)

Ниже в программе я вызываю mmap для этого региона и после спокойно в него пишу и из него читаю...

uint32_t *mem=(uint32_t *) mmap(NULL, 0x2000000, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, 0x17000000);

И операции вида mem[0] =5 ошибок не вызывают :laughing:

Изменено пользователем sheynmanyu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация