Jump to content

    

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? Как грамотно решить задачу копирования файла в область с известным физическим адресом?

Share this post


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

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

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

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

cat /proc/iomem

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

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

Share this post


Link to post
Share on other sites
проверьте так же, что система может отдавать 32МБ (дефолтный ограничитель 16МБ)

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

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

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

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

Edited by sheynmanyu

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this