UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor galax87
Visitor
8,754 Views
Registered: ‎04-18-2016

memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

Hi all.

I am trying to map a large portion of the OCM (0x7E1E uint16_t) into a Linux process.
It works but after the memset instruction it exits with segmentation fault.

Googling I found this:
http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
but it did not work.
I tried to play with the mmap options according to this
https://www.safaribooksonline.com/library/view/linux-system-programming/0596009585/ch04s03.html
but without results.

I was looking for the prototype memset_s but I did not find it in Petalinux 2014.4.

I'd like to mention that without the memset instruction my whole modbus server application is working very well.
Below there is the minimalistic code reproducing the error:

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

typedef unsigned short int    uint16_t;

int main()
{
    int fd;
    void *hr_ptr;
    unsigned page_hr_addr, page_hr_offset;
    unsigned page_size=sysconf(_SC_PAGESIZE);
    printf("page size: 0x%X...\n",page_size);
    unsigned holdingregister_base_addr;
    int nb_registers;
    uint16_t *tab_registers;

    uint16_t regis = 12;
    tab_registers = &regis;

    printf("tab_registers %d\n",*tab_registers);

    holdingregister_base_addr = 0xFFFE0110;

    fd=open("/dev/mem",O_RDWR);
        if(fd<1) {
            printf("cannot open /dev/mem\nquitting...\n");
            exit(-1);
        }else{
            printf("Starting memory mapping for modbus server...\n");
        }

    page_hr_addr=(holdingregister_base_addr & ~(page_size-1));
    page_hr_offset=holdingregister_base_addr-page_hr_addr;
    hr_ptr=mmap(NULL,page_size,PROT_READ|PROT_WRITE,
                       MAP_SHARED,fd,(holdingregister_base_addr & ~(page_size-1)));
    if((int)hr_ptr==-1) {
        printf("cannot mapping holding registers memory\nquitting...\n");
        exit(-1);
    }

    nb_registers = 0x7E1E;
    if (nb_registers == 0) {
        tab_registers = NULL;
    } else {
        tab_registers = (uint16_t *) (hr_ptr+page_hr_offset);
        if (tab_registers == NULL) {
            printf("failure\n");
            return EXIT_FAILURE;
        }else{
            printf("tab_registers not NULL!\n");
            tab_registers[0] = 9;
            printf("&tab_registers[0]=0x%X\n"
                    "*tab_registers[0]=0x%X\n",(unsigned int)&tab_registers[0],tab_registers[0]);
        }

        memset(tab_registers, 1, nb_registers * sizeof(uint16_t));
        printf("holding registers successfully mapped (START: 0x%X NB: 0x%X)\n",
                                           holdingregister_base_addr,nb_registers);

    }

    return 0;
}

 

The output of the code above is the following

page size: 0x1000...
tab_registers 12
Starting memory mapping for modbus server...
tab_registers not NULL!
&tab_registers[0]=0xB6F1A110
*tab_registers[0]=0x9
Segmentation fault

Debugging from the SDK on Windows 7 I can get this

gdbserver: Corrupted shared library list: 0xb6fff960 != 0x1010101

