[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [microblaze-uclinux] Relocate sections in bflt file format
Hi Tommy,
Tommy Kamps wrote:
I am running uClinux 2.6.20 on A Xilinx Spartan3E500 Revision D board.
The MicroBlaze design contains a coprocessor that I have designed myself.
This coprocessor has an internal block ram and some custom logic and
is connected to the FSL bus
and to the PLB for memory access to the block ram.
I have developed a user program that contains two global arrays that
should be put in the
block RAM of the coprocessor. When using the Xilinx kernel, this can
be done by putting the arrays
in a separate section:
int array_1[16] __attribute__ ((section(".cpmem")));
int array_2[16] __attribute__ ((section(".cpmem")));
and using a linker script that assigns the PLB address of the
coprocessor to this section.
Now, I want to run this application in uClinux. The problem is that
the elf file format is not used here, but the
Binary Flat File Format (bflt). The linker script that worked for the
Xilinx MicroBlaze linker does not work for the
microblaze-uclinux-ld linker. I have found some information about the
bflt format, but it was not sufficient for me
to solve this problem. I know I have to do something with relocation,
but I am not sure how, and I could not find sufficient
information about this subject.
Can someone please give some pointers to fix this?
There's no clean way to do this - under Linux you are not allowed to
pin userspace data or code to fixed physical addresses.
That said, you can hack it up by just forcing userspace pointers to
known, fixed addresses:
#define BRAM_ADDRESS 0x2000
struct my_struct {
};
struct my_struct *bram_array = (struct my_struct *)BRAM_ADDRESS;
You can then dereference the mbra_array ptr and it will be resident in BRAM.
Of course, this will completely break if you run two instances of your
program, and you are on your own when it comes to guaranteeing mutex on
the data etc.
If you want to go further you could write your own userspace memory
allocator routines, call them bram_malloc(), bram_free() etc, if you
need that sort of flexibility.
Another, slightly cleaner way to do it, might be to use mmap(), like this:
int fd;
int *p;
fd = open("/dev/mem", O_RDWR);
p = (int *)mmap(0, 256, PROT_READ|PROT_WRITE,
MAP_PRIVATE, fd, BRAM_ADDRESS);
if (p == MAP_FAILED) {
printf("Err: cannot access adder!\n");
return -1;
}
This achieves the same effect, but if you ever port your design to
PowerPC or MicroBlaze with MMU, it will still work!
Regards,
John
___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/