316^done
(gdb)
317-exec-next 1
317^running
*running,thread-id="1"
(gdb)
*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",
frame={addr="0xb6ef13d0",func="??",args=[]},thread-id="1",stopped-threads="all",core="0"
(gdb)
318 info threads
&"info threads\n"
~"  Id   Target Id         Frame \n"
~"* 1    Thread 798        0xb6ef13d0 in ?? ()\n"
318^done
(gdb)
319-stack-info-depth
319^done,depth="2"
(gdb)
320-stack-list-frames 0 2
320^done,stack=[frame={level="0",addr="0xb6ef13d0",func="??"},frame={level="1",addr="0x000087ec",
func="main",file="../src/helloworld.c",fullname="c:\\users\\eexag13\\git\\xapp1078_2014.4\\design
\\work\\project_1\\project_1.sdk\\linux_template\\src\\helloworld.c",line="78"}]
(gdb)
321-data-list-changed-registers
321^done,changed-registers=["0","1","2","3","12","14","15","25"]
(gdb)
322 info sharedlibrary
&"info sharedlibrary\n"
=library-unloaded,id="/lib/libgcc_s.so.1",target-name="/lib/libgcc_s.so.1",
host-name="/lib/libgcc_s.so.1",thread-group="i1"
=library-unloaded,id="/lib/libc.so.6",target-name="/lib/libc.so.6",
host-name="/lib/libc.so.6",thread-group="i1"
=library-unloaded,id="/lib/ld-linux.so.3",target-name="/lib/ld-linux.so.3",
host-name="/lib/ld-linux.so.3",thread-group="i1"
~"No shared libraries loaded at this time.\n"
322^done
(gdb)
323 info signal SIGSEGV
&"info signal SIGSEGV\n"
~"Signal        Stop\tPrint\tPass to program\tDescription\n"
~"SIGSEGV       Yes\tYes\tYes\t\tSegmentation fault\n"
323^done
(gdb)
324-data-disassemble -s 0xb6ef13d0 -e 0xb6ef1448 -- 0
324^done,asm_insns=[{address="0xb6ef13d0",inst="stmiacs\tr3!, {r1, r12}"},
{address="0xb6ef13d4",inst="subscs\tr2, r2, #8"},
{address="0xb6ef13d8",inst="stmiacs\tr3!, {r1, r12}"},
{address="0xb6ef13dc",inst="bcs\t0xb6ef13bc"},
{address="0xb6ef13e0",inst="and\tr2, r2, #7"},{address="0xb6ef13e4",inst="subs\tr2, r2, #1"},
{address="0xb6ef13e8",inst="strbcs\tr1, [r3], #1"},{address="0xb6ef13ec",inst="subscs\tr2, r2, #1"},
{address="0xb6ef13f0",inst="strbcs\tr1, [r3], #1"},{address="0xb6ef13f4",inst="subscs\tr2, r2, #1"},
{address="0xb6ef13f8",inst="strbcs\tr1, [r3], #1"},{address="0xb6ef13fc",inst="subscs\tr2, r2, #1"},
{address="0xb6ef1400",inst="strbcs\tr1, [r3], #1"},{address="0xb6ef1404",inst="bcs\t0xb6ef13e4"},
{address="0xb6ef1408",inst="bx\tlr"},{address="0xb6ef140c",inst="nop\t{0}"},
{address="0xb6ef1410",inst="push\t{r4, lr}"},{address="0xb6ef1414",inst="mov\tr4, r2"},
{address="0xb6ef1418",inst="bl\t0xb6ef6a80"},{address="0xb6ef141c",inst="add\tr0, r0, r4"},
{address="0xb6ef1420",inst="pop\t{r4, pc}"},{address="0xb6ef1424",inst="rsb\tr12, r0, r1"},
{address="0xb6ef1428",inst="cmp\tr12, r2"},{address="0xb6ef142c",inst="push\t{r3, r4, r5, r6, r7, lr}"},
{address="0xb6ef1430",inst="mov\tr3, r1"},{address="0xb6ef1434",inst="mov\tr5, r0"},
{address="0xb6ef1438",inst="bcc\t0xb6ef14c0"},{address="0xb6ef143c",inst="cmp\tr2, #15"},
{address="0xb6ef1440",inst="bls\t0xb6ef149c"},{address="0xb6ef1444",inst="rsb\tr6, r1, #0"}]
(gdb)
325-data-disassemble -s 0x8828 -e 0x88a8 -- 0
325^done,asm_insns=[{address="0x00008828",func-name="__libc_csu_init",offset="24",inst="add\tr6, pc, r6"},
{address="0x0000882c",func-name="__libc_csu_init",offset="28",inst="bl\t0x8468 <_init>"},
{address="0x00008830",func-name="__libc_csu_init",offset="32",inst="add\tr5, pc, r5"},
{address="0x00008834",func-name="__libc_csu_init",offset="36",inst="rsb\tr6, r5, r6"},
{address="0x00008838",func-name="__libc_csu_init",offset="40",inst="asrs\tr6, r6, #2"},
{address="0x0000883c",func-name="__libc_csu_init",offset="44",inst="popeq\t{r3, r4, r5, r6, r7, r8, r9, pc}"},
{address="0x00008840",func-name="__libc_csu_init",offset="48",inst="sub\tr5, r5, #4"},
{address="0x00008844",func-name="__libc_csu_init",offset="52",inst="mov\tr4, #0"},
{address="0x00008848",func-name="__libc_csu_init",offset="56",inst="add\tr4, r4, #1"},
{address="0x0000884c",func-name="__libc_csu_init",offset="60",inst="ldr\tr3, [r5, #4]!"},
{address="0x00008850",func-name="__libc_csu_init",offset="64",inst="mov\tr0, r7"},
{address="0x00008854",func-name="__libc_csu_init",offset="68",inst="mov\tr1, r8"},
{address="0x00008858",func-name="__libc_csu_init",offset="72",inst="mov\tr2, r9"},
{address="0x0000885c",func-name="__libc_csu_init",offset="76",inst="blx\tr3"},
{address="0x00008860",func-name="__libc_csu_init",offset="80",inst="cmp\tr4, r6"},
{address="0x00008864",func-name="__libc_csu_init",offset="84",inst="bne\t0x8848 <__libc_csu_init+56>"},
{address="0x00008868",func-name="__libc_csu_init",offset="88",inst="pop\t{r3, r4, r5, r6, r7, r8, r9, pc}"},
{address="0x0000886c",func-name="__libc_csu_init",offset="92",inst="andeq\tr8, r0, r0, lsr #4"},
{address="0x00008870",func-name="__libc_csu_init",offset="96",inst="andeq\tr8, r0, r4, lsl r2"},
{address="0x00008874",func-name="__libc_csu_fini",offset="0",inst="bx\tlr"},
{address="0x00008878",func-name="_fini",offset="0",inst="push\t{r3, lr}"},
{address="0x0000887c",func-name="_fini",offset="4",inst="pop\t{r3, pc}"},
{address="0x00008880",func-name="_IO_stdin_used",offset="0",inst="andeq\tr0, r2, r1"},
{address="0x00008884",inst="strbvs\tr6, [r7, #-368]!\t; 0x170"},
{address="0x00008888",inst="bvc\t0x1a65510"},
{address="0x0000888c",inst="eorcc\tr3, r0, r5, ror #20"},
{address="0x00008890",inst="mrccs\t5, 2, r2, cr8, cr8, {3}"},
{address="0x00008894",inst="andeq\tr2, r10, lr, lsr #28"},
{address="0x00008898",inst="svcpl\t0x00626174"},
{address="0x0000889c",inst="stmdbvs\tr7!, {r1, r4, r5, r6, r8, r10, sp, lr}^"},
{address="0x000088a0",inst="rsbvc\tr7, r5, #1929379840\t; 0x73000000"},
{address="0x000088a4",inst="strtvs\tr2, [r5], #-115\t; 0x73"}]
(gdb)

 

Any help is appreciated.

Thanks in advance
Alessandro

0 Kudos
1 Solution

Accepted Solutions
Participant pete_128
Participant
16,123 Views
Registered: ‎04-02-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

No you do not need multiple mappings as there is no limitation on the size of the mmap. You just need to increase the size of the mmaping rounding up to a even page size. If there are gaps in the OCM where other things map pages then you would need to manage multiple pointers but for a phyiscally continuous mapping a single multi-page mmap of /dev/mem will work.

View solution in original post

0 Kudos
6 Replies
Participant pete_128
Participant
8,699 Views
Registered: ‎04-02-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

You mmap only maps one page but isn't the size of nb_registers (as used by the memset) bigger than one page?

0 Kudos
Visitor galax87
Visitor
8,676 Views
Registered: ‎04-18-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

Dear Pete,

 

Exactly.

 

Should I have more than one pointer in order to use memset (tab_register_1stpage, tab_register_2ndpage, etc. etc.)?

If yes, how can my application be able to access all the data even if after the page size?

 

Thanks for your reply

Alessandro

0 Kudos
Participant pete_128
Participant
16,124 Views
Registered: ‎04-02-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

No you do not need multiple mappings as there is no limitation on the size of the mmap. You just need to increase the size of the mmaping rounding up to a even page size. If there are gaps in the OCM where other things map pages then you would need to manage multiple pointers but for a phyiscally continuous mapping a single multi-page mmap of /dev/mem will work.

View solution in original post

0 Kudos
Visitor galax87
Visitor
8,608 Views
Registered: ‎04-18-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

It seems it's working! Thanks a lot Pete!

 

Let me just summarize to see if I understood properly.

 

I had:

hr_ptr=mmap(NULL,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(holdingregister_base_addr & ~(0x1000-1)));

Now I have:

hr_ptr=mmap(NULL,0x10000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(holdingregister_base_addr & ~(0x10000-1)));

This is working because 0x7E1E * sizeof(uint16_t) = 0x7E1E * 0x2 = 0xFC3C that is minor than 0x10000,

am I right?

 

Thanks a lot!

Cheers

 

Alessandro

 

 

 

 

 

0 Kudos
Participant pete_128
Participant
8,570 Views
Registered: ‎04-02-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

Your understanding is right.

 

0 Kudos
Visitor galax87
Visitor
8,563 Views
Registered: ‎04-18-2016

Re: memset segmentation fault on On Chip Memory (OCM) mapping

Jump to solution

Brilliant!

 

Thanks again Pete.

 

All the best

 

Alessandro

0 Kudos